Layer類
在前面的示例中并沒有使用背景,而且程序中的物體也很單一,但是實際的游戲不可能這樣。一般來講,游戲都會有背景,有的甚至用幾層背景來表示畫面的層次感。在游戲開發中可以通過作圖完成對背景的處理,不過在 MIDP v2.0 中可以通過 Layer 對象輕松處理游戲背景、物體的移動和實現動畫。
圖層是可以在游戲畫布中單獨繪制并能夠移動的一些對象,一般來說,游戲都會有超過一個的圖層。例如,背景圖層用來繪制游戲的背景,場景圖層用來顯示當前的場景,物體圖層用來顯示當前場景中移動的物體。例如,用游戲的一個場景來舉例,游戲的背景圖是星空,占據整個屏幕;然后在上面覆蓋建筑物圖層,這一圖層沒有覆蓋整個屏幕,而且是透明的,沒有覆蓋和透明的區域上就會顯示出背景;然后最上面才是物體圖層顯示移動的主角和障礙物。在MIDP 中TiledLayer類用來顯示背景和場景,Sprite類用來顯示移動的物體,這兩個類都是直接從Layer 類中派生的。
在MIDP 中并沒有限制圖層的數量,不過在開發游戲時必須考慮到設備的處理能力對實際的圖層數量做出限制。
類的定義為:public abstract class Layer extends Object ,是一個虛類。
public abstract class Layer extends Object
java.lang.Object
+-javax.microedition.lcdui.game.Layer
Layer 類是一個虛類并不能直接使用,因此在MIDP 中還定義 Layer 類的派生類 TiledLayer類和 Sprite 類處理背景圖層和移動的物體。Layer 類中提供的方法如表 7.2 所示。
7.3.1.1.1 表 7.2 Layer 類所定義的方法
方法名稱 |
方法原型與作用 |
getHeight |
public int getHeight( )
得到圖層的高度 |
getWidth |
public int getWidth( )
得到圖層的寬度 |
move |
public void move(int dx, int dy)
移動圖層,參數dx和dy分別表明在X軸和Y軸上移動的距離。如果dx 距離小于零,則表示向左或向上移動;如果dy 距離大于零,則表示向右或向下移動 |
續表
方法名稱 |
方法原型與作用 |
getX |
public int getX( )
得到圖層的起始點X 坐標 |
getY |
public int getY( )
得到圖層的起始點Y 坐標 |
setPosition |
public void setPosition(int x, int y)
將圖層移動到參數(x, y) 指定的坐標處 |
setVisible |
public void setVisible(boolean visible)
設置圖層是否可見 |
isVisible |
public boolean isVisible( )
檢測圖層是否可見 |
paint |
public abstract void paint(Graphics g)
繪制圖層,只有對于可見的圖層才會被實際繪制。一般來說,不需要直接調用圖層對象的 paint 方法,而是由LayerManager 對象調用這個方法 |
由于Layer 是無法直接使用的,因此在處理背景時需要用到 TiledLayer (分塊圖層)類。TiledLayer 類能夠按照單元的方式組織整個大的背景圖層。類的定義為:
public class TiledLayer extends Layer
java.lang.Object
+-javax.microedition.lcdui.game.Layer
+-javax.microedition.lcdui.game.TiledLayer
在 TiledLayer 類中有兩個概念:單元和圖像分塊。
單元是指將整個圖層分為相同大小的區域,假設游戲屏幕尺寸為:130×60,每個單元的面積為10×10,那么可以把屏幕分為13×6個單元。
圖像分塊是指將一幅大的圖像按照單元大小分為多個塊,對于屏幕的每個單元都可以用一個圖像進行填充。
TiledLayer 對象主要作用是管理圖像分塊和屏幕單元的填充。
l 首先一個TiledLayer 對象中包含了多個分塊的圖像。
l 其次當前圖層會被分為多個大小相等的單元,每個單元可以使用對象本身包含的一個圖像分塊填充。
圖7.2演示了如何將一幅大的圖像分割為為多個分塊。從圖7.2 中可以了解到一幅大的圖像被分為序號從1(不是從零開始,序號零被用來表示空圖像)開始的多個分塊。原始圖像按照從左到右,從上到下的順序計算新的分塊序號,此外每個分塊不一定需要設計為正方形(圖7.2 中序號4與序號5中的淺灰色部分為透明顏色)。
如圖7.2 所示,所有圖像分塊的序號都是正數,表示的是靜態圖像分塊。此外序號為0的分塊也是合法的,表示空圖像,相當于一個全透明的圖像。與序號為正數的分塊不同之處在于,序號為 0 的分塊由系統提供不需要用戶提供。

