Android ---snake 源代码分析
前言:
snake代码分析将分成几个部分,先从snake中几个关键技术点分析起,之后是源代码结构性的分析,snake的结构将会以uml图的方式分析。最后我会把东西整成一份word文档。今天先把源代码分析弄上来。完整分析在附件中。
/**
* 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, though,
* because when you catch one, not only will you become longer, but you'll move
* faster. Running into yourself or the walls will end the game.
*
*/
翻译:
这个一个每个人都喜欢的简单的小游戏
Snake 是游戏的实现类,通过控制小蛇在花园中游走寻找苹果,注意,每吃掉一个苹果,小蛇身体不但会变的更长,还会移动的更敏捷,一旦撞上四周的墙或是碰到自己就会结束这次游戏。
代码结构分析:
Snake : 主游戏窗口
SnakeView : 游戏视图类,是实现游戏的主体类
TileView : 一个处理图片或其它
Coordinate :这是一个包括两个参数,用于记录 X 轴和 Y 轴简单类,其中包括一个比较函数 .
RefshHandler :用于更新视图
源代码分析
Snake 状态分析:
在 snakeView 中定义了 snake 游戏的几种状态:
private int mMode = READY ;
public static final int PAUSE = 0; // 暂定
public static final int READY = 1; // 准备好了
public static final int RUNNING = 2; // 正在运行
public static final int LOSE = 3; // 结束 , 输了游戏
各种游戏状态
以上状态是通过: void setMode(int newMode) 函数实现。
如何实现画出小方块:
参看: http://yuefeng.iteye.com/blog/206706
public class DrawView extends View {
private final int mTileSize = 12;
private final String TAG = "DEMO" ;
private Paint pa = new Paint();
private Bitmap mTileArray ;
void loadImage(){
Resources r = this .getContext().getResources();
Drawable tile = r.getDrawable(R.drawable. redstar );
Bitmap bitmap = Bitmap.createBitmap ( mTileSize , mTileSize ,
Bitmap.Config. ARGB_8888 );
Canvas canvas = new Canvas(bitmap);
tile.setBounds(0, 0, mTileSize , mTileSize );
tile.draw(canvas);
mTileArray = bitmap;
}
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super (context, attrs, defStyle);
// TODO Auto-generated constructor stub
loadImage();
x = 10;
y = 10;
Log.i ( TAG , "DrawView 2" );
}
// 如果没有这段代码,大家可以试一下,改用上面的代码,程序能否通过。
public DrawView(Context context, AttributeSet attrs) {
super (context, attrs);
// TODO Auto-generated constructor stub
loadImage();
Log.i ( TAG , "DrawView 3" );
}
@Override
protected void onDraw(Canvas canvas) {
super .onDraw(canvas);
Log.i ( TAG , "onDraw 1" );
canvas.drawBitmap( mTileArray , x , y , pa );
}
}
通过上面的文章可以画出小方块,但注意到 SnakeView 一共有两构造函数,那个函数才真正起作用呢?
public SnakeView(Context context, AttributeSet attrs)
public SnakeView(Context context, AttributeSet attrs, int defStyle)
通过加 log 的方式,判断是第一个构造函数起作用。
在第一个构造函数上方有一段注释:通过 XML 文件构造出 SnakeView
* Constructs a SnakeView based on inflation from XML
如果不使用这个构造函数,将会造成错误,可以试一下,看一下结果是怎样!本人得到如下的错误提示:
05-21 14:13:26.079: ERROR/AndroidRuntime(711): Caused by: java.lang.NoSuchMethodException: DrawView
<!--
按键处理:
public boolean onKeyDown( int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent. KEYCODE_DPAD_UP ) {
Log.i ( TAG , "KEYCODE_DPAD_UP" );
}
return super .onKeyDown(keyCode, event);
}
如何让我们的小方块动起来?
实现小方块动起来的秘密在于 view 的 public void invalidate ()
大家可以参看 SDK 文档中关于 View 中 Drawing 中的一小段话
To force a view to draw, call invalidate() .// 为了让 view 重画,可以调用 invalidate 函数
方法:
在 DrawView 类中添加两个成员:
private int x , y ;
同时实现 get,set 方法,
在构造函数中添加他们的初始值,
修改 onDraw
@Override
protected void onDraw(Canvas canvas) {
super .onDraw(canvas);
Log.i ( TAG , "onDraw 1" );
canvas.drawBitmap( mTileArray , x , y , pa );
}
4 .修改 onKeyDown 函数
@Override
public boolean onKeyDown( int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent. KEYCODE_DPAD_UP ) {
Log.i ( TAG , "KEYCODE_DPAD_UP" );
dv .setX( dv .getX()+10);
dv .invalidate();
}
return super .onKeyDown(keyCode, event);
}
最后运行结果如下图:
我把第一阶段的代码放在hello.rar文中,由于是对snake游戏的试验性的分析,就在原来的hello工程中改写,下次会弄一个干净的工程。我尽量把分析的事例代码写的简单,所以只做加up事件,大家可以自行完善。