当前位置:   article > 正文

android 简单的贪吃蛇小游戏_android 集成小游戏

android 集成小游戏

贪吃蛇是一款经典的小游戏,游戏比较简单,实现也比较简单。

本篇博客将详细介绍我自己写的贪吃蛇的思路以及实现方式。

首先我们需要在游戏界面将游戏区域划分成无数个小方格,类似下图

画布(游戏区域)的宽为 width 高为 height ,列数 sizex=width/pointSize ,行数 sizey=height/pointSize. 由于画布的长宽不一定是pointSize的整数倍,所以为了所有的数据居中需要设置 x轴 y轴的偏移量(当前貌似偏移量可有可无,本人强迫症一定要加上),offsetX=(width - sizex*pointSize)/ 2,offsetY=(height - sizey*pointSize) / 2.

新建数组 spoints=new int[ sizex ][ sizey ] 用于保存方格矩阵 其中 spoints[x][y]==1说明该点属于当前小蛇身体的一部分, spoints[x][y]==0则表示小蛇当前未运动到此点。

新建 ArrayList<Point> points=new ArrayList<Point>(); 用于保存小蛇的身体的所有节点(points 中的 所有point的x,y对应的是 spoints数组的所有值为1的点的下标),points.get(0) 为头部坐标点,最后一个为尾部坐标点

   

 上面两幅图片代表的意思相同,都表示小蛇的当前状态(小蛇画的比较丑,请见谅)

下面开始考虑的小蛇的移动,小蛇的移动可以看成是将小蛇的尾巴的移动到小蛇的头部(根据方向判断移动的上下左右位置),其他的节点保持不动,见图示

得到下图运动后的状态

然后修改spoints数组对应的坐标的值,新增的头部对应的值修改为 1,移除的尾部的值修改为 0. 并将对应的坐标点加入points链表的对应位置,移除尾部的坐标点

解决了小蛇的移动问题,再来解决小蛇吃食物点的问题。

当小蛇吃到食物的时候,相当于将食物的点当成新的头部,而尾部不变,这样就相当于吃了之后变长了

这样就完成了小蛇的增长。

没有代码那就是耍流氓!!下面开始贴代码

git代码下载: 贪吃蛇          https://gitee.com/wuchang0213/TCS.git

csdn下载:https://download.csdn.net/download/weixin_41191134/10832869

再提供一个数独小游戏的下载:https://download.csdn.net/download/weixin_41191134/10832903