7.4.1.1.1 圖7.2 圖層中所用到的圖像分塊的構成
本節只介紹利用單一圖層進行顯示的知識,使用多個圖層的知識將在7.5節介紹。如果要創建顯示一個圖層需要以下步驟。
(1) 裝入圖像。
(2) 創建一個 TiledLayer 對象。
(3) 把圖像裝入TiledLayer 對象,并設定圖層的大小和每個分塊的尺寸。TiledLayer 對象會根據圖像的尺寸計算分塊的數量,并且通過每個分塊的尺寸和單元格的數 量計算圖層的面積,實際這個過程是在創建TiledLayer 對象時完成。
(4) 把圖像分塊按需要填入單元格,以后如果需要修改某個單元格的圖像,則可以重新設置。
(5) 調用TiledLayer 對象的paint 方法進行繪圖。
(6) 調用Canvas對象的flushGraphics 方法刷新屏幕。
除前面提到的靜態圖像分塊和空圖像分塊外,還有一種分塊類型,就是序號為負數的分塊,在MIDP 中表示動畫分塊。在圖層中使用動畫分塊的好處在于,如果修改動畫分塊內的圖像,那么整個圖層上相同序號的動畫分塊填充的單元格都會同時改變。
與靜態分塊不同,動畫分塊是需要額外創建的,創建的第一個動畫分塊的序號為 –1,第二個為 –2。在創建動畫分塊時,需要指定一個靜態分塊圖像作為初始圖像,為了實現動畫效果可以在變換畫面時用另一個靜態分塊圖像替換動態分塊中的現有圖像。例如,先創建一個動畫分塊,假設序號為 –1。初始圖像為圖7.2 中最下面一組分塊的序號1分塊,然后依次用其他序號的分塊圖像替代序號為–1 的動態分塊中的圖像。這樣被序號為 –1 的分塊所填充的所有單元格都能顯示出動態效果。
TiledLayer 類的方法如表 7.3 所示。
7.4.1.1.2 表7.3 TiledLayer 類所包含的方法
方法名稱 |
方法原型與作用 |
TiledLayer |
public TiledLayer(int columns, int rows, Image image, int tileWidth, int tileHeight)
構造方法,參數columns和rows分別表明圖層中的單元格列數和行數,參數 image 為包含所有分塊的圖像,參數 tileWidth和tileHeight分別表明每個分塊的寬度和高度。圖層的面積是單元格的數量乘以每個分塊圖像的面積。圖層實際的寬度為 columns × (tileWidth × tileHeight) ,高度為rows × (tileWidth × tileHeight) |
setCell |
public void setCell(int col, int row, int tileIndex)
將圖層中指定位置(col,row )單元格設置為序號為參數tileIndex 指定的分塊圖像。tileIndex 必須為0 或者是正數。如果為0 表示該單元格不填充 |
fillCells |
public void fillCells(int col, int row, int numCols, int numRows, int tileIndex)
將圖層中指定的單元格區域,位置為( col, row)、面積為( numCols, numRows) 用序號為tileIndex分塊圖像填充。fillCells與setCell 方法不同之處在于,能夠一次設置多個相同的單元格 |
getCellWidth |
public int getCellWidth( )
得到單元格寬度,也就是構造對象時 tileWidth 的值 |
getCellHeight |
public int getCellHeight( )
得到單元格高度,也就是構造對象時 tileHeight 的值 |
getColumns |
public int getColumns( )
得到圖層中單元格的列數 |
getRows |
public int getRows( )
得到圖層中單元格的行數 |
setStaticTileSet |
public void setStaticTileSet(Image image, int tileWidth, int tileHeight)
重新創建分塊圖像。在執行此操作后對象所包含的原有分塊會被刪除,而且圖層的面積會根據新的分塊大小重新計算 |
CreateAnimatedTile |
public int createAnimatedTile(int staticTileIndex)
創建一個動畫分塊,初始化時把序號為staticTileIndex 的分塊圖像作為這個動畫分塊的圖像。返回值為創建的動畫單元格序號,第一個創建動畫單元格為 -1,第二個為 –2 |
setAnimatedTile |
public void setAnimatedTile(int animatedTileIndex, int staticTileIndex)
將序號為animatedTileIndex 的動畫分塊的圖像用序號為 staticTileIndex 的分塊圖像代替 |
getAnimatedTile |
public int getAnimatedTile(int animatedTileIndex)
得到序號為animatedTileIndex 的動畫分塊實際的圖像分塊序號 |
下面先舉一個比較簡單的例子講解單一圖層的用法,在這個示例中將會直接使用圖層進行繪圖(使用LayerManager 對象管理多個圖層的知識將在7.5 節介紹)。此處要演示的效果是:在圖層上將某幾個單元格創建為動畫單元格并循環顯示動畫效果。
程序中所使用的圖像如圖7.3 所示,每個分塊面積為30×30像素。序號4用來填充地面;序號5用來填充屏幕的空白區;序號1和序號2以動畫的方式顯示一個跳動的小球;序號3和序號6用來顯示星星,在這里會創建一個動態分塊 –1 ,并且用序號3和序號6的圖像來輪流替換動態分塊中的圖像。

7.4.1.1.3 圖7.3 用來創建圖層的圖像分塊