Android坦克大战游戏设计解析六

本篇介绍坦克大战游戏除坦克之外的几个角色。
1. Bullet 子弹类        坦克发射出的子弹在游戏中飞行
2.Explosion 爆炸类   子弹击中子弹,障碍物,或是坦克显示爆炸
3. Powerup 增强宝贝类  星星,加坦克,定时器等
4. Score 分数类。         击中坦克或是攻取增强宝贝,加分显示,分数有100,200,300,400,500,击中不同坦克分数不同。
为直观起见,参见下图,红圈里从上到下分别是Bullet, Powerup, Explosion, Score.

子弹类,屏幕中所有显示子弹从一个子弹池BULLET_POOL中取出,子弹有方向,速度,及强度等属性,高强度的子弹可以击破石块。
它每个游戏帧所要完成的操作如下。

/**
 * Operation be done in each tick.
 */
public void tick(){
 if (!isVisible() || direction==BattleField.NONE)
  return;
 // Move the bullet.
 move(dx, dy);
 int x = getRefPixelX();
 int y = getRefPixelY();
 PlayerTank playerTank=(PlayerTank)Tank.getTank(0);
 //outside the battle field, hitting the border
 if (x <= 0 || x >= battleField.getWidth() || y <= 0
   || y >= battleField.getHeight()) {
 
  //this is to avoid explosition outside the battlefield.
  if(x<=0) x=0;
  if(x >= battleField.getWidth()) x= battleField.getWidth();
  if(y<=0) y=0;
  if(y>= battleField.getHeight())y=battleField.getHeight();
  setPosition(x,y);
  explode();
  return;
 }
  
 // See if it hit a tank.
 if (friendly) {
  // See if it hit an enemy tank.
  for (int i = 1; i < Tank.POOL_SIZE; i++) {
   EnemyTank enemy = (EnemyTank)Tank.getTank(i);
   if (enemy!=null && enemy.isVisible() &&
     collidesWith(enemy, false)) {
    enemy.explode();
    explode();
    return;
   }
  }
 } else {
  // See if it hit player tank.
   
  if (collidesWith(playerTank, false)) {
   playerTank.explode();
   explode();
   return;
  }
 }
  
 //check to see if hit player's home
 if(Powerup.isHittingHome(this)){
  //TODO: Game Over
  explode();
  return;
 }
 // See if it hit a wall.
 if (battleField.hitWall(x, y, strength)) {
  explode();
  return;
 }
  
 // See if it hit another bullet.
 for (int i = 0; i < POOL_SIZE; i++) {
  Bullet anotherBullet=BULLET_POOL;
  if(this!=anotherBullet && anotherBullet.isVisible()){
   if (collidesWith(anotherBullet, false)) {
    explode();
    BULLET_POOL.explode();
    return;
   }
  }
 }
}


要判断是否击中墙壁,对方坦克,或是对方子弹,是否击中“家”,如果有,则爆炸,如都没有,则同方向前行一步。
爆炸类,子弹击中障碍物(墙,子弹,坦克)时显示爆炸动画效果。它有两种一个是大爆炸,一个是小爆炸。
它每个游戏帧所要完成的操作比较简单,每步显示一个动画帧,直到显示完。要判断是否击中墙壁,对方坦克,或是对方子弹,是否击中“家”,如果有,则爆炸,如都没有,则同方向前行一步。
爆炸类,子弹击中障碍物(墙,子弹,坦克)时显示爆炸动画效果。它有两种一个是大爆炸,一个是小爆炸。
它每个游戏帧所要完成的操作比较简单,每步显示一个动画帧,直到显示完。

/**
 * Operation be done in each tick.
 */
public void tick() {
 if (!isVisible())
  return;
 nextFrame();
 if (getFrame() == 0){
  setVisible(false);
 }
}


