转载请注明出处:http://blog.csdn.net/b2569449528/article/details/78475327

工作需要开发了一个贪食蛇apk预装到公司产品,共10关。包含了游戏得分记录,升级地图切换,游戏音效,退出游戏可继续,游戏速度调节等等功能

游戏是基于重绘view机制开发的,没有使用surfaceview(因为之前已经写过一个),喜欢的可以参考下改改。英文不好大家将就着看看

这是游戏界面实现,主要思路是通过开启一个线程,然后在线程中开启一个循环,不断的去改变蛇的位置,改变位置之后则调用刷新界面的方法重绘,实现小蛇移动。当然大家肯定也猜到了,游戏速度也是在其中控制的。

package com.example.snake.view;import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StreamCorruptedException;import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;import com.example.snake.R;
import com.example.snake.bean.BackGround;
import com.example.snake.bean.Food;
import com.example.snake.bean.Obstacle;
import com.example.snake.bean.Snake;
import com.example.snake.utils.LogUtils;
import com.example.snake.utils.ObjectOutputUtils;
import com.example.snake.utils.OnGameOverListener;/*** @author dengjifu* @date 20171027*/
public class SnakeView extends View implements Runnable {/*******************************************/private Context context;private BackGround backGround;private Snake snake;private Obstacle obstacle;private Food food;private Bitmap bgBitmap, snakeBitmap, obstacleBitmap, foodBitmap;private int width, height;// game statepublic static final int GAMEING = 1;public static final int GAME_OVER = 2;public static final int GAME_PAUSE = 3;public static final int GAME_WIN = 4;public static int gameState = GAMEING;// game is a new game or continue gamepublic static final int NEW_GAME = 1;public static final int OLD_GAME = 2;public static int gameStore = NEW_GAME;private Thread gameThread;// when game over then let the Thread run endpublic static boolean endGame = false;// when level up then Thread sleep 1000mspublic volatile static boolean isLevelUp = false;// when the application was in the background and the MainActivity is go// into onStop() method// then let the Thread sleep, until it back to front;public static volatile boolean sleepThread = false;// when the game is over,to execute the interface method and pass the length// of snake to calculate scoreprivate OnGameOverListener onGameOverListener;// game speed arraypublic static long[] speedsArray = new long[] { 400, 350, 300, 250, 200,150, 120 };// to set the game speedpublic static long speed = speedsArray[0];/*******************************************/public void setOnGameOverListener(OnGameOverListener onGameOverListener) {this.onGameOverListener = onGameOverListener;}public long getSpeed() {return speed;}public void setSpeed(long speed) {SnakeView.speed = speed;}public SnakeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}public SnakeView(Context context, AttributeSet attrs) {super(context, attrs);}public SnakeView(Context context, int width, int height) {super(context);this.context = context;this.width = width;this.height = height;initGame();gameThread = new Thread(this);gameThread.start();}private void initGame() {initBitMap();initBean();// if continue game then load the dataif (gameStore == OLD_GAME) {getGameData();}}private void initBean() {backGround = new BackGround(bgBitmap, width, height);obstacle = new Obstacle(obstacleBitmap);snake = new Snake(snakeBitmap, getContext());food = new Food(foodBitmap, snake, obstacle);snake.setObstacle(obstacle);snake.setFood(food);}private void initBitMap() {bgBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.block00);snakeBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.block4);foodBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.block6);obstacleBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.block0);}@Overrideprotected void onDraw(Canvas canvas) {backGround.draw(canvas);obstacle.draw(canvas);snake.draw(canvas);food.draw(canvas);}@Overridepublic void run() {while (true && !endGame) {try {LogUtils.d("thread", "name="+Thread.currentThread().getName());long start = System.currentTimeMillis();while (sleepThread) {Thread.sleep(3000);}while(isLevelUp){Thread.sleep(2000);snake.initSnake();obstacle.initObstacle(snake.getLastLength() / snake.levelNum);isLevelUp = false;}if (gameState == GAMEING) {snake.move();// Invalidate SnakeViewpostInvalidate();} else if (gameState == GAME_OVER) {backGround.initPoint();if (onGameOverListener != null) {onGameOverListener.afterGameOver(GAME_OVER,calculScore());}clearCache();clearGameData();saveGameStateToshareprefernce();endGame = true;} else if (gameState == GAME_WIN) {backGround.initPoint();clearCache();clearGameData();if (onGameOverListener != null) {onGameOverListener.afterGameOver(GAME_WIN,calculScore());}saveGameStateToshareprefernce();endGame = true;}long end = System.currentTimeMillis();long time = end - start;if (time < speed) {Thread.sleep(speed - time);} else {}} catch (InterruptedException e) {LogUtils.d("thread", "interrupt name="+Thread.currentThread().getName());}}}private void saveGameStateToshareprefernce() {SharedPreferences.Editor edit = context.getSharedPreferences("levelint", Context.MODE_PRIVATE).edit();edit.putInt("gameState", SnakeView.gameState);edit.apply();}// calculate scoreprivate int calculScore() {int eatLength = snake.getLength() + snake.getLastLength();int level = obstacle.getLevel();int Score = (int) (level * 100 + eatLength * 20 * ((600 - speed) / 100));return Score;}private void clearCache() {food.clearCache();snake.clearCache();obstacle.clearCache();}@Overridepublic void onWindowFocusChanged(boolean hasWindowFocus) {super.onWindowFocusChanged(hasWindowFocus);}// save the game datapublic void saveGameData() {LogUtils.d("saveObj", "--------saveGameData----");ObjectOutputUtils objectOutputUtils = new ObjectOutputUtils(context);try {objectOutputUtils.outPutObj(food, "food");objectOutputUtils.outPutObj(snake, "snake");objectOutputUtils.outPutObj(obstacle, "obstacle");} catch (FileNotFoundException e) {e.printStackTrace();LogUtils.d("saveObj", "--saveGameData-e---" + e.getMessage());} catch (NotFoundException e) {e.printStackTrace();LogUtils.d("saveObj", "--saveGameData-e---" + e.getMessage());} catch (IOException e) {e.printStackTrace();LogUtils.d("saveObj", "--saveGameData-e---" + e.getMessage());}}// read game datapublic void getGameData() {LogUtils.d("saveObj", "--------getGameData----");ObjectOutputUtils objectOutputUtils = new ObjectOutputUtils(context);try {Food objFood = (Food) objectOutputUtils.inPutObj("food");Snake objSnake = (Snake) objectOutputUtils.inPutObj("snake");Obstacle objobstacle = (Obstacle) objectOutputUtils.inPutObj("obstacle");if (objFood != null && objFood.getListFood() != null&& objFood.getListFood().size() > 0) {food.setData(objFood);}if (objSnake != null && objSnake.getPosition() != null&& objSnake.getPosition().size() > 0) {snake.setData(objSnake);}if (objobstacle != null && objobstacle.getList() != null&& objobstacle.getList().size() > 0) {obstacle.setData(objobstacle);}} catch (StreamCorruptedException e) {e.printStackTrace();LogUtils.d("saveObj", "--getGameData-e---" + e.getMessage());} catch (FileNotFoundException e) {e.printStackTrace();LogUtils.d("saveObj", "--getGameData-e---" + e.getMessage());} catch (ClassNotFoundException e) {e.printStackTrace();LogUtils.d("saveObj", "--getGameData-e---" + e.getMessage());} catch (NotFoundException e) {e.printStackTrace();LogUtils.d("saveObj", "--getGameData-e---" + e.getMessage());} catch (IOException e) {e.printStackTrace();LogUtils.d("saveObj", "--getGameData-e---" + e.getMessage());}}// clear datapublic void clearGameData() {LogUtils.d("saveObj", "--------clearGameData----");ObjectOutputUtils objectOutputUtils = new ObjectOutputUtils(context);try {objectOutputUtils.outPutObj(null, "food");objectOutputUtils.outPutObj(null, "snake");objectOutputUtils.outPutObj(null, "obstacle");} catch (FileNotFoundException e) {e.printStackTrace();LogUtils.d("saveObj", "--clearGameData-e---" + e.getMessage());} catch (NotFoundException e) {LogUtils.d("saveObj", "--clearGameData-e---" + e.getMessage());e.printStackTrace();} catch (IOException e) {LogUtils.d("saveObj", "--clearGameData-e---" + e.getMessage());e.printStackTrace();}}public void setDirection(int direction) {snake.setDIRECTION(direction);}public int getDirection() {return snake.getDIRECTION();}}

MainActivity主要的工作呢就是实现界面初始化以及按键监听,还有一个游戏结束时的回调。

MainActivity的代码:

package com.example.snake.activity;import android.content.Intent;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.KeyEvent;import com.example.snake.bean.Snake;
import com.example.snake.utils.LogUtils;
import com.example.snake.utils.OnGameOverListener;
import com.example.snake.view.SnakeView;
/*** @author dengjifu* @date 20171027*/
public class MainActivity extends BaseActivity implements OnGameOverListener{SnakeView snakeView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);DisplayMetrics metric = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metric);int width = metric.widthPixels; //width pxint height = metric.heightPixels; // height pxsnakeView = new SnakeView(this, width, height);setContentView(snakeView);snakeView.setClickable(false);snakeView.setOnGameOverListener(this);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_DPAD_LEFT:if(snakeView.getDirection()!=Snake.RIGHT && !Snake.isDirectionPressed){snakeView.setDirection(Snake.LEFT);Snake.isDirectionPressed = true;}return true;case KeyEvent.KEYCODE_DPAD_UP:if(snakeView.getDirection()!=Snake.BOTTOM && !Snake.isDirectionPressed){snakeView.setDirection(Snake.TOP);Snake.isDirectionPressed = true;}return true;case KeyEvent.KEYCODE_DPAD_RIGHT:if(snakeView.getDirection()!=Snake.LEFT && !Snake.isDirectionPressed){snakeView.setDirection(Snake.RIGHT);Snake.isDirectionPressed = true;}return true;case KeyEvent.KEYCODE_DPAD_DOWN:if(snakeView.getDirection()!=Snake.TOP && !Snake.isDirectionPressed){snakeView.setDirection(Snake.BOTTOM);Snake.isDirectionPressed = true;}return true;case KeyEvent.KEYCODE_ENTER:
//          if(SnakeView.gameState!=SnakeView.GAME_PAUSE){
//              SnakeView.gameState = SnakeView.GAME_PAUSE;
//          }else {
//              SnakeView.gameState = SnakeView.GAMEING;
//          }return true;}return super.onKeyDown(keyCode, event);}@Overridepublic void onBackPressed() {SnakeView.endGame = true;snakeView.saveGameData();LogUtils.d("saveObj", "-------onBackPressed--------");MainActivity.this.finish();}@Overridepublic void afterGameOver(int game,int score) {Intent intent = new Intent(this, DialogActivity.class);intent.putExtra("game", game);intent.putExtra("score", score);startActivity(intent);MainActivity.this.finish();}@Overrideprotected void onPause() {super.onPause();}@Overrideprotected void onDestroy() {super.onDestroy();}@Overrideprotected void onStop() {SnakeView.sleepThread = true;snakeView.saveGameData();LogUtils.d("saveObj", "-------onStop--------");super.onStop();}@Overrideprotected void onRestart() {LogUtils.d("saveObj", "-------onRestart--------");SnakeView.sleepThread = false;super.onRestart();}
}

