鍍金池/ 教程/ Android/ Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析五
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析八
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析一
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析五
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析六
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析七
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析二
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析三
Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析四

Android 坦克大戰(zhàn)游戲設(shè)計(jì)解析五

本篇介紹坦克大戰(zhàn)游戲場(chǎng)景類BattleField的設(shè)計(jì)思路。

BattleField 是 Game API 中 TiledLayer 的子類。TiledLayer 實(shí)現(xiàn)了由小的圖形(稱為 tile)拼接成大的背景,坦克大戰(zhàn)游戲的背景是由磚塊,石塊,樹(shù)林,水面,雪地等小的圖片拼接而成。TiledLayer 可以很容易的實(shí)現(xiàn)這種類型的背景,包括水面波汶的動(dòng)態(tài)效果。

下面的圖片是一個(gè)簡(jiǎn)單由多個(gè)小 tile 組成的游戲背景。

http://wiki.jikexueyuan.com/project/android-game-design/images/15.jpg" alt="pic" />

理論上 TiledLayer 可以實(shí)現(xiàn)無(wú)限大的背景。為簡(jiǎn)單起見(jiàn)坦克大戰(zhàn)游戲中采用了半隨機(jī)的方法來(lái)生成游戲背景,同時(shí)也提供了從文件讀取游戲背景的方法,如果想完全復(fù)現(xiàn) FC 的每一關(guān),可以使用地圖編輯器或是文本編輯器生成文件,然后從文件中讀取背景。
這里給出一個(gè)關(guān)口的例子文件。

0000000000000
0202020202020
0202020202020
0202026202020
0202020202020
0000020200000
6022000002206
0000020200000
0202020202020
0202020202020
0202000002020
0000000000000

其中0代表空白,1 代表雪地,2 代表磚塊,3 代表樹(shù)林,4,5 代表水面,6 代表石塊。由于每個(gè) tile 比較小,這里每個(gè)數(shù)據(jù)代表一個(gè) 2X2 的區(qū)塊,下面代表實(shí)現(xiàn)從文件生成游戲背景

/**
 * 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:
  }
 }
}

實(shí)現(xiàn)在游戲中采用了半隨機(jī)的方法,這樣游戲關(guān)卡可以有無(wú)限多,半隨機(jī)是指一半的磚塊是從 HZK16(16 點(diǎn)陣漢字庫(kù))讀取一個(gè)漢字,用其點(diǎn)陣顯示為磚塊,其它雪地,樹(shù)林等采用隨機(jī)數(shù)隨機(jī)分布在游戲場(chǎng)景中。前幾關(guān)的漢字是“引路蜂軟件”。

坦克大戰(zhàn)游戲中還會(huì)隨機(jī)出現(xiàn)一些增強(qiáng)法寶,比如定時(shí)器可以讓敵方坦克停止運(yùn)動(dòng),地雷可以使屏幕中敵方坦克全部炸毀。鐵鍬可以讓“家”全部被石塊包住從而使敵方子彈無(wú)法打穿。星星可以讓已方坦克加速,同時(shí)發(fā)射的子彈數(shù)增加并增加打擊能力(比如可以打穿石塊甚至樹(shù)林等等)。

所以 BattleField 中同時(shí)也定義了顯示 PowerUp(增強(qiáng)法寶),初始化敵方坦克位置(一般是從最上方的左,中,右依次出現(xiàn))。另外還要判斷某個(gè)位置坦克是否可能通過(guò)(有磚塊,石頭,水面不能通過(guò)),雪地要加速,其它地方可以通行。另外還要判斷子彈是否擊中墻壁(子彈擊中墻壁后要爆炸等等)。

最后來(lái)看看它的 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;
  }
 }
}

它主要顯示水面的動(dòng)態(tài)效果,如果當(dāng)前需要顯示石塊做的家,則將相應(yīng)的 cell 中填入石塊,由于寶貝有時(shí)效性,到了一定時(shí)間后將“家”變回普通磚塊做成。