增强宝贝类,有多种,无敌,加坦克,地雷,定时器等。不同的增强宝贝可以使玩家获得不同的能力,玩过坦克大战游戏的人都比较熟悉。
在游戏进行中, 会不时或者当玩家打中红色坦克时,会有游戏中随机出现不同增强宝贝。
它每个游戏帧所要完成的操作如下:
如果玩家得到“无敌”增强功能时,“无敌”具有一定的时效性,需要判断无敌是否过时,其它时候则让该增强宝贝有闪烁效果,引起玩家注意。增强宝贝类,有多种,无敌,加坦克,地雷,定时器等。不同的增强宝贝可以使玩家获得不同的能力,玩过坦克大战游戏的人都比较熟悉。
在游戏进行中, 会不时或者当玩家打中红色坦克时,会有游戏中随机出现不同增强宝贝。
它每个游戏帧所要完成的操作如下:
如果玩家得到“无敌”增强功能时,“无敌”具有一定的时效性,需要判断无敌是否过时,其它时候则让该增强宝贝有闪烁效果,引起玩家注意。

/**
 * Operation be done in each tick.
 */
public void tick(){
 if(type==NOTHING || !isVisible()) return;
 long tickTime = System.currentTimeMillis();
 long refreshPeriod=MILLIS_PER_TICK;
  
 //invulnerable powerup is controlled by the player tank.
 if(type!=INVULNERABLE &&type!=HOME && type!=HOME_DESTROYED){
  if(tickTime-startTime>livePeriod){
   setFrame(NOTHING);
   setVisible(false);
   return;
  }
 }else{
  refreshPeriod=MILLIS_PER_TICK/10;
 }
 if(timeTaken>=refreshPeriod){
  showNextFrame=!showNextFrame;
  if(type==INVULNERABLE){
     if(showNextFrame){
    setFrame(0);
   }else{
    setFrame(1);
   }
  }else if(type==HOME || type==HOME_DESTROYED){
     setFrame(type);
  }else{
   if(showNextFrame){
    setFrame(type);
   }else{
    setFrame(NOTHING);
   }
  }
  timeTaken = System.currentTimeMillis() - tickTime;
 } else{
  timeTaken+=1;
 }
}

最后一个是分数类,比较简单,它每个游戏帧所要完成的操作如下


最后一个是分数类,比较简单,它每个游戏帧所要完成的操作如下

/**
 * Operation be done in each tick.
 */
public void tick(){
 if(isVisible()){
  long tickTime = System.currentTimeMillis();
  if(startTime>0){
   if(tickTime-startTime>livePeriod){
    setVisible(false);
    startTime=0;
    return;
   }
  }
 }
}

在屏幕上显示几秒种后消失。
在屏幕上显示几秒种后消失。

 

