资源描述
Android贪吃蛇课程设计报告
综 合 实 践 报 告
课程名称 计算机系统综合实训
课题名称 贪吃蛇游戏开发
专 业 计算机科学与技术
班 级
学 号
姓 名
指导教师
2015年 12月 20日
湖南工程学院
课 程 设 计 任 务 书
课程名称 计算机系统综合实训
课 题 贪吃蛇游戏开发
专业班级 计算机1202
学生姓名
学 号
指导老师
审 批
任务书下达日期 2015 年 12月 20 日
任务完成日期 2016年 1月 11日
任务书
一、实训的内容
(1)设计内容:
在屏幕上设计一个贪吃蛇游戏,屏幕四周被绿色苹果包围,中间有贪吃蛇和随机产生的苹果,贪吃蛇的头是黄色的,身子是红色的。玩家按上、下、左、右键盘控制贪吃蛇在屏幕上向上、下、左、右移动,贪吃蛇只能向左、右方向90度转弯,当吃到一个苹果贪吃蛇就长一节,分数加一分,同时屏幕上又随机产生的一个黄色苹果,一旦碰到墙壁或自己的尾巴就失败。提示游戏得到的分数。
贪吃蛇游戏规则:
游戏初始化:在本游戏中,采用如下的策略进行初始化:将贪吃蛇基本初始化在屏幕的中央,初始移动方向和贪吃蛇节点的排列顺序一致,食物的坐标固定位置。
贪吃蛇的移动:除第一个节点以外,其它每个节点跟随前一个节点移动
贪吃蛇方向控制:贪吃蛇方向控制需要根据玩家的按键改变贪吃蛇的方向变量,在改变时需要注意,不能改变为当前方向的相反方向,例如当前方向是向下时,按向上的方向键是无效的。
(2) 设计要求:
按任务书的设计要求进行撰写。
其中游戏核心数据结构设计要求为:主要是界面控制信息和逻辑控制信息, 界面控制信息主要包含两个部分:贪吃蛇的位置信息,存储贪吃蛇的具体位置,另外一个就是闪烁的食物的位置。而逻辑控制信息主要包含三个部分:贪吃蛇的移动方向、闪烁控制以及程序暂停控制。
碰撞和处理,包括贪吃蛇和食物的碰撞和处理,贪吃蛇和四周的碰撞和处理,贪吃蛇的头和身的碰撞和处理,
二、综合实训时间安排
具体时间及要求安排如下:
综合实训时间为17~18周,包括上机与查资料。
17周安排(12月28日开始)
星期一(12月28日)
上午
星期二(12月29日)
下午
星期三(12月30日)
上午
星期四(12月31日)
上午
第18周
星期一至星期三上午 风华科技老师来校讲课
星期三下午去九华参观
星期四至星期五,卓京来校讲课
三、综合实训报告撰写要求
正文的内容:
1、课程实训目的及要求;
2、设计思路(需求分析、功能介绍、模块划分);
3、主要功能的实现(至少要有一个主要模块的流程图);
4、程序调试;
5、总结;
6、附件(所有程序的源代码,要求对程序写出必要的注释)。正文总字数要求在5000字以上(不含程序原代码)
附:课程实训报告装订顺序:封面、任务书、目录、正文、评分、附件(A4大小的图纸及程序清单)。
正文的格式:一级标题用3号黑体,二级标题用四号宋体加粗,正文用小四号宋体;行距为22。
目录
一、课程实训目的及要求 1
、课程实训目的 1
、课程实训要求 1
二、设计思路 1
、需求分析 1
、游戏界面分析 1
、游戏角色分析 1
、游戏控制分析 2
、可行性分析 2
、功能介绍 2
、模块划分 3
、系统功能模块层次 3
、运行机制 4
三、主要功能的实现 5
、功能流程图 5
四、程序调试 6
、功能测试 6
、测试结果 6
五、总结 6
六、 附件 8
、源代码 8
一、课程实训目的及要求
、课程实训目的
计算机系统综合实训能培养学生独立进行资料收集,综合运用所学的多门课程知识,培养分析问题和解决问题能力。验证和巩固充实所学理论知识,加深对相关内容的理解,能运用所学知识为社会服务,在实训中学习和锻炼,增长才干。本次实训采用项目制,要求学生进一步理解和掌握软件工程的方法和技术,培养合作意识、团队精神和技术文档的编写能力。为了让同学们更好地了解3G的目前应用情况,我们将邀请风华科技和卓京老师进行五天实训培训。
、课程实训要求
实训要求采用“项目小组”的形式,结合具体的开发项目进行设计。具体要求如下:
~9人,项目小组成员自行组织。
。
,按时完成每部分工作。
。
#和512#机房进行。
二、设计思路
、需求分析
、游戏界面分析
操作界面应该人性化设计,提示玩家按什么按键开始游戏,开始游戏之后,在游戏界面中,以坐标的形式对整体界面进行划分,将界面划分为网格,还应设计蛇的样式,食物的样式和墙的样式,在蛇吃到食物后的样式,还有游戏结束时的界面显示,游戏结束后,要显示所得的分数。
、游戏角色分析
设置游戏贪吃蛇初始时由固定小矩形块组成,在游戏中,要随机出现由单个矩形块构成的食物,并且设置随机出现的食物不要出现在蛇的身体中,在蛇吃到食物的时候,蛇的身体加长。此外,要判定游戏成功与失败的条件,当蛇的头和尾相撞或者蛇的头部撞到了墙上,则游戏失败,此时游戏结束,界面显示所得分数。另外蛇的移动原理,由外部按键设置监听控制蛇头的移动方向,在方向的指引下进行移动,蛇及食物的位置都是由坐标数组确定的,食物的位置也是随机产生的蛇的移动原理是后一矩形块覆盖前一个矩形块。当一个食物被吃掉的时候,要自动随机生成并显示下一个食物的位置。这些都是在设计过程中需要实现的。
、游戏控制分析
游戏中需要通过按键对蛇的移动方位进行控制,共需要设置四个方位,分别是“东”“西”“南”“北”,在按键上用“上”“下”“左”“右”,按键与执行部分涉及到监听,通过监听指示蛇的运动,此外,要设置蛇移动是的默认方向为“右”,蛇的移动只能是90度偏转,不能进行180度偏转。此外还要设置游戏的状态,有运行和结束两种状态,蛇体变长的时候用静态变量进行加分。
、可行性分析
贪吃蛇游戏是一种简单的大众的游戏,自从进入现代化以来,深受广大电脑和玩家的喜爱,所以做一个简单的贪吃蛇小游戏是有用的。
本次设计我主要运用Java语言来完成。Java语言是一种跨平台,适合于分布式计算环境的面向对象编程语言,用Java写的应用程序不用修改就可在不同的软硬件平台上运行。
由于Java主要用于网络应用程序开发,因此对安全性有较高的要求。如果没有安全保证,用户从网络下载程序执行就非常危险。Java通过自己的安全机制防止了病毒程序的产生和下载程序对本地系统的威胁破坏。
、功能介绍
贪吃蛇游戏是一款游戏,同时也是一款比较需要耐心的游戏。贪吃蛇游戏是一条蛇,不停地在屏幕上游走,吃在屏幕上出现的食物。当蛇吃掉1个食物后会变长,并且吃完食物时食物会消失,并立即随机生成1个新的食物,只要蛇头碰到屏幕四周或者碰到自己的身子,蛇就立即毙命。
:系统功能模块层次图
、运行机制
任何游戏都需要有个引擎来推动游戏的运行,在贪吃蛇这个游戏中,辅助类 MyHandler继承自 Handler,用来把 MyHandler与当前线程进行绑定,从而可以直接给线程发送消息并处理消息。注意一点: Handle对消息的处理都是异步。 MyHandler在 Handler的基础上增加 sleep()接口,用来每隔一个时间段后给当前线程发送一个消息。handleMessage()方法在接受消息后,根据当前的游戏状态重绘界面。update()与 sleep()间接的相互调用就构成了一个循环。由于 sleep()是个异步函数,所以 update()与 sleep()之间的相互调用才没有构成死循环。
:运行机制
三、主要功能的实现
、功能流程图
开始
始初化蛇和食物
屏幕显示蛇和食物位置
蛇开始移动,后坐标覆盖前坐标
是否有按键
否
根据上次方向更新坐标
是
根据按键不同在原坐标基础上改变蛇的坐标位置
更新方向
是否吃到食物
是
蛇身加1
否
是否越界或撞到蛇身
是
游戏结束
否
:功能流程图
四、程序调试
、功能测试
经过在模拟器上的测试,本软件能实现其功能,达到了小蛇在屏幕上的移动,小蛇吃食物,食物随机出现的功能,当小蛇头尾相撞或与墙相撞时,。
:运行时截图
、测试结果
通过对游戏软件的功能测试,控制测试和界面测试。对游戏的开始新游戏、退出和统计分数功能进行测试,并测试程序的键盘点击事件,结论是该游戏软件能正确实现功能要求。要求输出的效果与预期的输出效果完全一致。
五、总结
本次Java课程设计我们这组做的课题是设计贪吃蛇游戏,刚开始拿到题目我们组员都不知如何下手,经过小组成员一起查找资料,并且开会讨论,我们确定了设计的设计目标以及具体实现方式,包括如何将Java的思想运用到实际系统的详细设计之中。实验过程中,首先要将系统要实现的功能分为几大模块,然后每个组员分别完成,在此过程中使我加深了对Java的理解,以及如何进行团队工作的划分,学会发现各组员的长处并将其发挥出来。虽然大家没怎么学过Java,但大家都有C语言基础,所以通过努力实验,进一步培养我们利用Java语言进行编程和调试程序的能力,同时使我们能够学会将C语言与Java语言结合起来编写较复杂具有实际意义和算法复杂度较小的程序。与此同时熟练掌握Java语言的编辑,编译,调试程序,并将算法转变为程序实现。正确理解各种数据结构的逻辑特性和存储表示和基本操作的算法实现。掌握算法的时间分析和空间分析的技术。针对问题的特点选择合适的数据结构,设计实用高效的算法,提高大家的算法设计的能力和动手实验的技能。
六、附件
、源代码
SnakeActivity类:程序的入口,程序的界面。代码如下:
package ;
import ;
import ;
public class SnakeActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
(savedInstanceState);
setContentView();
().addActivity(this);
}
}
MyTile类:MyTile的基类是View,包含了贪吃蛇游戏画面的各个设定参数,主要负责绘制游戏画面。还定义了游戏运行时的画面改变及蛇体和食物的更新方法。MyTile类定义如下:
package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
@SuppressLint("DrawAllocation")
public class MyTile extends View {
private int size = 12; // 图片大小
private int xCount; // 横向格子
private int yCount; // 纵向格子
private int xOffset; // 原点坐标
private int yOffset; // 原点坐标
private int[][] map; // 地图数组
private Bitmap[] pics; // 图片数组
private static final int GERRN_STAR = 1; // 绿色图片
private static final int RED_STAR = 2; // 红色图片
private static final int YELLOW_STAR = 3; // 黄色图片
public static final int UP = 1; // 键盘上
public static final int RIGHT = 2; // 键盘右
public static final int DOWN = 3; // 键盘下
public static final int LEFT = 4; // 键盘左
public int direction; // 方向
private static final Random RANDOM = new Random();// 随机变量
private ArrayList<Coordinate> snakeList = new ArrayList<Coordinate>();// 蛇身数组
private ArrayList<Coordinate> appleList = new ArrayList<Coordinate>();// 苹果数组
private MyHandler handler = new MyHandler();// 线程
//private TextView snakeView;
private Context myTileContext;
private int isContinue=0;//停止游戏
public static long score=0;//游戏分数
// 从布局文件读取图片
public MyTile(Context context, AttributeSet attrs) {
super(context, attrs);
("MyTile(Context context, AttributeSet attrs) ");
myTileContext=context;
setFocusable(true);
// TODO Auto-generated constructor stub
}
// 绘图方法 Canvas:画布
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
(canvas);
("onDraw(Canvas canvas) ");
Paint myPaint = new Paint();// 生成一个画笔
// 循环绘制墙
for (int x = 0; x < xCount; x++) {
for (int y = 0; y < yCount; y++) {
// ("map[" + x + "]" + "[" + y + "]" + ":" +
// map[x][y]);
if (map[x][y] > 0) {// 判断已赋值的地图数组/ map[x][y]=1/ 绘制墙
(pics[map[x][y]],// pics[map[x][y]]=1 /绿色
xOffset + x * size, yOffset + y * size, myPaint);
}
}
}
}
// 屏幕发生变化时自动执行/屏幕的宽和高,在程序一开始就获取屏幕的宽和高。
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
(w, h, oldw, oldh);
("onSizeChanged(int w, int h, int oldw, int oldh) ");
xCount = (int) (w / size); // 四舍五入/取整/x轴格子总数
yCount = (int) (h / size); // 四舍五入/取整/y轴格子总数
xOffset = (w - xCount * size) / 2;// 原点坐标
yOffset = (h - yCount * size) / 2;// 原点坐标
map = new int[xCount][yCount];// 地图总格子
initGame();// 初始化游戏
}
// 初始化游戏
public void initGame() {
("initGame()");
();//清空蛇
();//清空食物
score=1000000000;//初始化分数
pics = new Bitmap[4];// 实例化图片数组
Resources resources = getContext().getResources();// 获取资源
loadPic(GERRN_STAR, ());// 加载图片
loadPic(RED_STAR, ());
loadPic(YELLOW_STAR, ());
(new Coordinate(5, 7));
(new Coordinate(4, 7));
(new Coordinate(3, 7));
(new Coordinate(2, 7));
direction = RIGHT;// 蛇的默认方向:右
addRandomApple();// 生成一个随机位置的苹果
update();// 实现重绘一次
}
// 加载图片
public void loadPic(int key, Drawable drawable) {
.println("loadPic(int key, Drawable drawable) ");
Bitmap bitmap = Bitmap
.createBitmap(size, size, );// 图片大小
Canvas canvas = new Canvas(bitmap);// 画布
(0, 0, size, size);// 设置位置大小
(canvas);
pics[key] = bitmap;
}
public void update() {
("update()");
clearTile(); // 清空
buildWall(); // 重绘墙
updateSnake(); // 更新蛇
updateApple(); // 更新苹果
(200);
}
public void clearTile() {
("clearTile()");
for (int x = 0; x < xCount; x++) {
for (int y = 0; y < yCount; y++) {
setTile(0, x, y);// 不给图形
}
}
}
// 为地图数组赋值
public void setTile(int picIndex, int x, int y) {
map[x][y] = picIndex;// 根据map[x][y]=1,初始化时再赋值
}
// 绘制墙
public void buildWall() {
("buildWall()");
for (int x = 0; x < xCount; x++) {
setTile(GERRN_STAR, x, 0); // 上
setTile(GERRN_STAR, x, yCount - 1); // 下
}
for (int y = 0; y < yCount; y++) {
setTile(GERRN_STAR, 0, y); // 左
setTile(GERRN_STAR, xCount - 1, y); // 右
}
}
public void updateSnake() {
boolean growSnake = false;// 蛇的生长标志
("updateSnake()");
Coordinate header = (0);
Coordinate newHeader = new Coordinate(1, 1);
switch (direction) {
case UP:
newHeader = new Coordinate(, - 1);
break;
case RIGHT:
newHeader = new Coordinate( + 1, );
break;
case DOWN:
newHeader = new Coordinate(, + 1);
break;
case LEFT:
newHeader = new Coordinate( - 1, );
break;
}
// 游戏结束
if ( < 1 || < 1 || > xCount - 2
|| > yCount - 2) {
gameOver();
return;
}
// 冲突检测新蛇头是否和自身坐标重叠,重叠的话游戏也结束
int snakelength = ();
for (int snakeindex = 0; snakeindex < snakelength; snakeindex++) {
Coordinate c = (snakeindex);
if ((newHeader)) {
gameOver();
return;
}
}
// 蛇吃掉苹果、新蛇头和苹果是否重叠
int appleLength = ();
for (int appleIndex = 0; appleIndex < appleLength; appleIndex++) {
Coordinate c = (appleIndex);
if ((newHeader)) {
(c); // 如果重叠,苹果坐标从苹果列表中移除
addRandomApple();// 再立刻增加一个新苹果
score += 10;
growSnake = true;// 蛇增长标志改为真
}
}
// 当蛇吃掉苹果后,增加长度
(0, newHeader);// 在蛇头的位置增加一个新坐标
if (!growSnake) {// 如果没有增长
// 如果蛇头没增长则删去最后一个坐标,相当于蛇向前走了一步
(() - 1);
}
// 重新设置一下颜色,蛇头是黄色的,蛇身是红色的
int index = 0;
for (Coordinate c : snakeList) {
if (index == 0) {
setTile(YELLOW_STAR, , );
} else {
setTile(RED_STAR, , );
}
index++;
}
}
//游戏结束提示
public void gameOver(){
Intent intent= new Intent();
(myTileContext, );
();
(intent);
isContinue=100;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
switch (keyCode) {
case :
direction = UP;
break;
case :
direction = RIGHT;
break;
case :
direction = DOWN;
break;
case :
direction = LEFT;
break;
}
return (keyCode, event);
}
// 产生随机苹果,需要进行冲突检查
private void addRandomApple() {
Coordinate newCoor = null;// 新的坐标
boolean found = false;// 防止苹果出现在蛇的身上
while (!found) {// 没有找到合适的苹果,就在循环体内一直循环,直到找到合适的苹果
int newX = 1 + (xCount - 2);// 随机生成食物的X坐标
int newY = 1 + (yCount - 2);// 随机生成食物的Y坐标
newCoor = new Coordinate(newX, newY);
boolean collision = false;// 确保新苹果不在蛇身下,先假设没有发生冲突
for (int index = 0; index < (); index++) {
// 只要和蛇占据的任何一个坐标相同,即认为发生冲突了
if ((index).equals(newCoor)) {
collision = true;// 发生冲突
}
}
found = !collision;// false,推出循环
}
(newCoor);// 生成一个新苹果放在苹果列表中
}
// 苹果的图形
public void updateApple() {
for (Coordinate c : appleList) {
setTile(YELLOW_STAR, , );
}
}
// 坐标类 记录蛇的位置
private class Coordinate {
private int x;
private int y;
public Coordinate(int x, int y) {
super();
= x;
= y;
}
// 冲突检查,蛇是否吃到苹果
public boolean equals(Coordinate other) {
if (x == && y == ) {
return true;
}
return false;
}
}
// 类似线程 Handler:可以定时处理或者分发消息
class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
("handleMessage(Message msg)"+msg);
/**
* 收到下面的sleep发送回来的消息时执行
*/
if(isContinue==100){
return ;
}else{
(msg);// 发送消息
update();// 更新蛇
// 调用onDraw方法重绘
();// 实现重绘 刷新页面
}
}
public void sleep(int delay) {
("sleep(int delay) ");
this. // 发送空消息激活handleMessage //发送空消息激活handleMessage (0);
// 发送空消息激活handleMessage
sendMessageDelayed(obtainMessage(0), delay);
}
}
}
NextActivity类:游戏结束界面,游戏结束显示游戏的分数,游戏提示,是否继续,是否退出。代码如下:
package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class NextActivity extends Activity{
String fenshuString="0";
private Button jixuButton;
private Button tuichuButton;
private TextView fenshuTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
("提示Activity!!!");
(savedInstanceState);
();
jixuButton=(Button)findViewById();
tuichuButton=(Button)findViewById();
fenshuTextView=(TextView)findViewById();
fenshuString="分数:"++"";
(fenshuString);
(new JiXuButtonListener());//注册监听器
(new TuiChuButtonListener());
().addActivity(this);
}
class JiXuButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
(, );
(intent);
}
}
class TuiChuButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
().exit();
}
}
}
SysApplication类:退出游戏时,推出整个应用程序。代码如下:
package ;
import ;
import ;
import ;
import ;
public class SysApplication extends Application {
private List<Activity> mList = new LinkedList<Activity>();
private static SysApplication instance;
private SysApplication() {
}
public synchronized static SysApplication getInstance() {
if (null == instance) {
instance = new SysApplication();
}
return instance;
}
// add Activity
public void addActivity(Activity activity) {
(activity);
}
public void exit() {
try {
for (Activity activity : mList) {
if (activity != null)
();
}
} catch (Exception e) {
();
} finally {
(0); //最终执行
}
}
}
界面设计:界面设计包括游戏主界面、游戏结束界面的设计。界面的设计采用的是xml文档形式,在xml文档中规划好界面布局布局后,分别在java文件中声明。
(1)游戏主界面,主界面采用线性布局设定,指定自定义的控件。:
<?xml version="" encoding="utf-8"?>
<LinearLayout xmlns:android=""
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000">
<
android:id="@+id/snake"
android:lay
展开阅读全文