Android贪吃蛇源码分析.docx
- 文档编号:18111590
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:14
- 大小:206.05KB
Android贪吃蛇源码分析.docx
《Android贪吃蛇源码分析.docx》由会员分享,可在线阅读,更多相关《Android贪吃蛇源码分析.docx(14页珍藏版)》请在冰点文库上搜索。
Android贪吃蛇源码分析
Android---snake源代码分析
代码结构分析:
Snake:
主游戏窗口
SnakeView:
游戏视图类,是实现游戏的主体类
TileView:
一个处理图片或其它
Coordinate:
这是一个包括两个参数,用于记录X轴和Y轴简单类,其中包括一个比较函数.
RefshHandler:
用于更新视图
Snake
这个类是游戏的主游戏窗口,是框架容器,
1.游戏的开始:
oncreate此外的亮点是:
setContentView(R.layout.snake_layout);设置窗口的布局文件,这里Android123给大家说明的是,这里的snake_layout使用了自定义资源标签的方式,大家注意学习:
这里我们可以看到来自SnakeView这个派生类的名称,由于Android内部的R.资源不包含SnakeView类,所以我们必须写清楚Package,比如com.exmple.android.snake.SnakeView然后和其他控件使用一样,都是一个id然后宽度、高度、以及自定义的标签tileSize(尾巴长度),如下:
android: id="@+id/snake" android: layout_width="fill_parent" android: layout_height="fill_parent" tileSize="12" /> 2.onPause: 关于这点,大家可以参考下在我blog中关于active生命周期 在玩游戏过程中,如果有来电或是其它事件中断,这时应该把当前状态保存。 以便返回时,还可以继续玩游戏。 这就使用onSaveInstanceState实现保存当前状态。 TileView 注: 此部分解析来自: Android示例程序Snake贪食蛇代码分析(三) TileView,从名称上不难看出这是一个方砖类,就是生成一个方块。 TileView使用了Android平台的显示基类View,View类是直接从java.lang.Object派生出来的,是各种控件比如TextView、EditView的基类,当然包括我们的窗口Activity类,这些在SDK文档中都说的比较清楚。 这里定义了5个int型全局的变量,分别是方砖的数量mTileSize;方砖水平x防线的数量mXTileCount;以及竖直y方向上的方砖数量mYTileCount,下面是一个相对偏移位置mXOffset和mYOffset;这里android123主让要大家了解如何自定义View在Android开发中,在一个View类中主要是重写onSizeChanged方法来控制改变部分,以及onDraw实现画布的修改,实现的简写如下: @Override protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){} @Override publicvoidonDraw(Canvascanvas){super.onDraw(canvas);} 我们自定义的TileView类需要自己添加一个构造方法,根据需要,我们还重载了一种包含样式的方法,这里大家可以多看下Gallery控件的实现,就好理解了,下面是基本框架。 publicTileView(Contextcontext,AttributeSetattrs,intdefStyle){super(context,attrs,defStyle);} publicTileView(Contextcontext,AttributeSetattrs){super(context,attrs);} 在贪食蛇游戏中我们知道Snake是移动的,所以加入了一个清除显示的clearTiles方法,通过一个二维数组保存一个gird网格型的运动轨迹,下一次我们将会讲解android贪食蛇的游戏逻辑和完整的关联拼接实现。 SnakeView 在这个类中实现的游戏的实体,从游戏需求的角色,这个游戏包括了如下方面: 1.随机产生小苹果,apples这里是复数,当然是是大于1个苹果,所以代码中产生了两个苹果。 2.游戏状态管理 3.画蛇,view的更新 4.吃掉苹果后小蛇状态的变化 5.画围墙 如果实现吃掉苹果小蛇速度变快? 关键是: mMoveDelay这个变量,以下是涉及到这个变量的函数, 每次吃掉苹果后,就会updateSnake一下,里面就把时间处理了: mMoveDelay*=0.9; 小蛇其实就是一个数组,google的代码就是好注释写的清楚: /** *mSnakeTrail: alistofCoordinatesthatmakeupthesnake'sbody *mAppleList: thesecretlocationofthejuicyapplesthesnakecraves. */ privateArrayList privateArrayList mSnakeTrail: 一个由Coordinates列表组织的蛇身. mAppleList: 存放鲜美多汁的苹果列表 通过这个数组画出小蛇不难,问题是如何判断游戏是否结束? 问题是如何判断游戏的状态 所有以下的代码来自updateSnake 1.吃了苹果 //Lookforapples intapplecount=mAppleList.size(); for(intappleindex=0;appleindex Coordinatec=mAppleList.get(appleindex); if(c.equals(newHead)){ mAppleList.remove(c); addRandomApple(); mScore++; mMoveDelay*=0.9; growSnake=true; } } 2.碰到了自己 //Lookforcollisionswithitself intsnakelength=mSnakeTrail.size(); for(intsnakeindex=0;snakeindex Coordinatec=mSnakeTrail.get(snakeindex); if(c.equals(newHead)){ setMode(LOSE); return; } } 3.碰到墙了 //Collisiondetection //Fornowwehavea1-squarewallaroundtheentirearena if((newHead.x<1)||(newHead.y<1)||(newHead.x>mXTileCount-2) ||(newHead.y>mYTileCount-2)){ setMode(LOSE); return; } 源代码分析 Snake状态分析: 在snakeView中定义了snake游戏的几种状态: privateintmMode=READY; publicstaticfinalintPAUSE=0;//暂定 publicstaticfinalintREADY=1;//准备好了 publicstaticfinalintRUNNING=2;//正在运行 publicstaticfinalintLOSE=3;//结束,输了游戏 各种游戏状态 rady running paused lose 以上状态是通过: voidsetMode(intnewMode)函数实现。 如何实现画出小方块: 参看: publicclassDrawViewextendsView{ privatefinalintmTileSize=12; privatefinalStringTAG="DEMO"; privatePaintpa=newPaint(); privateBitmapmTileArray; voidloadImage(){ Resourcesr=this.getContext().getResources(); Drawabletile=r.getDrawable(R.drawable.redstar); Bitmapbitmap=Bitmap.createBitmap(mTileSize,mTileSize, Bitmap.Config.ARGB_8888); Canvascanvas=newCanvas(bitmap); tile.setBounds(0,0,mTileSize,mTileSize); tile.draw(canvas); mTileArray=bitmap; } publicDrawView(Contextcontext,AttributeSetattrs,intdefStyle){ super(context,attrs,defStyle); //TODOAuto-generatedconstructorstub loadImage(); x=10; y=10; Log.i(TAG,"DrawView2"); } //如果没有这段代码,大家可以试一下,改用上面的代码,程序能否通过。 publicDrawView(Contextcontext,AttributeSetattrs){ super(context,attrs); //TODOAuto-generatedconstructorstub loadImage(); Log.i(TAG,"DrawView3"); } @Override protectedvoidonDraw(Canvascanvas){ super.onDraw(canvas); Log.i(TAG,"onDraw1"); canvas.drawBitmap(mTileArray,x,y,pa); } } 通过上面的文章可以画出小方块,但注意到SnakeView一共有两构造函数,那个函数才真正起作用呢? ●publicSnakeView(Contextcontext,AttributeSetattrs) ●publicSnakeView(Contextcontext,AttributeSetattrs,intdefStyle) 通过加log的方式,判断是第一个构造函数起作用。 在第一个构造函数上方有一段注释: 通过XML文件构造出SnakeView *ConstructsaSnakeViewbasedoninflationfromXML 如果不使用这个构造函数,将会造成错误,可以试一下,看一下结果是怎样! 本人得到如下的错误提示: 05-2114: 13: 26.079: ERROR/AndroidRuntime(711): Causedby: java.lang.NoSuchMethodException: DrawView 按键处理: publicbooleanonKeyDown(intkeyCode,KeyEventevent){ //TODOAuto-generatedmethodstub if(keyCode==KeyEvent.KEYCODE_DPAD_UP){ Log.i(TAG,"KEYCODE_DPAD_UP"); } returnsuper.onKeyDown(keyCode,event); } 如何让我们的小方块动起来? 实现小方块动起来的秘密在于view的publicvoidinvalidate() 大家可以参看SDK文档中关于View中Drawing中的一小段话 Toforceaviewtodraw,callinvalidate().//为了让view重画,可以调用invalidate函数 方法: 1.在DrawView类中添加两个成员: privateintx,y; 同时实现get,set方法, 2.在构造函数中添加他们的初始值, 3.修改onDraw @Override protectedvoidonDraw(Canvascanvas){ super.onDraw(canvas); Log.i(TAG,"onDraw1"); canvas.drawBitmap(mTileArray,x,y,pa); } 4.修改onKeyDown函数 @Override publicbooleanonKeyDown(intkeyCode,KeyEventevent){ //TODOAuto-generatedmethodstub if(keyCode==KeyEvent.KEYCODE_DPAD_UP){ Log.i(TAG,"KEYCODE_DPAD_UP"); dv.setX(dv.getX()+10); dv.invalidate(); } returnsuper.onKeyDown(keyCode,event); } 最后运行结果如下图: 附: 网络上关于snake分析的三篇文章 上一次我们大概讲解了下AndroidSDK中的演示程序Snake游戏的主框架,今天我看来看下实现的基础类TileView,从名称上不难看出这是一个方砖类,就是生成一个方块。 TileView使用了Android平台的显示基类View,View类是直接从java.lang.Object派生出来的,是各种控件比如TextView、EditView的基类,当然包括我们的窗口Activity类,这些在SDK文档中都说的比较清楚。 这里定义了5个int型全局的变量,分别是方砖的数量mTileSize;方砖水平x防线的数量mXTileCount;以及竖直y方向上的方砖数量mYTileCount,下面是一个相对偏移位置mXOffset和mYOffset;这里android123主让要大家了解如何自定义View在Android开发中,在一个View类中主要是重写onSizeChanged方法来控制改变部分,以及onDraw实现画布的修改,实现的简写如下: @Override protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){} @Override publicvoidonDraw(Canvascanvas){super.onDraw(canvas);} 我们自定义的TileView类需要自己添加一个构造方法,根据需要,我们还重载了一种包含样式的方法,这里大家可以多看下Gallery控件的实现,就好理解了,下面是基本框架。 publicTileView(Contextcontext,AttributeSetattrs,intdefStyle){super(context,attrs,defStyle);} publicTileView(Contextcontext,AttributeSetattrs){super(context,attrs);} 在贪食蛇游戏中我们知道Snake是移动的,所以加入了一个清除显示的clearTiles方法,通过一个二维数组保存一个gird网格型的运动轨迹,下一次我们将会讲解android贪食蛇的游戏逻辑和完整的关联拼接实现。 今天我们分析下最复杂的SnakeView的设计,它是派生于TileView方砖类,TileView构建是基于Android直接的显示类View,如果不明白的可以查看Android示例程序Snake贪食蛇代码分析 (二)一文有关TileView类的实现, 首先我们看到整个游戏分READY、PAUSE 、RUNNING 、LOSE四种mMode状态模式,分别对应准备、暂停、运行中、结束(死亡),毕竟贪食蛇没有胜利这个结果。 整个Snake的运行分4个方向,NORTH、SOUTH 、EAST、WEST分别对应了北、南、东、西四个方向,其中变量mDirection对应当前的方向,而mNextDirection对应下个运行时的位置。 这里星星分3种,使用的是一个Drawable图片,分RED_STAR、YELLOW_STAR和GREEN_STAR三种颜色,游戏的星星出现位置由Random随机数生成器来决定,这里Random一般和Timer系统时钟来随机生成更真实一些,通过一个Handler对象来控制画面的更新,使用了this.update();和this.invalidate();这两个本地方法,Update和invaildate均为android.view.View类的本地方法。 这里资源的使用通过Resourcesr=this.getContext().getResources();获取了r对象的实例,通过r.getDrawable(R.drawable.redstar)获取资源名为redstar的资源,返回的是一个Drawable对象。 对于按键信息,直接重写View类的onKeyDown方法,这里KeyEvent传递的是按键的映射,比如KEYCODE_DPAD_UP向上,KeyEvent.KEYCODE_DPAD_DOWN向下等等,详细的查看SDK中的onKeyDown @Override publicbooleanonKeyDown(intkeyCode,KeyEventmsg){ if(keyCode==KeyEvent.KEYCODE_DPAD_UP){} } 整个游戏的控制流程就是上面这些,对于游戏的逻辑而言比较简单,这个贪食蛇并没有包含3D设计和类似Nokia的能量走廊、6边形轨迹,有空了我们一起来完善一个3D的贪食蛇游戏
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 贪吃 源码 分析