代码比较多就不一一贴出来了,喜欢的可以去github上下载,别忘了给我个start哦!谢谢大家,下面是贴图。

截图如下:

原文链接:http://blog.csdn.net/b2569449528/article/details/78475327

下载链接:

http://download.csdn.net/download/b2569449528/10108784

GitHub链接:

https://github.com/1994jeff/MyDemo

android贪食蛇详细教程实现加源码相关推荐

  1. Android连接SQLServer详细教程(数据库+服务器+客户端),并在微软Azure云上搭建云服务

    Android连接SQLServer详细教程(数据库+服务器+客户端),并在微软Azure云上搭建云服务 参考博客:http://blog.csdn.net/zhyl8157121/article/d ...

  2. 华为云IOT Android应用开发详细教程

    华为云IOT Android应用开发详细教程 (Android Studio开发) 第〇章    简介       大家好,上一期发布的教程叫大家如何利用华为云物联网平台提供的官方Java Demo去 ...

  3. 魅族m8android固件,魅族M8刷Android系统图文详细教程

    <魅族M8刷Android系统图文详细教程>由会员分享,可在线阅读,更多相关<魅族M8刷Android系统图文详细教程(9页珍藏版)>请在人人文库网上搜索. 1.魅族M8刷An ...

  4. oppor15android9版本,OPPO R15如何升级Android 9.0 OPPO R15升级Android 9.0详细教程

    2018-05-11 16:32:50 OPPO R15如何升级Android 9.0 OPPO R15升级Android 9.0详细教程 标签:OPPO R15,OPPO R15 Android9. ...

  5. Android 贪食蛇

    初级贪食蛇 文章目录 初级贪食蛇 效果展示: 界面设计 算法设计 游戏面板类 蛇身类 蛇类 方向类 主函数类 效果展示: 界面设计 游戏界面的设计布局我们采用"相对布局中嵌套线性布局&quo ...

  6. Android LeakCanary使用详细教程

    导语 在Android的性能优化中,内存优化是必不可少的点,而内存优化最重要的一点就是解决内存泄漏的问题,在Android的内存泄漏分析工具也不少,比如PC端的有:AndroidStudio自带的An ...

  7. vue - element <upload> 组件批量上传文档,可携带其他表单数据项一同与文件 “手动提交“ 服务器(类似百度文库系统批量上传前端界面与逻辑)超详细教程示例源码,提供界面与逻辑完整源码

    效果图 本示例使用的是 element 组件库,其实什么组件库都行(逻辑是一样),只要你是 vue.js 项目就能使用本教程. 本文实现了 vue + element 使用 upload 组件批量上传 ...

  8. Android连接SQLServer详细教程(数据库+服务器+客户端)

    本文为原创,如果转载请注明出处 http://blog.csdn.net/zhyl8157121/article/details/8169172 其实之前发过一篇这样的博文http://blog.cs ...

  9. 2020最新款影视小程序后端+前端搭建详细教程附源码

    准备工作 教程很详细一步步操作都可以上线,教程都是亲自发布的,希望各位要搬运的时候备注来自哪里 购买云服务器:教程等待更新 购买域名+配置ssl证书:教程待更新 常见问题: 问:域名需要备案吗? 回: ...

