用J2ME在移動設備上實現動畫(2) (2007-04-11 11:48)

使用圖層

  在一個遊戲中 (或者其他的圖形程序),顯示區域內通常包含不同的內容(圖像可能是有關聯的或者是沒有關聯的)。比如一隻蜜蜂可以在森林,陸地,水面上飛翔,但是在一個迷宮中人卻不能穿越圍牆。

  MIDP 2.0遊戲 API爲此引進了圖層。圖層提供了控制屏幕上的對象或者上下文的方法。圖層可以是TiledLayer (比如背景), Sprite (比如飛機), 或者通過繼承Layer類自定義的類.

  下面代碼是對圖層使用的示例,本例中最重要的類是TiledLayer, LayerManager, 以及Image. Image 是用來保存具有相同大小的圖像或者圖象元素的類。 TiledLayer使用這些圖像來佈置背景

  當TiledLayer的實例被創建以時,構造方法要求五個參數,列數,行數,圖像,圖像元素的寬度和高度。這裏的例子中背景表格包含40 , 16 , 圖像時Tiles.png並且長寬都是7。代碼開頭的一些常量(TILE_GROUND etc.) 表示對圖像元素的引用。



  當TiledLayer實例被創建後,圖像元素的表格可以用 fillCells()方法來填充或者fillCell() 來填充。在代碼的最後 TiledLayer被加入到LayerManager. append() 方法用來把圖層加入到觀察窗口最下面。使用insert()可以把圖層插入到指定位置。

 

 

private TiledLayer tiles;
private LayerManager layers;
private Image tilesImage;

public final int TILE_GROUND = 1;
public final int TILE_WATER = 2;
public final int TILE_SHORE_LEFT = 3;
public final int TILE_FOREST = 4;
public final int TILE_AIR = 5;
public final int TILE_SHORE_RIGHT = 5;

// ...

// Creating an instance of the TiledLayer
layers = new LayerManager();
try {
tilesImage = Image.createImage("/Tiles.png");
} catch (IOException e) {}
tiles = new TiledLayer(40, 16, tilesImage, 7, 7);

// ...
// Filling the TiledLayer with tiles
tiles.fillCells(0, 0, 40, 16, TILE_AIR);
tiles.fillCells(14, 12, 12, 4, TILE_WATER);
tiles.fillCells(0, 10, 14, 6, TILE_GROUND);
// and more tiles like FOREST and the shores...

layers.append(tiles);

效果如下。

 

    使用精靈

  正如前面提到的那樣, 精靈被定義爲屏幕上的一個單獨的對象. 這個對象可以是推石頭的小人, 一架正在射擊的飛機。Sprite類的工作方式有點類似 TilesLayer ( 實事上他們都是從Layer類繼承來的). Sprite 也擁有一個包含幾副等大小的圖像的Image 對象。但是這些圖像與組成背景的圖像元素不同, 他們是表現遊戲主角的動畫的幀。因此精靈可以擁有動畫效果,並且通過更換其中的一些幀就可以輕鬆改變精靈的形象。

  下面代碼展示了怎麼創建一個Sprite的實例。原理其實和TiledLayer一樣.

try {
spriteImage = Image.createImage("/Sprite.png");
} catch (IOException e) {}

sprite = new Sprite(spriteImage, 7, 7);


  Layer類中的以下兩個方法可以輕鬆的控制精靈的移動:

move(int dx, int dy)
setPositions(int x, int y)


  通過 LayerManager來控制精靈的移動,繪製使非常方便的。下面的代碼展示了怎樣去控制一個精靈的移動。精靈的大小爲7×7,並且每次移動的幅度也是7個象素

public static final int UP = 0;
public static final int RIGHT = 1;
public static final int DOWN = 2;
public static final int LEFT = 3;

// ...

switch (direction){
case UP:
sprite.move(0, -7);
break;
case DOWN:
sprite.move(0, 7);
break;
case RIGHT:
sprite.move(7, 0);
break;
case LEFT:
sprite.move(-7, 0);
break;
default: break;
}


  遊戲編寫中還有一個重要的任務就是發現精靈間的碰撞。精靈可能必須呆在某個遊戲區域或者指定的迷宮,同時判斷精靈間的相互碰撞也是非常重要的。碰撞在有的遊戲中意味着轉換方向,有時候卻意味着game over

  Sprite 提供了以下四個方法,使我們可以對精靈的碰撞作出判斷:

collidesWith(Image image, int x, int y,
boolean pixelLevel)
collidesWith(Sprite s, boolean pixelLevel)
collidesWith(TiledLayer t, boolean pixelLevel)
defineCollisionRectangle(int x, int y,
int width, int height)


  當兩個Sprite的實例(也可以時TiledLayerSprite Image)碰撞或者說重合時,我們可以對此作出響應。

  結束語

  本文結合幾個例子介紹了MIDP 2.0中最常用遊戲 API的新特性,有了這些特性,開發者不但可以方便的控制比屏幕大的遊戲區域的繪製,而且可以方便的在不同圖層上繪製物體

      Game API函數使用以下四個類爲圖層提供靈活的支持

  1 Layer類是所有圖層類對象的抽象基類。它定義了一個圖層的基本屬性,包括位置,尺寸,和此圖層是否可見。Layer類的每個子類必須定義一個paint()方法,用來把這個圖層表現在一個圖象上,這個圖象將會被描畫到屏幕表面上。兩個確切的子類TiledLayerSprite應該能滿足你的二維遊戲的需要了。

   TiledLayer類用來建立背景圖像。你可以用一個小的源圖像貼的集合來高效的製作大的圖像。

   Sprite類是一個動畫層。你提供源幀就可以對整個動畫進行完全的控制。Sprite類也提供鏡像,並可對源幀作90度旋轉。

   LayerManager類是一個非常有用的類,用來保存你的場景中的所有圖層的動作軌跡。LayerManager paint()方法的一個簡單調用就足以控制所包含的所有圖層。

  使用TiledLayer

  儘管包含一些不是顯而易見的微妙不同,TiledLayer類還是很容易理解。這個類的基本思想就是,用一個源圖像提供一組圖像貼片,這些貼片可以組合成一幅大的場景。例如,下面的圖像是64*48像素的。


Source Image

  這個圖像被分成了1216*16的圖像貼片。TiledLayer類分配給每個圖像貼片編號,左上角的圖片規定爲1,以此類推。上面源圖像的各個貼片如下編號:


Tile Numbering

  用代碼創建一個TiledLayer類是非常簡單的。你需要確定行數和列數,源圖像以及這個源圖像裏每個貼片的像素大小。下面的代碼片斷告訴你如何裝載圖像和創建TiledLayer類。

Image image = Image.createImage("/board.png");
TiledLayer tiledLayer = new TiledLayer(10, 10, image, 16, 16);

  在例子中,新的TiledLayer類有10行,10列。這些來自image的圖像貼片大小是16*16像素。
有趣的部分還是用這些圖像貼片來創建一幕場景。利用setCell()方法可以把一個圖像貼片分配到一個數組元胞裏。你需要提供這個數組元胞所在行列數以及圖像貼片的編號。例如,你可以通過調用setCelll(2,1,5)方法把編號爲5的圖像貼片分配到第2行中的第3個數組元胞裏。如果你覺得這些參數看起來不對,請注意,圖像貼片編號是從1開始計數,而行和列的編號是從0開始的。參數缺省情況下,新的TiledLayer類對象中的所有數組元胞的圖像貼片標號爲0,這就意味着它們是空的。

  下面的代碼片斷向你說明一種使用整數數組來填充TiledLayer類對象。在實際圖像中,TiledLayer類可以從資源文件裏定義,這就使得定義背景時可以有更多的靈活性,並能提供新的背景和級別來增強遊戲的可玩性。

private TiledLayer createBoard() {
Image image = null;
try { image = Image.createImage("/board.png"); }
catch (IOException ioe) { return null; }

TiledLayer tiledLayer = new TiledLayer(10, 10, image, 16, 16);

int[] map = {
1, 1, 1, 1, 11, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 9, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 7, 1, 0, 0, 0, 0, 0,
1, 1, 1, 1, 6, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 7, 11, 0,
0, 0, 0, 0, 0, 0, 7, 6, 0, 0,
0, 0, 0, 0, 0, 7, 6, 0, 0, 0
};
for (int i = 0; i < map.length; i++) {
int column = i % 10;
int row = (i - column) / 10;
tiledLayer.setCell(column, row, map[i]);
}
return tiledLayer;
}

 

  爲了把這個TiledLayer類對象顯示在屏幕上,你需要調用一個Graphics對象的paint()方法。

TiledLayer類還支持動畫圖像帖子,這樣就使得通過一系列貼片來移動元胞集合很容易了。

若想得到更詳細的說明,參看TiledLayer類相關的API文檔。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章