5 Android 坦克大战游戏设计解析五
本篇介绍坦克大战游戏场景类 BattleField 的设计思路。
BattleField 是 Game API 中 TiledLayer 的子类。TiledLayer 实现了由小的图形(称为 tile) 拼接成大的背景,坦克大战游戏的背景是由砖块,石块,树林,水面,雪地等小的图片拼接而成。TiledLayer 可以很容易的实现这种类型的背景,包括水面波汶的动态效果。
下面的图片是一个简单由多个小 tile 组成的游戏背景。
图片 5.1 pic
理论上 TiledLayer 可以实现无限大的背景。为简单起见坦克大战游戏中采用了半随机的方法来生成游戏背景,同时也提供了从文件读取游戏背景的方法,如果想完全复现 FC 的每一关,可以使用地图编辑器或是文本编辑器生成文件,然后从文件中读取背景。
这里给出一个关口的例子文件。
0000000000000 0202020202020 0202020202020 0202026202020 0202020202020 0000020200000 6022000002206 0000020200000 0202020202020 0202020202020 0202000002020 0000000000000
其中 0 代表空白,1 代表雪地,2 代表砖块,3 代表树林,4,5 代表水面,6 代表石块。由于每个 tile 比较小,这里每个数据代表一个 2X2 的区块,下面代表实现从文件生成游戏背景
/** * Read the battle from an input stream. * @param is input stream stores the battle field information. */ private void readBattlefield(java.io.InputStream is) throws IOException { int c = -1; int x0 = (WIDTH_IN_TILES-NUMBER_IN_TILES)/2; int y0 = (HEIGHT_IN_TILES-NUMBER_IN_TILES)/2; int x=0,y=0; while ((c = is.read()) != -1 && y < NUMBER_IN_TILES) { switch (c) { case ' '://empty case '0': duplicateCell(x+x0, y+y0, 0);x+=2; break; case '1'://snow field duplicateCell(x+x0, y+y0,SNOW);x+=2; break; case '2'://brick wall duplicateCell(x+x0, y+y0, BRICK_WALL);x+=2; break; case '3'://forest duplicateCell(x+x0, y+y0, FOREST);x+=2; break; case '4': case '5'://water duplicateCell(x+x0, y+y0, -1 - ((x ^ y) & 1));x+=2; break; case '6': //Concrete wall duplicateCell(x+x0, y+y0, CONCRETE_WALL);x+=2; break; case '\n'://new line y+=2; x = 0; break; default: } } }
实现在游戏中采用了半随机的方法,这样游戏关卡可以有无限多,半随机是指一半的砖块是从 HZK16(16 点阵汉字库)读取一个汉字,用其点阵显示为砖块,其它雪地,树林等采用随机数随机分布在游戏场景中。前几关的汉字是“引路蜂软件”。
坦克大战游戏中还会随机出现一些增强法宝,比如定时器可以让敌方坦克停止运动,地雷可以使屏幕中敌方坦克全部炸毁。铁锹可以让“家”全部被石块包住从而使敌方子弹无法打穿。星星可以让已方坦克加速,同时发射的子弹数增加并增加打击能力(比如可以打穿石块甚至树林等等)。
所以 BattleField 中同时也定义了显示 PowerUp(增强法宝),初始化敌方坦克位置(一般是从最上方的左,中,右依次出现)。另外还要判断某个位置坦克是否可能通过(有砖块,石头,水面不能通过),雪地要加速,其它地方可以通行。另外还要判断子弹是否击中墙壁(子弹击中墙壁后要爆炸等等)。
最后来看看它的 tick() 中主要做些什么
public void tick() { int tickState = (tickCount++ >> 3); // slow down x8 int tile = tickState % 2; setAnimatedTile(-1 - tile, waterFrames[tile][(tickState % 4) / 2]); if(concreteWallStartTime>0){ long tickTime=System.currentTimeMillis(); if(tickTime-concreteWallStartTime>concreteWallPeriod){ makeHomeBrickWall(); concreteWallStartTime=0; } } }
它主要显示水面的动态效果,如果当前需要显示石块做的家,则将相应的 cell 中填入石块,由于宝贝有时效性,到了一定时间后将“家”变回普通砖块做成。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论