Android实例剖析笔记(五)

这个系列的前四篇文章介绍了Android sdk中自带的NotePad程序,算是开了个头,这篇开始介绍Android sdk中自带的第二个示例程序—Snake(贪食蛇)。本文将主要介绍我对这个示例程序进行的一些修改。

游戏暂停/继续机制

由于原来的代码中在游戏运行时没有提供控制选项(比如暂停/继续),因此除非你死了,否则只能玩到底。我这里对代码进行一些修改,加入一个Option Menu来提供暂停/继续机制。

首先加入一个变量记录游戏当前状态

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> private int mState = SnakeView.READY;

然后重载onCreateOptionsMenu函数,创建一个控制菜单项,并对其进行处理,提供暂停/继续机制。

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> /*
*@seeandroid.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*@Author:phinecos
*@Date:2009-08-28
*/
@Override
public boolean onOptionsItemSelected(MenuItemitem)
{
switch (item.getItemId())
{
case MENU_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);
}
else if (mState == SnakeView.RUNNING)
{
// 此前状态是"运行",则转为“暂停"
mState = SnakeView.PAUSE;
mSnakeView.setMode(SnakeView.PAUSE);
item.setIcon(android.R.drawable.ic_media_play).setTitle(R.string.cmd_run);
}
else if (mState == SnakeView.READY)
{
// 此前是"初始状态",则转为"运行"
mState = SnakeView.RUNNING;
}
return true ;
}
}
return super .onOptionsItemSelected(item);
}
/*
*@seeandroid.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*@Author:phinecos
*@Date:2009-08-28
*/
@Override
public boolean onCreateOptionsMenu(Menumenu)
{
super .onCreateOptionsMenu(menu);
menu.add(
0 ,MENU_CONTROL, 0 ,R.string.cmd_pause).setIcon(android.R.drawable.ic_media_pause);
return true ;
}

修改后运行截图如下:




当然,这段代码还是有问题的,游戏刚开始时,必须先点击菜单确认,再按上方向键才能开始。(以后再来修改。。。)

穿墙贪食蛇

第二个修改是把这个普通的贪食蛇改成可以穿墙(呵呵,这样就可以不死了。。。)。想必要修改的就是撞墙检测那段代码?没错,就是下面这段!

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> // Collisiondetection
// Fornowwehavea1-squarewallaroundtheentirearena
if ((newHead.x < 1 ) || (newHead.y < 1 ) || (newHead.x > mXTileCount - 2 ) || (newHead.y > mYTileCount - 2 ))
{
// 撞墙
setMode(LOSE);
return ;
}

原来的版本是发现撞墙时就直接判定为失败,我这里做个小小的修改,让它可以穿墙而去:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> private void updateSnake()
{
boolean growSnake = false ;

// grabthesnakebythehead
Coordinatehead = mSnakeTrail.get( 0 );
CoordinatenewHead
= new Coordinate( 1 , 1 );

mDirection
= mNextDirection;

switch (mDirection)
{
case EAST:
{
newHead
= new Coordinate(head.x + 1 ,head.y);
break ;
}
case WEST:
{
newHead
= new Coordinate(head.x - 1 ,head.y);
break ;
}
case NORTH:
{
newHead
= new Coordinate(head.x,head.y - 1 );
break ;
}
case SOUTH:
{
newHead
= new Coordinate(head.x,head.y + 1 );
break ;
}
}

// 穿墙的处理
if (newHead.x == 0 )
{
// 穿左边的墙
newHead.x = mXTileCount - 2 ;
}
else if (newHead.y == 0 )
{
// 穿上面的墙
newHead.y = mYTileCount - 2 ;
}
else if (newHead.x == mXTileCount - 1 )
{
// 穿右边的墙
newHead.x = 1 ;
}
else if (newHead.y == mYTileCount - 1 )
{
// 穿下面的墙
newHead.y = 1 ;
}
// 判断是否撞到自己
int snakelength = mSnakeTrail.size();
for ( int snakeindex = 0 ;snakeindex < snakelength;snakeindex ++ )
{
Coordinatec
= mSnakeTrail.get(snakeindex);
if (c.equals(newHead))
{
setMode(LOSE);
return ;
}
}
// 判断是否吃掉“苹果”
int applecount = mAppleList.size();
for ( int appleindex = 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 );
}
int index = 0 ;
for (Coordinatec:mSnakeTrail)
{
if (index == 0 )
{
setTile(YELLOW_STAR,c.x,c.y);
}
else
{
setTile(RED_STAR,c.x,c.y);
}
index
++ ;
}
}

其实修改后的代码非常简单,就是把新节点的值做些处理,让它移动到对应的行/列的头部或尾部即可。

下面就是修改后的“穿墙”贪食蛇的运行截图:



全屏机制

游戏一般都是全屏的,原始代码也考虑到标题栏太过难看了,于是使用下面这句代码就去掉了标题栏:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> requestWindowFeature(Window.FEATURE_NO_TITLE);

可还是没有达到全屏的效果,在Android1.5中实现全屏效果非常简单,只需要一句代码即可实现:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

运行效果如下图所示:


接下来的修改目标是加入得分排行榜机制,再加入一个启动画面和选择菜单。当然,这一篇文章水了点,仅仅记录了自己做的一些小实验,并没有涉及到Snake的代码分析,不过请继续期待下一篇文章。。。


作者:phinecos(洞庭散人)
出处:http://phinecos.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,并在文章页面明显位置给出原文连接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值