Android实例剖析笔记(五)
这个系列的前四篇文章介绍了Android sdk中自带的NotePad程序,算是开了个头,这篇开始介绍Android sdk中自带的第二个示例程序—Snake(贪食蛇)。本文将主要介绍我对这个示例程序进行的一些修改。
游戏暂停/继续机制
由于原来的代码中在游戏运行时没有提供控制选项(比如暂停/继续),因此除非你死了,否则只能玩到底。我这里对代码进行一些修改,加入一个Option Menu来提供暂停/继续机制。
首先加入一个变量记录游戏当前状态
然后重载onCreateOptionsMenu函数,创建一个控制菜单项,并对其进行处理,提供暂停/继续机制。
*@seeandroid.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*@Author:phinecos
*@Date:2009-08-28
*/
@Override
publicbooleanonOptionsItemSelected(MenuItemitem)
{
switch(item.getItemId())
{
caseMENU_CONTROL:
{
if(mState==SnakeView.PAUSE)
{//此前状态是"停止",则转为"运行"
mState=SnakeView.RUNNING;
mSnakeView.setMode(SnakeView.RUNNING);
item.setIcon(android.R.drawable.ic_media_pause).setTitle(R.string.cmd_pause);
}
elseif(mState==SnakeView.RUNNING)
{//此前状态是"运行",则转为“暂停"
mState=SnakeView.PAUSE;
mSnakeView.setMode(SnakeView.PAUSE);
item.setIcon(android.R.drawable.ic_media_play).setTitle(R.string.cmd_run);
}
elseif(mState==SnakeView.READY)
{//此前是"初始状态",则转为"运行"
mState=SnakeView.RUNNING;
}
returntrue;
}
}
returnsuper.onOptionsItemSelected(item);
}
/*
*@seeandroid.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*@Author:phinecos
*@Date:2009-08-28
*/
@Override
publicbooleanonCreateOptionsMenu(Menumenu)
{
super.onCreateOptionsMenu(menu);
menu.add(0,MENU_CONTROL,0,R.string.cmd_pause).setIcon(android.R.drawable.ic_media_pause);
returntrue;
}
修改后运行截图如下:
当然,这段代码还是有问题的,游戏刚开始时,必须先点击菜单确认,再按上方向键才能开始。(以后再来修改。。。)
穿墙贪食蛇
第二个修改是把这个普通的贪食蛇改成可以穿墙(呵呵,这样就可以不死了。。。)。想必要修改的就是撞墙检测那段代码?没错,就是下面这段!
//Fornowwehavea1-squarewallaroundtheentirearena
if((newHead.x<1)||(newHead.y<1)||(newHead.x>mXTileCount-2)||(newHead.y>mYTileCount-2))
{//撞墙
setMode(LOSE);
return;
}
原来的版本是发现撞墙时就直接判定为失败,我这里做个小小的修改,让它可以穿墙而去:
{
booleangrowSnake=false;
//grabthesnakebythehead
Coordinatehead=mSnakeTrail.get(0);
CoordinatenewHead=newCoordinate(1,1);
mDirection=mNextDirection;
switch(mDirection)
{
caseEAST:
{
newHead=newCoordinate(head.x+1,head.y);
break;
}
caseWEST:
{
newHead=newCoordinate(head.x-1,head.y);
break;
}
caseNORTH:
{
newHead=newCoordinate(head.x,head.y-1);
break;
}
caseSOUTH:
{
newHead=newCoordinate(head.x,head.y+1);
break;
}
}
//穿墙的处理
if(newHead.x==0)
{//穿左边的墙
newHead.x=mXTileCount-2;
}
elseif(newHead.y==0)
{//穿上面的墙
newHead.y=mYTileCount-2;
}
elseif(newHead.x==mXTileCount-1)
{//穿右边的墙
newHead.x=1;
}
elseif(newHead.y==mYTileCount-1)
{//穿下面的墙
newHead.y=1;
}
//判断是否撞到自己
intsnakelength=mSnakeTrail.size();
for(intsnakeindex=0;snakeindex<snakelength;snakeindex++)
{
Coordinatec=mSnakeTrail.get(snakeindex);
if(c.equals(newHead))
{
setMode(LOSE);
return;
}
}
//判断是否吃掉“苹果”
intapplecount=mAppleList.size();
for(intappleindex=0;appleindex<applecount;appleindex++)
{
Coordinatec=mAppleList.get(appleindex);
if(c.equals(newHead))
{
mAppleList.remove(c);
addRandomApple();
mScore++;
mMoveDelay*=0.9;
growSnake=true;
}
}
//pushanewheadontotheArrayListandpulloffthetail
mSnakeTrail.add(0,newHead);
//exceptifwewantthesnaketogrow
if(!growSnake)
{
mSnakeTrail.remove(mSnakeTrail.size()-1);
}
intindex=0;
for(Coordinatec:mSnakeTrail)
{
if(index==0)
{
setTile(YELLOW_STAR,c.x,c.y);
}
else
{
setTile(RED_STAR,c.x,c.y);
}
index++;
}
}
其实修改后的代码非常简单,就是把新节点的值做些处理,让它移动到对应的行/列的头部或尾部即可。
下面就是修改后的“穿墙”贪食蛇的运行截图:
全屏机制
游戏一般都是全屏的,原始代码也考虑到标题栏太过难看了,于是使用下面这句代码就去掉了标题栏:
可还是没有达到全屏的效果,在Android1.5中实现全屏效果非常简单,只需要一句代码即可实现:
运行效果如下图所示:
接下来的修改目标是加入得分排行榜机制,再加入一个启动画面和选择菜单。当然,这一篇文章水了点,仅仅记录了自己做的一些小实验,并没有涉及到Snake的代码分析,不过请继续期待下一篇文章。。。
作者:phinecos(洞庭散人)
出处:http://phinecos.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,并在文章页面明显位置给出原文连接