贪吃蛇游戏分析.docx

上传人:b****4 文档编号:4011808 上传时间:2023-05-06 格式:DOCX 页数:23 大小:29.36KB
下载 相关 举报
贪吃蛇游戏分析.docx_第1页
第1页 / 共23页
贪吃蛇游戏分析.docx_第2页
第2页 / 共23页
贪吃蛇游戏分析.docx_第3页
第3页 / 共23页
贪吃蛇游戏分析.docx_第4页
第4页 / 共23页
贪吃蛇游戏分析.docx_第5页
第5页 / 共23页
贪吃蛇游戏分析.docx_第6页
第6页 / 共23页
贪吃蛇游戏分析.docx_第7页
第7页 / 共23页
贪吃蛇游戏分析.docx_第8页
第8页 / 共23页
贪吃蛇游戏分析.docx_第9页
第9页 / 共23页
贪吃蛇游戏分析.docx_第10页
第10页 / 共23页
贪吃蛇游戏分析.docx_第11页
第11页 / 共23页
贪吃蛇游戏分析.docx_第12页
第12页 / 共23页
贪吃蛇游戏分析.docx_第13页
第13页 / 共23页
贪吃蛇游戏分析.docx_第14页
第14页 / 共23页
贪吃蛇游戏分析.docx_第15页
第15页 / 共23页
贪吃蛇游戏分析.docx_第16页
第16页 / 共23页
贪吃蛇游戏分析.docx_第17页
第17页 / 共23页
贪吃蛇游戏分析.docx_第18页
第18页 / 共23页
贪吃蛇游戏分析.docx_第19页
第19页 / 共23页
贪吃蛇游戏分析.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

贪吃蛇游戏分析.docx

《贪吃蛇游戏分析.docx》由会员分享,可在线阅读,更多相关《贪吃蛇游戏分析.docx(23页珍藏版)》请在冰点文库上搜索。

贪吃蛇游戏分析.docx

贪吃蛇游戏分析

第6章Android游戏入门

(一)

第一部分本次上机任务

贪吃蛇游戏实现

第二部分任务实现

贪吃蛇游戏是一款经典的老游戏,很多游戏教程都会用该游戏作为游戏入门的示例。

今天我们也采取该游戏作为游戏入门示例。

在理论课上已经对于如何使用View组件进行游戏开发有了初步了解,下面通过View组件实现完成的贪吃蛇游戏。

掌握要点:

掌握将View组件作为游戏开发组件的基本流程

掌握当手机屏幕发生改变时数据的保存

任务说明:

1、游戏的基本流程。

游戏加载时界面如图:

当点击模拟器上的向上的方向键,开始游戏,界面如下:

此时点击上下左右方向键,可以控制“蛇”按照特定的方式移动,每吃一个食物,蛇身会长一格,同时在背景内会再次提供一个新的食物,当蛇头碰到“墙壁”时,游戏结束。

2、游戏的场景实现

通过上面的截图可以看出,整个游戏的场景有红黄绿三种颜色的小图片构成,故在此编写TileView,该类作为整个场景的基础类,代码如下:

publicclassTileViewextendsView{

privatestaticfinalStringTAG="TileView";

//每个方格的大小

protectedstaticintmTileSize;

//横向的方格数

protectedstaticintmXTileCount;

//纵向的方格数

protectedstaticintmYTileCount;

//xy坐标系的偏移量

privatestaticintmXOffset;

privatestaticintmYOffset;

//图片

privateBitmap[]mTitleArray;

//二维方格地图

privateint[][]mTileGrid;

//画笔

privatefinalPaintmPaint=newPaint();

publicTileView(Contextcontext,AttributeSetattrs,intdefStyle){

super(context,attrs,defStyle);

//TODOAuto-generatedconstructorstub

TypedArraya=context.obtainStyledAttributes(attrs,R.styleable.TileView);

mTileSize=a.getInteger(R.styleable.TileView_tileSize,12);

Log.v(TAG,String.valueOf(mTileSize));

a.recycle();

}

//实际调用的是该构造方法

publicTileView(Contextcontext,AttributeSetattrs){

super(context,attrs);

TypedArraya=context.obtainStyledAttributes(attrs,R.styleable.TileView);

mTileSize=a.getInt(R.styleable.TileView_tileSize,12);

a.recycle();

}

//设置图片数组的大小

publicvoidresetTiles(inttilecount){

mTitleArray=newBitmap[tilecount];

Log.v(TAG,String.valueOf(mTitleArray.length));

}

//在游戏还未正式开始前,

//首先要做一些初始化工作,

//在View第一次加载时会首先调用onSizeChanged,

//这里就是做这些事的最好时机

@Override

protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){

//TODOAuto-generatedmethodstub

super.onSizeChanged(w,h,oldw,oldh);Log.v(TAG,"w"+String.valueOf(w)+"h"+String.valueOf(h)+"oldw"+String.valueOf(oldw)+"oldh"+String.valueOf(oldh));

Log.v(TAG,String.valueOf(mTileSize));

mXTileCount=(int)Math.floor(w/mTileSize);

Log.v(TAG,"mXTileCount"+String.valueOf(mXTileCount));

mYTileCount=(int)Math.floor(h/mTileSize);

Log.v(TAG,"mYTileCount"+String.valueOf(mYTileCount));

mXOffset=((w-(mTileSize*mXTileCount))/2);

mYOffset=((h-(mTileSize*mYTileCount))/2);

Log.v(TAG,"mXOffset"+String.valueOf(mXOffset));

Log.v(TAG,"mYOffset"+String.valueOf(mYOffset));

mTileGrid=newint[mXTileCount][mYTileCount];

clearTiles();

}

//加载图片

publicvoidloadTile(intkey,Drawabletile){

Bitmapbitmap=Bitmap.createBitmap(mTileSize,mTileSize,Bitmap.Config.ARGB_8888);

Canvascanvas=newCanvas(bitmap);

tile.setBounds(0,0,mTileSize,mTileSize);

tile.draw(canvas);

mTitleArray[key]=bitmap;

}

publicvoidclearTiles(){

Log.v(TAG,"clearTiles");

for(intx=0;x

for(inty=0;y

setTile(0,x,y);

}

}

}

publicvoidsetTile(inttileindex,intx,inty){

mTileGrid[x][y]=tileindex;

}

//第一次调用完onSizeChanged后,会紧跟着第一次来调用onDraw来绘制View自身

//当然,此时由于所有方格的状态都是0,所以它在屏幕上等于什么也不会去绘制。

@Override

protectedvoidonDraw(Canvascanvas){

//TODOAuto-generatedmethodstub

Log.v(TAG,"onDrawiscalled");

super.onDraw(canvas);

for(intx=0;x

for(inty=0;y

if(mTileGrid[x][y]>0){

canvas.drawBitmap(mTitleArray[mTileGrid[x][y]],mXOffset+x*mTileSize,mYOffset+y*mTileSize,mPaint);

}

}

}

}

}

在该类中loadTile()方法进行图片的加载,resetTiles()方法设置图片数组的大小,onSizeChanged()方法进行游戏开始前相关元素初始化工作,onDraw()方法在onSizeChanged()方法调用后被调用,完成图形的绘制工作。

3、游戏主类SnakeView的实现。

该类继承TileView,在该类中完成游戏图形渲染以及游戏碰撞检测等主要功能。

首先在该类中进行状态设置常量代码编写:

publicclassSnakeViewextendsTileView{

privatestaticfinalStringTAG="SnakeView";

//游戏状态

publicstaticfinalintPAUSE=0;

publicstaticfinalintREADY=1;

publicstaticfinalintRUNNING=2;

publicstaticfinalintLOSE=3;

privateintmMode=READY;

//“蛇”运动方向

privatestaticfinalintNORTH=1;

privatestaticfinalintSOUTH=2;

privatestaticfinalintEAST=3;

privatestaticfinalintWEST=4;

privateintmDirection=NORTH;

privateintmNextDirection=NORTH;

//不同颜色图片

privatestaticfinalintRED_STAR=1;

privatestaticfinalintYELLOW_STAR=2;

privatestaticfinalintGREEN_STAR=3;

//分数

privatelongmScore=0;

//延迟时间

privatelongmMoveDelay=600;

//最后移动的位置

privatelongmLastMove;

……

}

第二步,编写initSnakeView()方法,负责游戏开始时初始化游戏场景。

代码如下:

privatevoidinitSnakeView(){

setFocusable(true);

Resourcesr=this.getContext().getResources();

resetTiles(4);

loadTile(RED_STAR,r.getDrawable(R.drawable.redstar));

loadTile(YELLOW_STAR,r.getDrawable(R.drawable.yellowstar));

loadTile(GREEN_STAR,r.getDrawable(R.drawable.greenstar));

}

第三步编写内部类Coordinate,该类主要的功用是负责图片移动坐标的维护。

代码如下:

privateclassCoordinate{

publicintx;

publicinty;

publicCoordinate(intnewX,intnewY){

x=newX;

y=newY;

}

publicbooleanequals(Coordinateother){

if(x==other.x&&y==other.y){

returntrue;

}

returnfalse;

}

@Override

publicStringtoString(){

//TODOAuto-generatedmethodstub

return"Coordinate:

["+x+","+y+"]";

}

}

第四步编写内部Handler负责UI的更新。

代码如下:

classRefreshHandlerextendsHandler{

@Override

publicvoidhandleMessage(Messagemsg){

//TODOAuto-generatedmethodstub

Log.v(TAG,"refreshHandleriscalled!

!

");

super.handleMessage(msg);

SnakeView.this.update();

SnakeView.this.invalidate();

}

//时间越来越短,刷新越来越快。

publicvoidsleep(longdelayMillis){

this.removeMessages(0);

Log.v(TAG,"handlersleepiscalled"+delayMillis);

sendMessageDelayed(obtainMessage(0),delayMillis);

}

}

第五步构建添加食物方法,代码如下:

privatevoidaddRandomApple(){

//Log.v(TAG,"addRandomAppleiscalled");

CoordinatenewCoord=null;

booleanfound=false;

while(!

found){

intnewX=1+RNG.nextInt(mXTileCount-2);

intnewY=1+RNG.nextInt(mYTileCount-2);

newCoord=newCoordinate(newX,newY);

booleancollision=false;

intsnakelength=mSnakeTrail.size();

for(intindex=0;index

if(mSnakeTrail.get(index).equals(newCoord)){

collision=true;

}

}

found=!

collision;

}

if(newCoord==null){

Log.e(TAG,"SomehowendedupwithanullnewCoord!

");

}

mAppleList.add(newCoord);

}

当表示蛇的集合存在当前食物的坐标,表示发生了碰撞了。

代码如下:

classRefreshHandlerextendsHandler{

@Override

publicvoidhandleMessage(Messagemsg){

//TODOAuto-generatedmethodstub

Log.v(TAG,"refreshHandleriscalled!

!

");

super.handleMessage(msg);

SnakeView.this.update();

SnakeView.this.invalidate();

}

//时间越来越短,刷新越来越快。

publicvoidsleep(longdelayMillis){

this.removeMessages(0);

Log.v(TAG,"handlersleepiscalled"+delayMillis);

sendMessageDelayed(obtainMessage(0),delayMillis);

}

}

第七步编写initNewGame方法,程序第一次加载显示的游戏场景。

代码如下:

privatevoidinitNewGame(){

mSnakeTrail.clear();

mAppleList.clear();

mSnakeTrail.add(newCoordinate(7,7));

mSnakeTrail.add(newCoordinate(6,7));

mSnakeTrail.add(newCoordinate(5,7));

mSnakeTrail.add(newCoordinate(4,7));

mSnakeTrail.add(newCoordinate(3,7));

mSnakeTrail.add(newCoordinate(2,7));

mNextDirection=NORTH;

//Twoapplestostartwith

addRandomApple();

addRandomApple();

mMoveDelay=600;

mScore=0;

}

该方法清空“蛇”的图片和食物图片,而后六章图片组成一个初始的蛇,而且蛇最开始向北移动,而后随机的添加两个食物。

第八步编写oordArrayListToArray和coordArrayToArrayList将数组和集合中进行转换的方法。

代码如下:

privateArrayListcoordArrayToArrayList(int[]rawArray){

Log.v(TAG,"coordArrayToArrayListiscalled!

");

ArrayListcoordArrayList=newArrayList();

intcoordCount=rawArray.length;

for(intindex=0;index

Coordinatec=newCoordinate(rawArray[index],rawArray[index+1]);

coordArrayList.add(c);

}

returncoordArrayList;

}

privateint[]coordArrayListToArray(ArrayListcvec){

Log.v(TAG,"coordArrayListToArray!

");

intcount=cvec.size();

int[]rawArray=newint[count*2];

for(intindex=0;index

Coordinatec=cvec.get(index);

rawArray[2*index]=c.x;

rawArray[2*index+1]=c.y;

}

returnrawArray;

}

通过这两个方法将整型数组和集合框架进行方便的转换。

第九步编写食物被吃掉后,更新食物方法。

代码如下:

privatevoidupdateApples(){

for(Coordinatec:

mAppleList){

setTile(YELLOW_STAR,c.x,c.y);

}

}

第十步编写更新外围“墙”的方法,代码如下:

privatevoidupdateWalls(){

for(intx=0;x

setTile(GREEN_STAR,x,0);

setTile(GREEN_STAR,x,mYTileCount-1);

}

for(inty=1;y

setTile(GREEN_STAR,0,y);

setTile(GREEN_STAR,mXTileCount-1,y);

}

}

从上述代码中可以看出墙四面铺满了绿色的图片。

第十一步编写更新蛇的方法,代码如下:

privatevoidupdateSnake(){

//TODOAuto-generatedmethodstub

//Log.v(TAG,"---------------updateSnakeiscalled!

!

");

booleangrowSnake=false;

//grabthesnakebythehead

Coordinatehead=mSnakeTrail.get(0);

CoordinatenewHead=newCoordinate(1,1);

mDirection=mNextDirection;

Log.v(TAG,"updateSnakemDirection="+mDirection);

//判断用户输入的方向

//右横坐标加1

switch(mDirection){

caseEAST:

{

newHead=newCoordinate(head.x+1,head.y);

break;}

//左横坐标减1

caseWEST:

{

newHead=newCoordinate(head.x-1,head.y);

break;}

//上纵坐标加1

caseNORTH:

{

newHead=newCoordinate(head.x,head.y-1);

break;}

//下纵坐标-1

caseSOUTH:

{

newHead=newCoordinate(head.x,head.y+1);

break;}

}

//检测碰撞

if((newHead.x<1)||(newHead.y<1)||(newHead.x>mXTileCount-2)||(newHead.y>mYTileCount-2)){

setMode(LOSE);

return;

}

intsnakelength=mSnakeTrail.size();

//自己碰到自己

for(intsnakeindex=0;snakeindex

Coordinatec=mSnakeTrail.get(snakeindex);

if(c.equals(newHead)){

setMode(LOSE);

return;

}

}

intapplecount=mAppleList.size();

//当吃到苹果后的处理,移除一个添加一个,同时分数加1,速度加快。

for(intappleindex=0;appleindex

Coordinatec=mAppleLis

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2