最新文章

  1. 今天没有浪费时间,我努力了
  2. Layui框架 中table解决日期格式问题
  3. 【笨木头Lua专栏】基础补充08:协同程序之resume-yield间的数据返回
  4. 包无法安装_R语言基础教程——第2章:R下载安装和环境搭建
  5. Day07 - Ruby比一比:Symbol符号与String字串
  6. 湘苗培优|值不值?效果告诉你
  7. torchtext处理文本数据——使用自己的word2vec模型作为词向量建立词表(学习二)
  8. JBPM中文乱码的一种解决方法
  9. mysql前179天_做up主179天的经历
  10. Java多线程Queue_Java多线程-BlockingQueue-ArrayBlockingQueue-LinkedBlockingQueue
  11. 【NOIP2014】【Luogu2118】比例简化(枚举)
  12. 【LA4992】Jungle Outpost(半平面交+二分)
  13. C++中L和_T()之区别
  14. 使用 VLD 检测内存泄漏
  15. 计算两个时间相差几年几月
  16. Python3入门视频教程百度网盘
  17. 计算机截屏无法保存,win7电脑自带截图软件保存图片失败怎么办?
  18. 浪尖聊聊大数据从业者的迷茫及解决方案
  19. hbuilderx安装教程_HBuilderX入门教程
  20. 使用exe4j+inno setup打包exe文件踩坑记录

热门文章

  1. 跨境电商推广干货:掘金东南亚和这几个推广平台
  2. Office系列---将Office文件(Word、PPT、Excel)转换为PDF文件,提取Office文件(Word、PPT)中的所有图片
  3. 建站的原型图是什么意思?
  4. 阿里内部Redis宝典遭外泄极致经典:源码+实战+理论
  5. CSS 按钮悬停效果
  6. 【论文笔记】Radatron: Accurate Detection Using Multi-Resolution Cascaded MIMO Radar
  7. Kaldi语音识别技术
  8. Python 跑深度学习遇到的一些问题集锦
  9. word如何设置每一章节的页眉都不同
  10. Android Studio4.0以上设置护眼背景色