Android SDK 示例程序贪吃蛇详解
- 格式:doc
- 大小:207.00 KB
- 文档页数:14
附录1.SnakeView类package com.example.android_snake.view;import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.Timer;import java.util.TimerTask;import com.example.android_snake.R;import com.example.android_snake.food.Food;import com.example.android_snake.snake.Body;import com.example.android_snake.snake.Head;import com.example.android_snake.snake.Snake;import com.example.android_snake.snake.SnakeDirection; import com.example.android_snake.stone.Stone;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.Style;import android.os.Handler;import android.util.DisplayMetrics;import android.view.Display;import android.view.MotionEvent;import android.view.View;import android.view.ViewManager;import android.view.WindowManager;import android.widget.Toast;public class SnakeView extends View {private Context context;private Bitmap headBitmap;private Bitmap bodyBitmap;private Bitmap foodBitmap;private Bitmap stoneBitmap;// 屏幕的高度和宽度private int screenHeight;private int screenWidth;// 每个小格子的高度和宽度private int eachHeight;private int eachWidth;private Snake snake;private Food food;private Stone stone;private int [] listx;private int [] listy;private Timer timer = new Timer();Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {moveSnake();invalidate();}};public SnakeView(Context context) {super(context);this.context = context;listx =new int[100];listy =new int[100];// 获得屏幕的高和宽DisplayMetrics metrics = new DisplayMetrics();WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);windowManager.getDefaultDisplay().getMetrics(metrics);screenHeight = metrics.heightPixels;screenWidth = metrics.widthPixels;eachHeight = screenHeight / 32;eachWidth = screenWidth / 20;// 初始化图片headBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.head);bodyBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.body);foodBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.food);stoneBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.stone);this.initSnake();this.initFood();this.initstone();gameRun();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint = new Paint();// 定义画笔paint.setColor(Color.GRAY);// 设置画笔颜色paint.setAntiAlias(true);// 去除锯齿paint.setStyle(Style.STROKE);// 设置空心实心paint.setTextSize(40);drawLines(canvas, paint);drawStone(canvas, paint);if(isCollide()){canvas.drawText("Game Over!", screenWidth/4, screenHeight/3, paint);canvas.drawText("得分", screenWidth/4, screenHeight/2, paint);timer.cancel();}else{this.drawSnake(canvas, paint);}boolean flag = IsRectCollision(snake.getHead().getPointX(), snake.getHead().getPointY(), eachWidth, eachHeight,food.getPointX(), food.getPointY(), eachWidth, eachHeight);if (flag) {food = null;snake.getBodyList().add(new Body());this.initFood();this.initstone();} else {this.drawFood(canvas, paint);this.drawStone(canvas, paint);}}//方向控制@Overridepublic boolean onTouchEvent(MotionEvent event) {int x = (int) event.getX();int y = (int) event.getY();SnakeDirection nowDir = snake.getSnakeDirection();int m = -screenHeight * x + screenHeight * screenWidth - screenWidth * y;int n = screenHeight * x - screenWidth * y;if ((m > 0 && n > 0) && (nowDir != SnakeDirection.DOWN)) {snake.setSnakeDirection(SnakeDirection.UP);} else if ((m > 0 && n < 0) && (nowDir != SnakeDirection.RIGHT)) { snake.setSnakeDirection(SnakeDirection.LEFT);} else if ((m < 0 && n > 0) && (nowDir != SnakeDirection.LEFT)) { snake.setSnakeDirection(SnakeDirection.RIGHT);} else if ((m < 0 && n < 0) && (nowDir != SnakeDirection.UP)) { snake.setSnakeDirection(SnakeDirection.DOWN);}return super.onTouchEvent(event);}public void gameRun() {timer.scheduleAtFixedRate(new TimerTask() {public void run() {handler.obtainMessage().sendToTarget();}}, 100, 400);}/** 画网格线*/public void drawLines(Canvas canvas, Paint paint) {int startX = 0, startY = 0;for (int i = 0; i < 100; i++) {canvas.drawLine(0, startY, screenWidth, startY, paint);startY = startY + eachHeight;}for (int i = 0; i < 100; i++) {canvas.drawLine(startX, 0, startX, screenHeight, paint);startX = startX + eachWidth;}canvas.drawLine(0, 0, screenWidth, screenHeight, paint);canvas.drawLine(0, screenHeight, screenWidth, 0, paint);}// 初始化蛇public void initSnake() {List<Body> bodies = new ArrayList<Body>();Head head = new Head(eachWidth * 4, eachHeight * 2, headBitmap);Body body1 = new Body(eachWidth * 3, eachHeight * 2, bodyBitmap);Body body2 = new Body(eachWidth * 2, eachHeight * 2, bodyBitmap);Body body3 = new Body(eachWidth * 1, eachHeight * 2, bodyBitmap);Body body4 = new Body(eachWidth * 0, eachHeight * 2, bodyBitmap);bodies.add(body1);bodies.add(body2);bodies.add(body3);bodies.add(body4);snake = new Snake(head, bodies, SnakeDirection.RIGHT);}// 画蛇public void drawSnake(Canvas canvas, Paint paint) {canvas.drawBitmap(headBitmap, snake.getHead().getPointX(), snake .getHead().getPointY(), paint);for (int i = 0; i < snake.getBodyList().size(); i++) {canvas.drawBitmap(bodyBitmap, snake.getBodyList().get(i).getPointX(), snake.getBodyList().get(i).getPointY(), paint);}}// 改变蛇身的位置public void changSnakePosition(int pointX, int pointY) {for (int i = snake.getBodyList().size() - 1; i > 0; i--) {snake.getBodyList().get(i).setPointX(snake.getBodyList().get(i - 1).getPointX());snake.getBodyList().get(i).setPointY(snake.getBodyList().get(i - 1).getPointY());}snake.getBodyList().get(0).setPointX(snake.getHead().getPointX());snake.getBodyList().get(0).setPointY(snake.getHead().getPointY());}// 移动蛇public void moveSnake() {int nowPointX = snake.getHead().getPointX();int nowPointY = snake.getHead().getPointY();if (snake.getSnakeDirection() == SnakeDirection.RIGHT) {changSnakePosition(nowPointX, nowPointY);if (nowPointX >= screenWidth - eachWidth) {snake.getHead().setPointX(0);} else {snake.getHead().setPointX(nowPointX + eachWidth);}} else if (snake.getSnakeDirection() == SnakeDirection.DOWN) { changSnakePosition(nowPointX, nowPointY);if (nowPointY >= screenHeight - eachHeight) {snake.getHead().setPointY(0);} else {snake.getHead().setPointY(nowPointY + eachHeight);}} else if (snake.getSnakeDirection() == SnakeDirection.LEFT) {changSnakePosition(nowPointX, nowPointY);if (nowPointX <= 0) {snake.getHead().setPointX(screenWidth - eachWidth);} else {snake.getHead().setPointX(nowPointX - eachWidth);}} else if (snake.getSnakeDirection() == SnakeDirection.UP) {changSnakePosition(nowPointX, nowPointY);if (nowPointY <= 0) {snake.getHead().setPointY(screenHeight - eachHeight);} else {snake.getHead().setPointY(nowPointY - eachHeight);}}}// 初始化foodpublic void initFood() {int x = new Random().nextInt(19);int y = new Random().nextInt(29);food = new Food(eachWidth * x, eachHeight * y, foodBitmap);}// 在界面上画出Foodpublic void drawFood(Canvas canvas, Paint paint) {if (food != null) {canvas.drawBitmap(foodBitmap, food.getPointX(), food.getPointY(),paint);}}// 初始化stonepublic void initstone() {int x = new Random().nextInt(17);int y = new Random().nextInt(23);stone = new Stone(eachWidth * x, eachHeight * y, stoneBitmap);int i=0,j=0;listx[i++]=x;listy[j++]=y;}// 在界面上画出Stonepublic void drawStone(Canvas canvas, Paint paint) {if (true) {canvas.drawBitmap(stoneBitmap, stone.getPointX(), stone.getPointY(),paint);for(int k=0;k<100;k++){//food = new Food(eachWidth * listx[k], eachHeight * listy[k], foodBitmap);//canvas.drawBitmap(stoneBitmap,listx[k], listy[k],paint);}}}/*** 矩形碰撞检测参数为x,y,width,height** @param x1* 第一个矩形的x* @param y1* 第一个矩形的y* @param w1* 第一个矩形的w* @param h1* 第一个矩形的h* @param x2* 第二个矩形的x* @param y2* 第二个矩形的y* @param w2* 第二个矩形的w* @param h2* 第二个矩形的h* @return是否碰撞*/public boolean IsRectCollision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {if (x2 > x1 && x2 >= x1 + w1) {return false;} else if (x2 < x1 && x2 <= x1 - w2) {return false;} else if (y2 > y1 && y2 >= y1 + h1) {return false;} else if (y2 < y1 && y2 <= y1 - h2) {return false;} else {return true;}}//检测蛇头是否与蛇身碰撞//检测蛇头与墙的碰撞//public boolean isCollide() {boolean flag = false;for (int i = 0; i < snake.getBodyList().size(); i++) {flag = IsRectCollision(snake.getHead().getPointX(),snake.getHead().getPointY(), eachWidth, eachHeight,snake.getBodyList().get(i).getPointX(),snake.getBodyList().get(i).getPointY(),eachWidth,eachHeight);for(int j=0;j<100;j++){flag = IsRectCollision(snake.getHead().getPointX(),snake.getHead().getPointY(), eachWidth, eachHeight,listx[j],listy[j], eachWidth,eachHeight);if(flag){break;}}if ((snake.getHead().getPointX() < 1) ||(snake.getHead().getPointY() < 1) ||(snake.getHead().getPointX() > screenWidth - 1)||(snake.getHead().getPointY() > screenHeight - 1)){flag = true;}if(flag){break;}}return flag;}}2.MainActivity类package com.example.android_snake;import com.example.android_snake.R;import com.example.android_snake.view.SnakeView;//Downloads By import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.MenuItem;import android.view.Window;import android.view.WindowManager;public class MainActivity extends Activity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);//设置全屏getWindow().setFlags(youtParams.FLAG_FULLSCREEN, youtParams.FLAG_FULLSCREEN);SnakeView view = new SnakeView(this);setContentView(view);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu);return true;}}3.Food类package com.example.android_snake.food;import android.graphics.Bitmap;public class Food {private int pointX;private int pointY;private Bitmap foodBitmap;public Food() {super();}public Food(int pointX, int pointY, Bitmap foodBitmap) { super();this.pointX = pointX;this.pointY = pointY;this.foodBitmap = foodBitmap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getFoodBitmap() {return foodBitmap;}public void setFoodBitmap(Bitmap foodBitmap) {this.foodBitmap = foodBitmap;}}4.Body类package com.example.android_snake.snake;import android.graphics.Bitmap;public class Body {private int pointX;private int pointY;private Bitmap bodyBitMap;public Body() {super();}public Body(int pointX, int pointY, Bitmap bodyBitMap) { super();this.pointX = pointX;this.pointY = pointY;this.bodyBitMap = bodyBitMap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getBodyBitMap() {return bodyBitMap;}public void setBodyBitMap(Bitmap bodyBitMap) {this.bodyBitMap = bodyBitMap;}}5.Head类package com.example.android_snake.snake;import android.graphics.Bitmap;public class Head {private int pointX;private int pointY;private Bitmap headBitMap;public Head() {super();}public Head(int pointX, int pointY, Bitmap headBitMap) {super();this.pointX = pointX;this.pointY = pointY;this.headBitMap = headBitMap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getHeadBitMap() {return headBitMap;}public void setHeadBitMap(Bitmap headBitMap) {this.headBitMap = headBitMap;}}6.Snake类package com.example.android_snake.snake;import java.util.ArrayList;import java.util.List;import android.graphics.Bitmap;public class Snake {private Head head;private Body body;private List<Body> bodyList;private SnakeDirection snakeDirection;public Snake(){}public Snake(Head head,List<Body> bodyList,SnakeDirection snakeDirection){ super();this.head = head;this.bodyList = bodyList;this.snakeDirection = snakeDirection;}public Head getHead() {return head;}public void setHead(Head head) {this.head = head;}public Body getBody() {return body;}public void setBody(Body body) {this.body = body;}public List<Body> getBodyList() {return bodyList;}public void setBodyList(List<Body> bodyList) {this.bodyList = bodyList;}public SnakeDirection getSnakeDirection() {return snakeDirection;}public void setSnakeDirection(SnakeDirection snakeDirection) { this.snakeDirection = snakeDirection;}}7.SnakeDirection类package com.example.android_snake.snake;public enum SnakeDirection {UP,DOWN,LEFT,RIGHT;}8.Stone类package com.example.android_snake.stone;import android.graphics.Bitmap;public class Stone {private int pointX;private int pointY;private Bitmap stoneBitmap;public Stone() {super();}public Stone(int pointX, int pointY, Bitmap foodBitmap) { super();this.pointX = pointX;this.pointY = pointY;this.stoneBitmap = stoneBitmap;}public int getPointX() {return pointX;}public void setPointX(int pointX) {this.pointX = pointX;}public int getPointY() {return pointY;}public void setPointY(int pointY) {this.pointY = pointY;}public Bitmap getStoneBitmap() {return stoneBitmap;}public void setFoodBitmap(Bitmap foodBitmap) { this.stoneBitmap = stoneBitmap;}}。
贪吃蛇系统功能需求分析
目录
1需求分析 (1)
2功能描述 (1)
3系统架构 (2)
4用例描述 (2)
4.1游戏开始或退出 (2)
4.2游戏难度选择 (2)
4.3游戏输赢判断 (3)
4.4得分查询 (3)
5用例图 (4)
6时序图 (5)
6.1开始与退出时序图 (5)
6.2游戏设置时序图 (5)
6.3玩游戏时序图 (6)
6.4游戏帮组时序图 (6)
7类图 (7)
8界面设计 (8)
1需求分析
此需求分析说明书对《贪吃蛇游戏》软件做了全面的用户需求分析,明确所要开发的游戏软件应具有的功能、性能与界面,使系统分析人员及软件开发人员能清楚地了解用户的需求,并在此基础上进一步提出概要设计说明书和完成后续设计与开发工作。
2功能描述
功能包括如下几点:
1)贪吃蛇的基本玩法:即可以用上、下、左、右键游戏区蛇的运动方向,使之向
着有食物的方向运动,并吞吃食物使身体增长,如果蛇在移动过程中,撞到墙
壁或身体交叉蛇头撞到自己的身体游戏结束。
2)调节蛇的运动速度:即用户可以调节蛇的速度来选择不同的难度。
3)选择关卡功能:即游戏分不同的难度级别,用户可以选择不同的难度级别进行
游戏。
4)游戏帮组:即用户可以查看游戏说明、查看英雄榜等。
3系统架构
4用例描述
4.1游戏开始或退出
4.2游戏难度选择
4.3游戏输赢判断
4.4得分查询
5用例图
6时序图
6.1开始与退出时序图
6.2游戏设置时序图
6.3玩游戏时序图
6.4游戏帮组时序图
7类图
8界面设计。
贪吃蛇设计说明书贪吃蛇设计说明书开发小组成员:目录1.需求陈述 (3)2.软件结构 (3)2.1用例图 (3)2.2类图 (4)2.3状态图---------------------------------------------------------------4 3.程序描述 (4)3.1功能 (5)3.2性能 (5)3.3输入项目 (5)3.4输出项目 (6)3.5算法 (6)3.6程序逻辑 (6)4.测试要点-----------------------------------------75.对象设计-------------------------------------------------------------------71.需求陈述1.用户需要开发一款命名为贪吃蛇的休闲小游戏2.开始游戏时,存在一条向右运动的小蛇和蛇需要吃掉的豆3.用户通过键盘的“上下左右”键控制小蛇分别向“上下左右”运动来吃掉豆,同时增加自身的长度4.小蛇吃掉游戏规定数量的豆后,游戏结束5.游戏分为初级、中级、高级6.小蛇不能碰到边界7.小蛇自身不能碰撞8.游戏可以暂停和重新开始9.游戏完成后计算所得分数10.游戏在任何时候都可以退出2.软件结构1.用例图2.类图3.状态图3.程序描述3.1功能小蛇可以通过方向键进行方向的变化。
屏幕上随机的出现豆,贪吃蛇在运动的过程中蛇头可以吃掉出现的的豆。
吃掉豆后,蛇的身体会增长一节。
当蛇的身体碰到四周的墙壁或者是自己的身体时,游戏会结束。
并且,在屏幕的上方有一个分数牌显示,游戏开始时分数为0,每当蛇吃掉一个豆,分数会增加10分。
而在游戏的过程中,玩家可以按菜单上的退出键或点击界面的关闭按钮退出游戏。
3.2性能本款游戏在界面设计上清晰明了、美观大方;在操作上简单、易懂。
有效率高,不易出错的优点。
本游戏着重于娱乐大众,并且有锻炼反应速度的特点。
3.3输入项目1)用户在界面菜单的操作有点击“开始”、“暂停”、“结束”、“重新开始”、“初级”、“中级”、“高级”。
贪吃蛇程序设计贪吃蛇是一款经典的电子游戏,其设计简单却极具挑战性,深受各个年龄段玩家的喜爱。
下面将详细介绍贪吃蛇程序的设计过程,包括基本规则、程序结构、实现方法以及可能的扩展功能。
基本规则贪吃蛇游戏的基本规则如下:1. 游戏界面是一个矩形网格,蛇在网格中移动。
2. 蛇由多个方块组成,初始时通常只有几个方块。
3. 玩家通过键盘控制蛇头的移动方向。
4. 蛇在吃到食物后,身体长度会增加一节。
5. 如果蛇头撞到自己的身体或屏幕边缘,游戏结束。
程序结构贪吃蛇程序主要包括以下几个部分:1. 游戏界面:显示蛇、食物和网格。
2. 蛇的移动逻辑:控制蛇的移动方向和速度。
3. 食物生成逻辑:随机在界面上生成食物。
4. 碰撞检测:检测蛇是否吃到食物或撞到自己及屏幕边缘。
5. 分数和生命值:记录玩家的得分和剩余生命。
实现方法1. 初始化- 设置游戏界面的大小。
- 初始化蛇的位置和长度。
- 随机生成食物的位置。
2. 游戏循环- 监听键盘输入,更新蛇头的移动方向。
- 根据移动方向更新蛇的位置。
- 检查蛇是否吃到食物,如果是,则增加蛇的长度和分数,并生成新的食物。
- 检查蛇是否撞到自己的身体或屏幕边缘,如果是,则结束游戏。
- 刷新游戏界面,显示当前的蛇、食物和分数。
3. 绘制界面- 使用图形库或API绘制网格、蛇和食物。
4. 处理用户输入- 监听键盘事件,根据用户的输入改变蛇的移动方向。
5. 碰撞检测- 检查蛇头是否与食物重叠,如果是,则触发吃食物的逻辑。
- 检查蛇头是否与蛇身其他部分重叠,如果是,则游戏结束。
- 检查蛇头是否到达屏幕边缘,如果是,则游戏结束。
可能的扩展功能1. 多种难度级别:根据游戏难度调整蛇的移动速度或食物的生成频率。
2. 特殊食物:例如,某些食物可以让蛇短暂加速或获得保护,避免碰撞。
3. 自定义皮肤:允许玩家选择或设计蛇和食物的外观。
4. 多人模式:支持多个玩家在同一设备或网络上进行游戏。
5. 成就系统:为玩家设置各种成就目标,增加游戏的可玩性。
微信⼩程序之贪吃蛇⼩游戏开发(完整代码)1:⾸先是index.wxml⽂件代码:<!--index.wxml--><canvas canvas-id='snakeCanvas' style='width:100%;height:100%;background-color:#ccc;'bindtouchstart='canvasStart' bindtouchmove='canvasMove' bindtouchend='canvasEnd'></canvas>2:然后是index.js⽂件代码//index.js//⼿指按下时的坐标var startX = 0;var startY = 0;//⼿指在canvas上移动的坐标var moveX = 0;var moveY = 0;//移动位置跟开始位置差值var X =0;var Y = 0;//⼿指⽅向var direction = null;//蛇移动⽅向var snakeDirection = "right";//⾝体对象(数组)var snakeBodys = [];//⾷物对象(数组)var foods = [];//窗⼝的宽⾼var windowWidth = 0;var windowHeight = 0;//⽤来获取屏幕⼤⼩wx.getSystemInfo({success: function (res) {windowWidth = res.windowWidth;windowHeight = res.windowHeight;}});//蛇头对象var snakeHead = {x: parseInt(Math.random() * (windowWidth-20)),y: parseInt(Math.random() * (windowHeight-20)),color: '#ff0000', //这⾥只能接受16进制没法写red这样w: 20,h: 20,reset:function(){this.x = parseInt(Math.random() * (windowWidth - 20));this.y = parseInt(Math.random() * (windowHeight - 20));}}//⽤于确定是否删除var collideBol = true;Page({canvasStart:function(e){startX = e.touches[0].x;startY = e.touches[0].y;},canvasMove:function(e){moveX = e.touches[0].x;moveY = e.touches[0].y;X = moveX - startX;Y = moveY - startY;if(Math.abs(X) > Math.abs(Y) && X > 0){direction = "right";}else if(Math.abs(X) > Math.abs(Y) && X < 0){direction = "left";}else if (Math.abs(Y) > Math.abs(X) && Y > 0) {direction = "down"; //这⾥很奇怪,是我数学坐标系没学好吗?明明Y轴正坐标是向上才对啊 }else if (Math.abs(Y) > Math.abs(X) && Y < 0) {direction = "top";}},canvasEnd:function(){snakeDirection = direction;},onReady:function(){var context = wx.createContext();//帧数var frameNum = 0;function draw(obj){context.setFillStyle(obj.color);context.beginPath();context.rect(obj.x, obj.y, obj.w, obj.h);context.closePath();context.fill();}//蛇头与⾷物碰撞函数function collide(obj1,obj2){var l1 = obj1.x;var r1 = obj1.w + l1;var t1 = obj1.y;var b1 = obj1.h+t1;var l2 = obj2.x;var r2 = obj2.w + l2;var t2 = obj2.y;var b2 = obj2.h + t2;//这⾥1是蛇头⽅块的上下左右边框 2是⾷物,同样是上下左右//(当蛇头⼜边框撞到⾷物左边框也就是⼤于左边框时就是碰撞了)if(r1>l2 && l1<r2 && b1 > t2 && t1< b2){return true;}else{return false;}}//蛇头与墙壁碰撞函数function collide2(obj1){var l1 = obj1.x;var r1 = obj1.w + l1;var t1 = obj1.y;var b1 = obj1.h + t1;if (l1 <=snakeHead.w || r1 >=windowWidth || t1 <=snakeHead.h || b1 >= windowHeight){ return true;}else{return false;}}function directionSet(){switch (snakeDirection) {case"left":snakeHead.x -= snakeHead.w;break;case"right":snakeHead.x += snakeHead.w;break;case"down":snakeHead.y += snakeHead.h;break;case"top":snakeHead.y -= snakeHead.h;break;}}function animate(){frameNum++;if (frameNum % 20 == 0){//蛇⾝体数组添加⼀个上⼀个的位置(⾝体对象)snakeBodys.push({x: snakeHead.x,y: snakeHead.y,w: 20,h: 20,color: "#00ff00"});if (snakeBodys.length > 4) {//移除不⽤的⾝体位置if (collideBol){snakeBodys.shift();}else{collideBol = true;}}directionSet();}//绘制蛇头draw(snakeHead);if (collide2(snakeHead)) {collideBol = false;snakeHead.reset();snakeBodys=[];draw(snakeHead);}//绘制蛇⾝for(var i=0;i<snakeBodys.length;i++){var snakeBody = snakeBodys[i];draw(snakeBody);}//绘制⾷物for(var i=0;i<foods.length;i++){var foodObj = foods[i];draw(foodObj);if (collide(snakeHead,foodObj)){//console.log("撞上了");collideBol = false;foodObj.reset();}}wx.drawCanvas({canvasId:"snakeCanvas",actions:context.getActions()});requestAnimationFrame(animate);}function rand(min,max){return parseInt(Math.random()*(max-min))+min;}//构造⾷物对象function Food() {var w = rand(10,20);this.w = w;this.h = w;this.x = rand(this.w, windowWidth - this.w);this.y = rand(this.h, windowHeight - this.h);this.color = "rgb("+rand(0,255)+","+rand(0,255)+","+rand(0,255)+")";//内部⽅法(重置⾷物位置颜⾊)this.reset = function (){this.x = rand(0,windowWidth);this.y = rand(0,windowHeight);this.color = "rgb(" + rand(0, 255) + "," + rand(0, 255) + "," + rand(0, 255) + ")"; }}for (var i = 0; i < 20; i++) {var foodObj = new Food();foods.push(foodObj);}animate();}})。
安卓贪吃蛇源代码#define M 200#include"graphics.h"#include<stdlib.h>#include<stdio.h>#include<string.h>#include<iostream.h>#include<dos.h>#include<conio.h>#include <windows.h>#define LEFT 97//A#define RIGHT 100//D#define DOWN 115//S#define UP 119//W#define Esc 0x011bint i,key;int score=0;int gamespeed=250;//游戏速度可根据实际情况自行调整struct Food{int x;//食物的横坐标int y;//食物的纵坐标int yes;//判断是否要出现食物的变量}food;//食物的结构体struct Snake{int x[M];int y[M];int node;//蛇的节数int direction;//蛇的移动方向int life;//蛇的生命,0表示活着,1表示死亡}snake;void Init();//图形驱动void Close();//图形结束void DrawK();//开始画面void GamePlay();//玩游戏的具体过程void GameOver();//游戏结束void PrScore();//输出成绩void main()//主函数{Init();//图形驱动DrawK();//开始画面GamePlay();//玩游戏的具体过程Close();//图形结束}void Init()//图形驱动{int gd=DETECT,gm;initgraph(&gd,&gm," ");/*此处为turboc的路径,读者可以根据自己的电脑而改*/cleardevice();}void DrawK()//开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙{setbkcolor(GREEN);setcolor(LIGHTRED);setlinestyle(0,0,5);//设置线型for(i=50;i<=600;i+=10)//画围墙{rectangle(i,40,i+10,49);//上边rectangle(i,451,i+10,460);//下边}for(i=40;i<=450;i+=10){rectangle(50,i,59,i+10);//左边rectangle(601,i,610,i+10);//右边}}void GamePlay()//玩游戏的具体过程{rand();//随机数发生器food.yes=1;//1表示需要出现新食物,0表示已经存在食物snake.life=0;//蛇活着snake.direction=1;//方向往右snake.x[0]=100;snake.y[0]=100;//舌头坐标snake.x[1]=110;snake.y[1]=100 ;snake.node=2;//蛇的节数PrScore();//输出分数while(1)//可重复玩游戏,按ESC键结束{while(!kbhit())//在没有按键的情况下,蛇自己移动身体{if(food.yes==1)//需要出现新食物{food.x=rand()%400+60;food.y=rand()%350+60;while(food.x%10!=0)//食物随即出现后必须让食物能够在整格内,这样才能让蛇迟到food.x++;while(food.y%10!=0)food.y++;food.yes=0;//画面上有食物了}if(food.yes==0)//画面上有食物就要显示{setcolor(GREEN);rectangle(food.x,food.y,food.x+10,food.y-10);}for(i=snake.node-1;i>0;i--)//蛇的每个环节往前移动,也就是贪吃蛇的关键算法{snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}switch(snake.direction)//1,2,3,4表示上下左右四个方向,通过这个判断来移动蛇头{case 1:snake.x[0]+=10;break;case 2:snake.x[0]-=10;break;case 3:snake.y[0]-=10;break;case 4:snake.y[0]+=10;break;}for(i=3;i<snake.node;i++)//从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来{if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]){GameOver();//显示失败snake.life=1;break;}}if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455)//蛇是否撞到墙壁{GameOver();//本次游戏结束snake.life=1;//蛇死}if(snake.life==1)//以上两种判断以后,如果蛇死就跳出内循环,重新开始break;if(snake.x[0]==food.x&&snake.y[0]==food.y)//吃到食物以后{setcolor(0);//把画面上的食物去掉rectangle(food.x,food.y,food.x+10,food.y-10);snake.x[snake.node]=-20;snake.y[snake.node]=-20;//新的一节先放在看不见得位置,下次循环就取前一节的位置snake.node++;//蛇的身体长一节food.yes=1;score+=10;PrScore();//输出新的得分}setcolor(WHITE);//画出蛇for(i=0;i<snake.node;i++)rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10);Sleep(gamespeed);setcolor(0);//用黑色去除蛇的最后一节rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);}if(snake.life==1)//如果蛇死就跳出循环break;key=getchar();//接受案件if(key==Esc)//按ESC键退出break;else if(key==UP&&snake.direction!=4)snake.direction=3;else if(key==RIGHT&&snake.direction!=2)snake.direction=1;else if(key==LEFT&&snake.direction!=1)snake.direction=2;else if(key==DOWN&&snake.direction!=3)snake.direction=4;}//endwhile(1)}void GameOver()//游戏结束{cleardevice();PrScore();setcolor(RED);outtextxy(100,100,"我会回来的!!!!!");getch();}void PrScore()//输出成绩{char str[10];setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(6);sprintf(str,"score:%d",score);outtextxy(55,20,str);}void Close()//图形结束{getch();closegraph();}。
基于安卓平台贪吃蛇游戏的设计一、选题依据1.设计(论文)题目:基于安卓平台贪吃蛇游戏的设计2.研究领域:通信运用3.设计(论文)工作的理论意义和应用价值目前随着移动设备越来越普及以及移动设备的硬件的提升,移动设备的功能越来越完善,android系统平台也日渐火热起来。
目前为止国内已经有很多Android系统的用户。
截止2013年Android系统的国内市场占有率已经过75%,在西欧以及北美智能手机市场占有率也在80%左右。
可见Android系统正处于发展的顶峰。
手机游戏作为Android系统平台的一个重要组成部分,正在被越来越多的人所重视。
全球在使用的移动电话已经超过59亿部,而且这个数字每天都在不断增加。
手机游戏潜在的市场比其他任何平台都要大。
二、设计研究的内容1.重点解决的问题(1)基于Android游戏动画的实现(2)游戏地图的数据结构的表示(3)游戏动画中的碰撞检测问题2.拟开展研究的几个主要方面:1理论上和实践上的意义关于Android游戏动画,基于安卓平台实现一个相对高效并且简单易用的游戏引擎,或者从其他手机平台移植相对较为成熟的游戏动画引擎。
解决此问题可以为贪吃蛇游戏以及其他类似的动画游戏提供流畅的动画效果,实现游戏引擎同时也可以提高游戏动画的代码复用率,提高游戏编程的效率。
深入理解Android系统的Dalvik虚拟机工作机制。
由于Android平台使用Java语言进行开发,谷歌的工程师改写了Java ME的虚拟机。
解决虚拟机垃圾回收时所造成的占用系统资源较大的问题,可以提高游戏的流畅性,提升用户的游戏体验。
解决游戏人工智能的解决方案,贪吃蛇游戏中,地图寻路问题并非如此简单,必须考虑多方面的因素。
触屏以及重力感应器等操控方式的处理问题。
在Android平台中相对传统的手机系统,Android系统提供多种传感器的调用接口。
探索使用手机导航球,重力感应,触屏操作等新型操控模式提高用户操作体验。
Android SDK 示例程序贪吃蛇详解
转载
Snake也是一个经典游戏了,Nokia蓝屏机的王牌游戏之一。
Android SDK 1.5就有了它的身影。
我们这里就来详细解析一下Android SDK Sample中的Snake工程。
本工程基于SDK 2.3.3版本中的工程,路径为:%Android_SDK_HOME% /samples/android-10/Snake
一、Eclipse工程
通过File-New Project-Android-Android Project,选择“Create project from existing sample”创建自己的应用SnakeAndroid,如下图:
运行效果如下图:
二、工程结构和类图
其实Snake的工程蛮简单的,源文件就三个:Snake.java SnakeView.java TileView.java。
Snake 类是这个游戏的入口点,TitleView类进行游戏的绘画,SnakeView类则是对游戏控制操作的处理。
Coordinate,RefreshHandler是2个辅助类,也是SnakeView类中的内部类。
其中,Coordinate是一个点的坐标(x,y),RefreshHandler将RefreshHandler对象绑定某个线程并给它发送消息。
如下图:
任何游戏都需要有个引擎来推动游戏的运行,最简化的游戏引擎就是:在一个线程中While 循环,检测用户操作,对用户的操作作出反应,更新游戏的界面,直到用户退出游戏。
在Snake这个游戏中,辅助类RefreshHandler继承自Handler,用来把RefreshHandler与当前线程进行绑定,从而可以直接给线程发送消息并处理消息。
注意一点:Handle对消息的处理都是异步。
RefreshHandler在Handler的基础上增加sleep()接口,用来每隔一个时间段后给当前线程发送一个消息。
handleMessage()方法在接受消息后,根据当前的游戏状态重绘界面,运行机制如下:
这比较类似定时器的概念,在特定的时刻发送消息,根据消息处理相应的事件。
update()与sleep()间接的相互调用就构成了一个循环。
这里要注意:mRedrawHandle绑定的是Avtivity 所在的线程,也就是程序的主线程;另外由于sleep()是个异步函数,所以update()与sleep()之间的相互调用才没有构成死循环。
最后分析下游戏数据的保存机制,如下:
这里考虑了Activity的生命周期:如果用户在游戏期间离开游戏界面,游戏暂停;或者由于内存比较紧张,Android关闭游戏释放内存,那么当用户返回游戏界面的时候恢复到上次离开时的界面。
三、源码解析
详细解析下源代码,由于代码量不大,以注释的方式列出如下:
3、TileView.java
四、工程文件下载
为了方便大家阅读,可以到如下地址下载工程源代码:
/f/14312223.html
五、小结及下期预告:
本次详细解析了Android SDK 自带Sample——Snake的结构和功能。
下次将会把这个游戏移植到J2ME平台上,并且比较Android和J2ME的区别和相通之处,让从事过J2ME开发的朋友对Android开发有个更加直观的认识。