只贴了要的游戏界面的代码

  1. public class TcsView extends View {
  2. private Paint paint;
  3. //小蛇的组成点
  4. private ArrayList<Point> points=new ArrayList<Point>();
  5. private Point pointFood=new Point();//食物点
  6. //游戏界面的 方格划分
  7. private int[][] spoints;
  8. //方格数组的大小
  9. private int sizex;
  10. private int sizey;
  11. //小蛇的头部对应在数组中的位置
  12. private int headerX;
  13. private int headerY;
  14. //食物的坐标点
  15. private int foodX;
  16. private int foodY;
  17. //偏移量
  18. private int offsetX=0;
  19. private int offsetY=0;
  20. //随机数
  21. private Random random=new Random();
  22. private boolean isStart=true;
  23. //屏幕宽高
  24. private int width;
  25. private int height;
  26. //小蛇方块的大小
  27. private int pointSize=20;
  28. //方向
  29. private int direction=0;// 0 上 -1 下 1 左 2 右
  30. //触摸点坐标
  31. private float tdx;
  32. private float tdy;
  33. private boolean isStop=false;
  34. private TcsScoreListener tcsScoreListener;
  35. private Handler handler=new Handler(new Handler.Callback() {
  36. @Override
  37. public boolean handleMessage(Message message) {
  38. switch (message.what){
  39. case 1:
  40. headerNext();
  41. break;
  42. }
  43. return false;
  44. }
  45. });
  46. private void headerNext(){
  47. if(points.size()==0||isStop||foodX==-1) return;
  48. //小蛇的移动控制,可以看成是小蛇的首尾发生了移动,
  49. // 头部根据下一次移动的方向移动到下一格,然后去掉结尾
  50. switch (direction){
  51. case 0:
  52. headerY--;
  53. break;
  54. case -1:
  55. headerY++;
  56. break;
  57. case 1:
  58. headerX--;
  59. break;
  60. case 2:
  61. headerX++;
  62. break;
  63. }
  64. //判断是否到达边界
  65. if(headerX<0||headerY<0){
  66. isStop=true;
  67. }else {
  68. //判断小蛇是否吃到自己
  69. if(spoints[headerX][headerY]==1){
  70. isStop=true;
  71. }
  72. points.add(0,new Point(headerX,headerY));
  73. spoints[headerX][headerY]=1;
  74. if(tcsScoreListener!=null){
  75. tcsScoreListener.onTCSScore(points.size());
  76. }
  77. if(headerX==foodX && headerY==foodY){
  78. foodX=-1;
  79. foodY=-1;
  80. initPointFood();
  81. }else {
  82. Point move=points.get(points.size()-1);
  83. spoints[move.x][move.y]=0;
  84. points.remove(points.size() - 1);
  85. }
  86. if (!isStop){
  87. invalidate();
  88. }
  89. }
  90. }
  91. public TcsView(Context context, @Nullable AttributeSet attrs) {
  92. super(context, attrs);
  93. init();
  94. }
  95. private void init() {
  96. paint=new Paint();
  97. paint.setStrokeJoin(Paint.Join.ROUND);
  98. paint.setStrokeCap(Paint.Cap.ROUND);
  99. paint.setStrokeWidth(1);
  100. paint.setAntiAlias(true);
  101. //100为时间的发生间隔,即小蛇多久移动一次,此处修改可调节小蛇的速度
  102. new Timer().schedule(new TimerTask() {
  103. @Override
  104. public void run() {
  105. handler.sendEmptyMessage(1);
  106. }
  107. },0,100);
  108. }
  109. public void setTcsScoreListener(TcsScoreListener tcsScoreListener) {
  110. this.tcsScoreListener = tcsScoreListener;
  111. }
  112. @SuppressLint("DrawAllocation")
  113. @Override
  114. protected void onDraw(Canvas canvas) {
  115. super.onDraw(canvas);
  116. width=getWidth();
  117. height=getHeight();
  118. if(isStart){
  119. //根据宽高以及 pointSize 将游戏区域划分成不同的矩形区块,
  120. sizex=width/pointSize;
  121. sizey=height/pointSize;
  122. spoints=new int[sizex][sizey];
  123. //计算偏移量
  124. offsetX=(width-(sizex*pointSize))/2;
  125. offsetY=(height-(sizey*pointSize))/2;
  126. //头部起始坐标默认在屏幕中央
  127. headerX=sizex/2;
  128. headerY=sizey/2;
  129. spoints[headerX][headerY]=1;
  130. points.add(0,new Point(headerX,headerY));
  131. initPointFood();
  132. isStart=false;
  133. }
  134. for(int i=0;i<points.size();i++){
  135. Point point=points.get(i);
  136. drawPoint(canvas,paint,point);
  137. }
  138. drawPoint(canvas,paint,pointFood);
  139. }
  140. @SuppressLint("ClickableViewAccessibility")
  141. @Override
  142. public boolean onTouchEvent(MotionEvent event) {
  143. if(!isStop) {
  144. switch (event.getAction()) {
  145. case MotionEvent.ACTION_DOWN:
  146. tdx = event.getX();
  147. tdy = event.getY();
  148. break;
  149. case MotionEvent.ACTION_UP:
  150. float dx = Math.abs(tdx - event.getX());
  151. float dy = Math.abs(tdy - event.getY());
  152. if (dx > 40 || dy > 40) {
  153. //判断为滑动,不是点击
  154. Log.d("*****onTouchEvent****", "/**/*/*//**98*8/*9*/89*898565/*** ");
  155. } else {
  156. if (direction == 0 || direction == -1) {
  157. if (tdx > points.get(0).x) {
  158. direction = 2;
  159. } else {
  160. direction = 1;
  161. }
  162. } else if (direction == 1 || direction == 2) {
  163. if (tdy > points.get(0).y) {
  164. direction = -1;
  165. } else {
  166. direction = 0;
  167. }
  168. }
  169. handler.sendEmptyMessage(1);
  170. }
  171. break;
  172. }
  173. }
  174. return super.onTouchEvent(event);
  175. }
  176. //根据点的左边画出对应的点
  177. private void drawPoint(Canvas canvas,Paint paint,Point point){
  178. RectF rectF=new RectF(
  179. offsetX+point.x*pointSize,
  180. offsetY+point.y*pointSize,
  181. offsetX+(point.x+1)*pointSize,
  182. offsetY+(point.y+1)*pointSize);
  183. canvas.drawRect(rectF,paint);
  184. }
  185. /**
  186. * 确定食物点的位置
  187. */
  188. private void initPointFood(){
  189. foodX=random.nextInt(sizex);//获取随机的坐标点
  190. foodY=random.nextInt(sizey);
  191. //判断当前坐标点是否在小蛇的轨迹上
  192. if(spoints[foodX][foodY]==1){
  193. initPointFood();
  194. }else {
  195. //标准化坐标位置
  196. pointFood.set(foodX,foodY);
  197. }
  198. }
  199. /**
  200. * 根据传入的参数 修改小蛇的运动方向
  201. * @param dire
  202. */
  203. public void changeDirection(int dire) {
  204. switch (dire){
  205. case 0:// 小蛇上下运动时 可修改为左右运动
  206. case -1:
  207. if(direction==1||direction==2){
  208. direction=dire;
  209. }
  210. break;
  211. case 1://小蛇左右运动时 可修改方向为上下运动
  212. case 2:
  213. if(direction==0||direction==-1){
  214. direction=dire;
  215. }
  216. break;
  217. }
  218. }
  219. /**
  220. * 设置重新开始
  221. */
  222. public void restart(){
  223. isStop=false;
  224. isStart=true;
  225. points.clear();
  226. invalidate();
  227. }
  228. }
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号