代码源于反编坦克大战游戏的apk文件 Android apk文件 反编说明 一.------ 反编apk文件目的 目前反编android程序功能最强的jd-gui.exe(http://laichao.googlecode.com/files/jdgui.zip), 也只能反编没用混淆器编译的android程序的80%代码,对于混淆器编译的android程序,只能 反编不到10%代码。    借鉴成功的商业程序代码,是新手快速提高编程水平的途径。为此,笔者制作了 android反编译工具,能将混淆器编译的apk文件,还原java文件,资源文件的android开发 项目。可以直接编译目的apk文件,运行效果与原apk一样。只有能正常运行的程序,才有价值 对它进行分析、借鉴。  二.----- 反编java的成员,方法名,类名     经混淆器编译的apk文件,会将原代码的成员,方法名更换为单字符的短名。例如原代码 成员名GetName、方法名PayDialog() 经混淆器编译后,转换为a、b()的短名,这是为了 增加反编代码的阅读难度,同时也阻止成员名,方法名的搜索定位,是防反编译的重要手段。 为提高反编译代码的阅读性,笔者的android反编译工具,将成员,方法短名,按一定的规则 转为长名,使得成员、方法名具有很强的逻辑性,大大提高了代码的阅读性。   成员、方法短名转换为长名的规则: 1-- 公共成员名: 短名a --> Pa_源类名_类型  注: 源类名-声明公共成员所在的类名; 类型 -成员的类型,如int类型的成员,类型字符就是int     2-私有成员名: 短名a --> Ma_类型 3-- 公共方法名: 短名b() --> 源类名_bxxx() 注: 源类名-- 声明公共方法所在的类         xxx   -- 3位数字序号 4-- 私有方法名: 短名b() --> pri_bxx() 5-- 本地成员(方法内的变量):  短名c --> Lc_类型 6-- 类名: 短名a.java --> axxxx.java 注: xxxx -- 4位数字序号  从长名的字符,就可以直接知道成员的属性(如公共、私有、本地的成员,成员的类型, 公共成员的源类名),同时, 长名字符串是唯一的,可以用于字符搜索查找精确 定位、更换,大大提高了反编java代码的阅读性,不亚于阅读原代码。 对于编译时,无混淆为短名的成员、方法名,反编时,还是采用原代码的名称。 只要不符合上面规则的成员、方法名称,就是原代码的名称。    一般说来,成员原名字符,是编程人员自定义有一定意义的字符串,可以望字生意。  但成员名毕竟不是短文,非原编程作者,很难从短短几个字符,就能知道成员的作用。只能通  过分析成员在上下文的赋值、取值关系,才能准确地了解成员的作用;另一方面,成员原名字符,  尤其是字符短的成员名,一般都不能保证字符串的唯一性,造成查询定位成员的困难,影响程  序的分析。        按公共,私有,本地成员的作用域不同,分析的側重点要区别对待。分析程序的整体功能流程,重点  要分析公共成员和公共方法,分析类,方法的功能呢时,重点放在私有、本地成员上。 反编的成员长名,有很强的逻辑性, 从长名就能直接知道成员,方法的作用域和源类名(声明该成员, 方法所在的类名),这大大降低了分析的难度。         三.---- 反编的循环控制层风格          因编译后,会将原java代码的for (i=1,100,i++)循环语句 转为 for ( ; ;), if (i>100) { break} else { i++}    2条语句,反编后的java的也是用上面2条语句代替for (i=1,100,i++),但在if语句附上"控制if“的注释     同样,用for ( ; ;) 取代原java的 while 语句    四.---- 反编的类形式        反编的java 都用独立的类取代原码的类中类,匿名类。 虽然对于只使用一次对象值的(通常是监听类),都可以将独立类改为匿名类。但笔者认为, 将一大段匿名类代码放在方法的参数中,会影响阅读性, 倾向于独立类的阅读性好于匿名类。     五.----  项目各目录的简介     本项目反编于 网上下载游戏 2.0.4版本的apk文件, 在Eclipse平台上的android 2.2版本(android-8)能成功编译,正常运行。在编译前,要将用户   本地2.2或以上版本的android.jar链接到本项目。     assets\ -- 背景声文件        bin\ -- 由编译所生成的class、 apk 文件     gen\ -- 由编译所生成的R.java(源于res\的资源数据) libs\ -- 原生态引擎库 res\ -- 图片,字符的资源库     src\ -- 程序(java)文件 AndroidManifest.xml -- 项目的配置文件  project.properties -- 配置Android版本文件 readme.txt -- 本内容 .---- 不足与该进     目前反编的java,都直接用android常量数值,而无用到常量名。这影响了程序的分析。    如 src\cn\koogame\ui\KooUiActivity.java 的onTouchEvent() ( 重载手势方法中)中,      可以用 case MotionEvent.ACTION_MOVE: 代替 case 2: ,显然前者阅读性优于后者。    因笔者还没有android常量大全资料,只好暂时直接地使用常量值。若那位读者愿提供 Android常量大全资料,非常欢迎发到笔者的邮箱 walte139@163.com 。 若有建议、意见、批评,也欢迎发给笔者。 Walte 2013.10.12                 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值