1、Snake游戏分析排版Snake游戏分析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”创建自己的应用 Snak
2、eAndroid,如下图: 运行效果如下图: 二、工程结构和类图 其实 Snake的工程蛮简单的,源文件就三个: Snake.java SnakeView.java TileView.java。 Snake类是这个游戏的入口点, TitleView类进行游戏的绘画, SnakeView类则是对游戏控制操作的处理。 Coordinate, RefreshHandler是 2个辅助类,也是 SnakeView类中的内部类。其中, Coordinate是一个点的坐标( x, y), RefreshHandler将 RefreshHandler对象绑定某个线程并给它发送消息。如下图: 任何游戏都需要有
3、个引擎来推动游戏的运行,最简化的游戏引擎就是:在一个线程中 While循环,检测用户操作,对用户的操作作出反应,更新游戏的界面,直到用户退出游戏。 在 Snake这个游戏中,辅助类 RefreshHandler继承自 Handler,用来把 RefreshHandler与当前线程进行绑定,从而可以直接给线程发送消息并处理消息。注意一点: Handle对消息的处理都是异步。 RefreshHandler在 Handler的基础上增加 sleep()接口,用来每隔一个时间段后给当前线程发送一个消息。 handleMessage()方法在接受消息后,根据当前的游戏状态重绘界面,运行机制如下: 运行机
4、制 这比较类似定时器的概念,在特定的时刻发送消息,根据消息处理相应的事件。 update()与 sleep()间接的相互调用就构成了一个循环。这里要注意: mRedrawHandle绑定的是 Avtivity所在的线程,也就是程序的主线程;另外由于 sleep()是个异步函数,所以 update()与 sleep()之间的相互调用才没有构成死循环。 最后分析下游戏数据的保存机制,如下: 这里考虑了 Activity的生命周期:如果用户在游戏期间离开游戏界面,游戏暂停;或者由于内存比较紧张, Android关闭游戏释放内存,那么当用户返回游戏界面的时候恢复到上次离开时的界面。 三、源码解析 详细
5、解析下源代码,由于代码量不大,以注释的方式列出如下: 1、 Snake.java Java代码 /* *Title:Snake *Copyright:(C)2007TheAndroidOpenSourceProject.LicensedundertheApacheLicense,Version2.0(theLicense) *authorGavin标注 */ packagecom.deaboway.snake; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.TextView; /* *Snak
6、e:asimplegamethateveryonecanenjoy. * *ThisisanimplementationoftheclassicGameSnake,inwhichyoucontrola *serpentroamingaroundthegardenlookingforapples.Becareful,though, *becausewhenyoucatchone,notonlywillyoubecomelonger,butyoullmove *faster.Runningintoyourselforthewallswillendthegame. * */ /贪吃蛇:经典游戏,在一
7、个花园中找苹果吃,吃了苹果会变长,速度变快。碰到自己和墙就挂掉。 publicclassSnakeextendsActivity privateSnakeViewmSnakeView; privatestaticStringICICLE_KEY=snake-view; /* *CalledwhenActivityisfirstcreated.Turnsoffthetitlebar,setsup *thecontentviews,andfiresuptheSnakeView. * */ /在activity第一次创建时被调用 Override publicvoidonCreate(Bundles
8、avedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.snake_layout); mSnakeView=(SnakeView)findViewById(R.id.snake); mSnakeView.setTextView(TextView)findViewById(R.id.text); /检查存贮状态以确定是重新开始还是恢复状态 if(savedInstanceState=null) /存储状态为空,说明刚启动可以切换到准备状态 mSnakeView.setMode(SnakeView
9、.READY); else /已经保存过,那么就去恢复原有状态 Bundlemap=savedInstanceState.getBundle(ICICLE_KEY); if(map!=null) /恢复状态 mSnakeView.restoreState(map); else /设置状态为暂停 mSnakeView.setMode(SnakeView.PAUSE); /暂停事件被触发时 Override protectedvoidonPause() super.onPause(); /Pausethegamealongwiththeactivity mSnakeView.setMode(Sna
10、keView.PAUSE); /状态保存 Override publicvoidonSaveInstanceState(BundleoutState) /存储游戏状态到View里 outState.putBundle(ICICLE_KEY,mSnakeView.saveState(); /* Title: Snake Copyright: (C) 2007 The Android Open Source Project. Licensed under the Apache License, Version 2.0 (the License) author Gavin 标注 */ package
11、 com.deaboway.snake; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; /* Snake: a simple game that everyone can enjoy. * This is an implementation of the classic Game Snake, in which you control a serpent roaming around the garden looking for apples. Be careful,
12、 though, because when you catch one, not only will you become longer, but youll move faster. Running into yourself or the walls will end the game. * */ / 贪吃蛇: 经典游戏,在一个花园中找苹果吃,吃了苹果会变长,速度变快。碰到自己和墙就挂掉。 public class Snake extends Activity private SnakeView mSnakeView; private static String ICICLE_KEY =
13、snake-view; /* Called when Activity is first created. Turns off the title bar, sets up the content views, and fires up the SnakeView. * */ / 在 activity 第一次创建时被调用 Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.snake_layout); mSnake
14、View = (SnakeView) findViewById(R.id.snake); mSnakeView.setTextView(TextView) findViewById(R.id.text); / 检查存贮状态以确定是重新开始还是恢复状态 if (savedInstanceState = null) / 存储状态为空,说明刚启动可以切换到准备状态 mSnakeView.setMode(SnakeView.READY); else / 已经保存过,那么就去恢复原有状态 Bundle map = savedInstanceState.getBundle(ICICLE_KEY); if
15、(map != null) / 恢复状态 mSnakeView.restoreState(map); else / 设置状态为暂停 mSnakeView.setMode(SnakeView.PAUSE); / 暂停事件被触发时 Override protected void onPause() super.onPause(); / Pause the game along with the activity mSnakeView.setMode(SnakeView.PAUSE); / 状态保存 Override public void onSaveInstanceState(Bundle ou
16、tState) / 存储游戏状态到View里 outState.putBundle(ICICLE_KEY, mSnakeView.saveState(); 2、 SnakeView.java Java代码 /* *Title:Snake *Copyright:(C)2007TheAndroidOpenSourceProject.LicensedundertheApacheLicense,Version2.0(theLicense) *authorGavin标注 */packagecom.deaboway.snake; importjava.util.ArrayList; importjava.
17、util.Random; importandroid.content.Context; importandroid.content.res.Resources; importandroid.os.Handler; importandroid.os.Message; importandroid.util.AttributeSet; importandroid.os.Bundle; importandroid.util.Log; importandroid.view.KeyEvent; importandroid.view.View; importandroid.widget.TextView;
18、/* *SnakeView:implementationofasimplegameofSnake * * */publicclassSnakeViewextendsTileView privatestaticfinalStringTAG=Deaboway; /* *Currentmodeofapplication:READYtorun,RUNNING,oryouhavealready *lost.staticfinalintsareusedinsteadofanenumforperformance *reasons. */游戏状态,默认值是准备状态 privateintmMode=READY;
19、 /游戏的四个状态暂停准备运行和失败 publicstaticfinalintPAUSE=0; publicstaticfinalintREADY=1; publicstaticfinalintRUNNING=2; publicstaticfinalintLOSE=3; /游戏中蛇的前进方向,默认值北方 privateintmDirection=NORTH; /下一步的移动方向,默认值北方 privateintmNextDirection=NORTH; /游戏方向设定北南东西 privatestaticfinalintNORTH=1; privatestaticfinalintSOUTH=2;
20、 privatestaticfinalintEAST=3; privatestaticfinalintWEST=4; /* *LabelsforthedrawablesthatwillbeloadedintotheTileViewclass */三种游戏元 privatestaticfinalintRED_STAR=1; privatestaticfinalintYELLOW_STAR=2; privatestaticfinalintGREEN_STAR=3; /* *mScore:usedtotrackthenumberofapplescapturedmMoveDelay:numberof
21、*millisecondsbetweensnakemovements.Thiswilldecreaseasapplesare *captured. */游戏得分 privatelongmScore=0; /移动延迟 privatelongmMoveDelay=600; /* *mLastMove:trackstheabsolutetimewhenthesnakelastmoved,andis *usedtodetermineifamoveshouldbemadebasedonmMoveDelay. */最后一次移动时的毫秒时刻 privatelongmLastMove; /* *mStatus
22、Text:textshowstotheuserinsomerunstates */显示游戏状态的文本组件 privateTextViewmStatusText; /* *mSnakeTrail:alistofCoordinatesthatmakeupthesnakesbody *mAppleList:thesecretlocationofthejuicyapplesthesnakecraves. */蛇身数组(数组以坐标对象为元素) privateArrayListmSnakeTrail=newArrayList(); /苹果数组(数组以坐标对象为元素) privateArrayListmAp
23、pleList=newArrayList(); /* *Everyoneneedsalittlerandomnessintheirlife */随机数 privatestaticfinalRandomRNG=newRandom(); /* *Createasimplehandlerthatwecanusetocauseanimationtohappen.We *setourselvesasatargetandwecanusethesleep()functiontocausean *update/invalidatetooccuratalaterdate. */创建一个RefreshHandle
24、r来产生动画:通过sleep()来实现 privateRefreshHandlermRedrawHandler=newRefreshHandler(); /一个Handler classRefreshHandlerextendsHandler /处理消息队列 OverridepublicvoidhandleMessage(Messagemsg) /更新View对象 SnakeView.this.update(); /强制重绘 SnakeView.this.invalidate(); /延迟发送消息 publicvoidsleep(longdelayMillis) this.removeMessages(0); sendMessageDelayed(obtainMessage(0),delayMillis); ; /* *ConstructsaSnakeViewbasedoninflationfromXML
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1