天天看點

使用TiledLayer類及Canvas類實作遊戲背景圖層

1. 建立一個平鋪圖層

MIDP 2.0 API通過TiledLayer類支援平鋪圖層,這個類使得建立和使用平鋪圖層變得相對容易。每個平鋪圖層都有一個相關的圖像,它指定了一組用來描述平鋪圖層地圖的貼磚。每個平鋪圖層都有一個地圖,它包含了用來引用圖層圖像中的單個貼磚的貼磚索引。由于TiledLayer派生自Layer類,是以,可以按照和操縱遊戲Sprite(精靈)差不多的方式來操縱,即可以改變平鋪圖層的位置、獲得它的尺寸和位置、繪制它并且通過一小段簡單的方法用來控制它的要見性。

建立一個平鋪圖層的時候,要以貼磚為機關指定它的寬度和高度,以及包含貼磚組的圖像、貼磚的寬度和高度。每塊貼磚的大小必須相同。當第一次建立一個平鋪的圖層的時候,這些資訊都傳遞到TieldLayer構造函數中。

下面的代碼摘自我做的遊戲,其功能用來建立一個平鋪圖層:

//太空背景

private TiledLayer        waterLayer;

……

try{

                  waterLayer=new TiledLayer(50,200,Image.createImage("/res/backg.png"),32,32);

                } catch (IOException e) {

                        System.err.println("^_抱歉,太空背景圖檔加載失敗^_^")

TiedLayer()構造函數中的頭兩個參數分别指定了平鋪圖層的列數和行數。第3個參數是一個Image對象。其餘兩個參數分别是每個貼磚的寬度和高度,在本程式中背景貼磚的寬和高都是為32像素的标準正方形。

建立了一個TiledLayer對象以後,接下來就是把其每個單元格設定為貼磚索引,進而建立其地圖。貼磚索引都是從1開始計數,索引0是一個特殊的貼磚索引,表示貼磚空缺,即繪制平鋪圖層的時候,貼磚索引被指定為0的貼磚是透明的。

下面是本遊戲中存儲在一個一維整數數組中的圖層地圖(數值被忽略)

/*Setup the water tiled layer map*/

Int [] waterMap={

};

由于沒有把貼磚索引數組傳遞給Tiedlayer的方法,所有必須多次調用setCell()方法把貼磚索引置入到平鋪圖層的每個單元格中。下面代碼是本遊戲使用一個for循環來為遊戲平鋪圖層來完成這項任務的代碼:

/*Set the contents of cells*/

                int column,row=-1;

                for (int i = 0; i < waterMap.length; i++) {

                        column = i % 24;

                        row = (i - column) / 24;

                        waterLayer.setCell(column, row, waterMap[i]);

                    }

這段代碼通過循環通路了貼地磚地圖的每個條目,并根據具體的行和列來設定平鋪圖層中的每個相應的單元格。這段代碼可以很容易地進行修改以适應不同大小的地圖,隻要改變第2行和第5行代碼中的行數和列數就可以了。

2. 移動和繪制一個平鋪圖層

Canvas類的update()方法是處理按鍵輸入和和相應的地方。在本遊戲中,按鍵輸入導緻背景圖層在精靈下滾動,而精靈在遊戲中由按鍵操作移動,關于按鍵的處理已在我的一篇博文

《手機遊戲中處理按鍵輸入的方法》

中提到。

使一個圖層移動并且具有動感的代碼如下:

/***********背景更新*******************************/

  private void backGroundUpdate() {

    //實作背景的移動

        if(y<0)

        {

                y+=speedOfBG;

                downLimit-=speedOfBG;

                upLimit-=speedOfBG;

        }

        //使太空背景具有動感

        if (++waterDelay > 3) {

            if (++waterTile[0] > 3)

                waterTile[0] = 1;

            waterLayer.setAnimatedTile(-1, waterTile[0]);

            if (--waterTile[1] < 1)

                waterTile[1] = 3;

            waterLayer.setAnimatedTile(-2, waterTile[1]);

            waterDelay = 0;

  }

繼續閱讀