安卓大作业围住神经猫小游戏.docx
《安卓大作业围住神经猫小游戏.docx》由会员分享,可在线阅读,更多相关《安卓大作业围住神经猫小游戏.docx(23页珍藏版)》请在冰豆网上搜索。
安卓大作业围住神经猫小游戏
《移动终端应用开发》
大
作
业
报
告
书
题目:
围住神经猫小游戏
专业:
计算机科学与技术
学号:
学生姓名:
××
指导教师:
叉叉叉
完成日期:
2016-5-31
一需求分析
安卓游戏已经是大势所趋,开发安卓游戏也将是游戏开发者的重中之重,所以我选择试做一个安卓小游戏来作为我的android课程大作业。
围住神经猫是一款益智类的小游戏,它可以在人们生活烦躁工作无聊之时提高一种新的打发时间、舒缓压力的休闲方式,也可以锻炼人的逻辑思维能力、判断力和观察力。
首先我们从游戏界面开始分析,一开始是游戏欢迎界面,点击“开始游戏”,就可以切换到游戏界面,开始玩游戏了。
在游戏界面中,有游戏背景,还有神经猫在移动时的样式,并把神经猫可移动的范围以坐标的方式分为若干个点。
游戏结束时会对玩家进行提示,若玩家成功围住神经猫则显示玩家所用的步数。
然后是对神经猫这个游戏控制的分析,神经猫可移动的范围是9×9,我设置神经猫的初始位置是固定的,但是系统在游戏一开始生成的路障是随机的,一共是16个路障,之后玩家将根据游戏的情况对神经猫进行堵截,当玩家每选择一个点作为自己想设置的路障时,那个点将改变为橘色,而神经猫将根据可选择的路径自动移动到下一个地点,当神经猫移动到任意一个边缘时,游戏会提示玩家失败,当玩家成功围住神经猫时,游戏会提示玩家成功且会显示出玩家所用的步数。
这个游戏要用到二维数组,把神经猫可以移动的范围进行记录,还必须要对神经猫的移动方式进行设置,还有每个点不同状态的转换,路障的自动生成,还有对玩家所用步数的统计,这个游戏所要用到的主要软件是Eclipse、ADT,它的主要语言是java,操作系统是windows7.
二系统功能设计
项目具体功能描述如下:
1)游戏开始界面:
有比较搞笑的背景图来吸引玩家,然后点击开始游戏,
切换到游戏界面
2)游戏界面:
神经猫一开始在游戏的正中间,平且还有系统随机生成的16
个路障,范围是9×9的空间里,并且把它分成了点,玩家在点上设置好路障后,神经猫会在看选取的路径中随机选取一条,并移动到下一个点,直至游戏结束。
3)游戏结束界面:
当神经猫移动到任意边缘时,会显示通关失败的提示;但玩家成功围住神经猫时,则显示成功通关页面,并且统计了玩家所用的步数。
三项目概要设计
3.1功能模块设计
(1)程序流程图
根据用户需求,本软件程序流程图如下:
成功通关失败
通关再来一次
图1.程序流程图
(2)程序模块设计
为了提高代码的重复利用率,程序设计时自定义了以下几个类:
1 自定义坐标类(Dot):
每一个点都是一个抽象的对象,需要把每一个点抽象为一个类,然后让每一个圆圈继承于这个类。
2 自定义绘制布局类(playground):
继承surfaceview,将制定的绘图呈现在surfaceview上,界面的响应和绘制都在surfaceview上完成的。
3 自定义实现接口(OnTouchListener):
为了界面的点击做出响应。
(3)界面功能详细设计
各界面功能详尽介绍如下:
1)游戏开始界面(图1:
homepage):
打开程序首先显示游戏开始界面,通过点击开始游戏,马上自动跳转到游戏界面图(homepage2)
图1:
homepage
2)游戏界面(图2:
homepage2):
进入到游戏界面以后,就可以正式开始游戏啦玩家开始对神经猫进行围追截堵
图2:
homepage2
3)游戏结束界面(图3:
homepage3、图4:
homepage4):
若玩家成功围住神经猫则显示图3,若失败则显示图4
图3:
homepage3图4:
homepage4
四项目主要代码
系统实现相应功能的主要代码如下:
记录每个场景中的元素它的X,Y坐标点的状态:
packagecom.example.crazycat;
publicclassDot{//记录每个场景中的元素它的X,Y坐标点的状态。
并不会直接参与界面的响应和界面的绘制
privateintx,y;
privateintstatus;//记录这个点的状态
publicstaticfinalintSTATUS_OFF=-1;//代表可走的路径
publicstaticfinalintSTATUS_IN=0;//猫的当前位置
publicstaticfinalintSTATUS_ON=1;//已经设置的路障
//指定x,y的坐标
publicDot(intx,inty){
this.x=x;
this.y=y;
this.status=STATUS_OFF;
}
//指定geter和sette方法
publicintgetX(){
returnx;
}
publicvoidsetX(intx){
this.x=x;
}
publicintgetY(){
returny;
}
publicvoidsetY(inty){
this.y=y;
}
publicintgetStatus(){
returnstatus;
}
publicvoidsetStatus(intstatus){
this.status=status;
}
//同时设置x。
y的方法
publicvoidsetXY(intx,inty){
this.x=x;
this.y=y;
}
}
Playground类的实现:
packagecom.example.crazycat;
importjava.util.HashMap;
importjava.util.Timer;
importjava.util.TimerTask;
importjava.util.Vector;
importandroid.annotation.SuppressLint;
importandroid.app.AlertDialog;
importandroid.app.AlertDialog.Builder;
importandroid.content.Context;
importandroid.content.DialogInterface;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.Paint;
importandroid.graphics.RectF;
importandroid.graphics.drawable.Drawable;
importandroid.view.KeyEvent;
importandroid.view.MotionEvent;
importandroid.view.SurfaceHolder;
importandroid.view.SurfaceHolder.Callback;
importandroid.view.SurfaceView;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.view.View.OnTouchListener;
importandroid.widget.Toast;
publicclassPlayGroundextendsSurfaceViewimplementsOnTouchListener{
//界面的响应和界面的绘制在SurfaceView完成,触摸事件的响应通过OnTouchListener接口实现
//行数
privatestaticfinalintROW=9;
//列数
privatestaticfinalintCOL=9;
//障碍的数量
privatestaticfinalintBOCKS=COL*ROW/5;
//屏幕宽度去
privateintSCREEN_WIDTH;
//每个通道的宽度
privateintWIDTH;
//奇数行和偶数行通道间的位置偏差量
privateintDISTANCE;
//屏幕顶端和通道最顶端间的距离
privateintOFFSET;
//整个通道与屏幕两端间的距离
privateintlength;
//做成神经猫动态图效果的单张图片
privateDrawablecat_drawable;
//背景图
privateDrawablebackground;
//神经猫动态图的索引
privateintindex=0;
privateDot[][]matrix;
privateDotcat;
privateTimertimer=null;
privateTimerTasktimerttask=null;
privateContextcontext;
privateintsteps;
privateint[]images={R.drawable.cat1,R.drawable.cat2,R.drawable.cat3,
R.drawable.cat4,R.drawable.cat5,R.drawable.cat6,R.drawable.cat7,
R.drawable.cat8,R.drawable.cat9,R.drawable.cat10,
R.drawable.cat11,R.drawable.cat12,R.drawable.cat13,
R.drawable.cat14,R.drawable.cat15,R.drawable.cat16};
@SuppressLint("ClickableViewAccessibility")
publicPlayGround(Contextcontext){
super(context);//使用Context创建当前类构造函数
matrix=newDot[ROW][COL];//将行高,列宽传递进去,指定数组大小
cat_drawable=getResources().getDrawable(images[index]);
background=getResources().getDrawable(R.drawable.bg);
this.context=context;
initGame();//调用游戏初始化
getHolder().addCallback(callback);//将Callback对象指定给getholder
setOnTouchListener(this);//设定为自己的触摸监听器
this.setFocusable(true);
this.setFocusableInTouchMode(true);
}
@Override
publicbooleanonKeyDown(intkeyCode,KeyEventevent){
if(keyCode==KeyEvent.KEYCODE_BACK){
stopTimer();
}
returnsuper.onKeyDown(keyCode,event);
}
//初始化游戏:
分别对可走路径位置,猫的位置和路障位置进行初始化
privatevoidinitGame(){
steps=0;
for(inti=0;ifor(intj=0;j
matrix[i][j]=newDot(j,i);/*X,Y坐标值和行列值是相反的。
即通过查找列值获得X坐标,查找行值获得Y坐标*/
}
}
for(inti=0;ifor(intj=0;j
matrix[i][j].setStatus(Dot.STATUS_OFF);
}
}
cat=newDot(COL/2-1,ROW/2-1);//设置猫的起始点
getDot(cat.getX(),cat.getY()).setStatus(Dot.STATUS_IN);//把猫的起始点的状态设置为STATUS_IN,才能记录猫的位置
for(inti=0;iintx=(int)((Math.random()*1000)%COL);
inty=(int)((Math.random()*1000)%ROW);//随机获取1对坐标点
if(getDot(x,y).getStatus()==Dot.STATUS_OFF){//对当前可用路径点进行选择
getDot(x,y).setStatus(Dot.STATUS_ON);//把这个点设置成路障
i++;
}
}
}
//实现界面绘制,在redraw方法中将所有元素以图形化显示出来,也就是将它绘制在Canvas对象上
privatevoidredraw(){
Canvascanvas=getHolder().lockCanvas();//锁定画布
canvas.drawColor(Color.GRAY);//设置颜色为浅灰色
Paintpaint=newPaint();//创建Paint对象
paint.setFlags(Paint.ANTI_ALIAS_FLAG);//开启抗锯齿,优化视频质量
//用两个For循环嵌套将所有的点显示到界面中来
for(inti=0;ifor(intj=0;j
DISTANCE=0;//引入偏移量
if(i%2!
=0){
DISTANCE=(int)WIDTH/2;//对偶数行进行缩进
}
Dotdot=getDot(j,i);//将坐标赋值给内部变量one
switch(dot.getStatus()){//由于每个点对应的三种状态颜色不一样,要用一个switch语句
caseDot.STATUS_IN:
paint.setColor(0XFFEEEEEE);//STATUS_IN状态时设置颜色为浅灰
break;
caseDot.STATUS_ON:
paint.setColor(0XFFFFAA00);//STATUS_ON状态时设置颜色为橙色
break;
caseDot.STATUS_OFF:
paint.setColor(0X74000000);//STATUS_OFF状态时设置颜色为黑色
break;
default:
break;
}
canvas.drawOval(newRectF(dot.getX()*WIDTH+DISTANCE
+length,dot.getY()*WIDTH+OFFSET,(dot.getX()+1)
*WIDTH+DISTANCE+length,(dot.getY()+1)*WIDTH
+OFFSET),paint);
/*在Canvas画布上画椭圆并界定它的上下左右边界宽度且有错位*/
}
}
intleft=0;
inttop=0;
if(cat.getY()%2==0){
left=cat.getX()*WIDTH;
top=cat.getY()*WIDTH;
}else{
left=(int)(WIDTH/2)+cat.getX()*WIDTH;
top=cat.getY()*WIDTH;
}
//此处神经猫图片的位置是根据效果图来调整的
cat_drawable.setBounds(left-WIDTH/6+length,top-WIDTH/2
+OFFSET,left+WIDTH+length,top+WIDTH+OFFSET);
cat_drawable.draw(canvas);
background.setBounds(0,0,SCREEN_WIDTH,OFFSET);
background.draw(canvas);
getHolder().unlockCanvasAndPost(canvas);;//取消Canvas的锁定,把绘图内容更新到界面上
}
//为Surfaceview添加Callback
Callbackcallback=newCallback(){//声明并实例化一个Callback接口
publicvoidsurfaceCreated(SurfaceHolderholder){
redraw();//执行redraw函数,在界面第一次显示时将指定的内容显示到界面上
startTimer();
}
//使用surfaceChanged方法来适配不同的屏幕尺寸
publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,
intheight){
WIDTH=width/(COL+1);
OFFSET=height-WIDTH*ROW-2*WIDTH;
length=WIDTH/3;
SCREEN_WIDTH=width;
}
publicvoidsurfaceDestroyed(SurfaceHolderholder){
stopTimer();
}
};
//开启定时任务
privatevoidstartTimer(){
timer=newTimer();
timerttask=newTimerTask(){
publicvoidrun(){
gifImage();
}
};
timer.schedule(timerttask,50,65);
}
//停止定时任务
publicvoidstopTimer(){
timer.cancel();
timer.purge();
}
//动态图
privatevoidgifImage(){
index++;
if(index>images.length-1){
index=0;
}
cat_drawable=getResources().getDrawable(images[index]);
redraw();
}
//获取通道对象
privateDotgetDot(intx,inty){
returnmatrix[y][x];
}
//判断神经猫是否处于边界
privatebooleaninEdge(Dotdot){
if(dot.getX()*dot.getY()==0||dot.getX()+1==COL
||dot.getY()+1==ROW){
returntrue;//当前点的坐标无论是x或y为0,或x或y值是定义的游戏场景最大值时都处于边界
}
returnfalse;
}
//移动cat至指定点
privatevoidmoveTo(Dotdot){
dot.setStatus(Dot.STATUS_IN);//dot的状态设置为猫所处的点
getDot(cat.getX(),cat.getY()).setStatus(Dot.STATUS_OFF);//将猫当前点的状态复位
cat.setXY(dot.getX(),dot.getY());//将猫移动到新的点
}
//获取one在方向dir上的可移动距离,中心点6个方向距离的判断与获取。
路径结束点为路障用负数表示,为场景边缘用正数表示
privateintgetDistance(Dotone,intdir){
intdistance=0;
if(inEdge(one)){
return1;//如果下一个点已在屏幕边缘,无需再判断
}
Dotori=one;//定义ori和next,ori指定为当前函数传入的one
Dotnext;
while(true){
next=getNeighbour(ori,dir);
if(next.getStatus()==Dot.STATUS_ON){
returndistance*-1;//下一个点为路障的话,直接返回距离0
}
if(inEdge(next)){
distance++;
returndistance;//下一个点为场景边缘时,距离+1并返回
}
distance++;
ori=next;
}
}
//获取dot的相邻点,返回其对象
privateDotgetNeighbour(Dotdot,intdir){//每个点都有6个相邻点
switch(dir){
case1:
returngetDot(dot.getX()-1,dot.getY());//获得中心点左边相邻点
case2:
if(dot
|
|
|