第三章 用精靈實現動畫?
屏幕快照
在這一章你將創建你的第一個
MIDlet
程序來學習如何用精靈來創建簡單的動畫。
(
圖
8)
展示了模擬器上運行的完整的
MIDlet
程序的一系列屏幕快照。
(圖8)
螺旋運動的精靈
我們的
MIDlet
程序的精靈如
(
圖
9)
所示:
(圖9)
這個精靈由4行4列,16張獨立的幀組成。每一幀按次序顯示以創建動畫效果。
創建精靈類:AnimationSprite.java
在本教程中,對于你要開發的每一個MIDlet程序,當使用Wieless Toolkit(WTK)開發時,都遵循一組相同的開發步驟:
1. 創建工程.
2. 書寫源代碼.
3. 編譯和預校驗源代碼.
4. 運行MIDlet.
創建工程
創建一個新的工程
1. 點擊New Project.
2. 輸入工程名和MIDlet類名,如(圖10)所示.
3. 點擊Create Project.
(圖10)
編寫代碼:第一步
在這個MIDlet程序中你將發現3個源代碼文件:
° AnimationSprite.java: 精靈類
° AnimationCanvas.java: 顯示精靈的GameCanvas
° Animation.java: MIDlet程序啟動和停止的代碼
將下面的AnimationSprite.java代碼拷貝粘貼到文本編輯器:

/**//*---------------------------------------------
*?AnimationSprite.java
*----------------------------------------------*/
import?javax.microedition.lcdui.game.*;
import?javax.microedition.lcdui.*;

public?class?AnimationSprite?extends?Sprite
{

??public?AnimationSprite(Image?image,?int?frameWidth,?int?frameHeight)
{
????//?調用Sprite的構造函數
????super(image,?frameWidth,?frameHeight);
??}
}
當你創建了一個新工程,
WTK
會為你創建適當的目錄結構。本例中,
WTK
創建了目錄
C:\WTK20\apps\Animation
以及必要的子目錄。將
AnimationSprite.java
等
Java
源文件保存到
src
目錄下
(
如圖
11)
所示:
(圖11)
注意:啟動器盤符和WTK目錄會根據Toolkit安裝目錄的不同而不同。
編寫代碼:第二步
把下面的AnimationCanvas.java的代碼拷貝到文本編輯器中,把文件保存到上一節中的相同的目錄下。

/**//*--------------------------------------------------
*?AnimationCanvas.java
*-------------------------------------------------*/
import?javax.microedition.lcdui.game.*;
import?javax.microedition.lcdui.*;

public?class?AnimationCanvas?extends?GameCanvas?implements?Runnable
{
????//?一幀精靈圖像的尺寸
????private?static?final?int?FRAME_WIDTH?=?57;
????private?static?final?int?FRAME_HEIGHT?=?53;
????private?AnimationSprite?spSpiral;?//?動畫精靈
????private?LayerManager?lmgr;?//?圖層管理器
????private?boolean?running?=?false;?//?線程是否啟動

????public?AnimationCanvas()
{
????????//?游戲畫布構造函數
????????super(true);

????????try
{
????????????//?創建動畫精靈
????????????spSpiral?=?new?AnimationSprite(Image.createImage("/spiral.png");
????????????//?將精靈的參考象素移到精靈的中間
????????????spSpiral.defineReferencePixel(FRAME_WIDTH?/?2,?FRAME_HEIGHT?/?2);
????????????//?將精靈放置在屏幕中心
????????????//?(精靈的中心和屏幕的中心重合)
????????????spSpiral.setRefPixelPosition(getWidth()?/?2,?getHeight()?/?2);
????????????//?創建圖層管理器
????????????lmgr?=?new?LayerManager();
????????????lmgr.append(spSpiral);

????????}catch?(Exception?e)
{
????????????System.out.println("Unable?to?read?PNG?image");
????????}
????}

????/**//*--------------------------------------------------
????*?啟動線程
????*-------------------------------------------------*/

????public?void?start()
{
????????running?=?true;
????????Thread?t?=?new?Thread(this);
????????t.start();
????}

????/**//*--------------------------------------------------
????*?主循環
????*-------------------------------------------------*/

????public?void?run()
{
????????Graphics?g?=?getGraphics();

????????while?(running)
{
????????????//?刷新屏幕
????????????drawDisplay(g);

????????????try
{
????????????????Thread.sleep(150);

????????????}?catch?(InterruptedException?ie)?
{
????????????????System.out.println("Thread?exception");
????????????}
????????}
????}

????/**//*--------------------------------------------------
????*?刷新屏幕
????*-------------------------------------------------*/

????private?void?drawDisplay(Graphics?g)
{
????????//?顯示下一幀精靈圖像
????????spSpiral.nextFrame();
????????//?繪制圖層
????????lmgr.paint(g,?0,?0);
????????//?將屏幕緩沖刷新到屏幕
????????flushGraphics();
????}

????/**//*--------------------------------------------------
????*?停止線程
????*-------------------------------------------------*/

????public?void?stop()
{
????????running?=?false;
????}
}編寫代碼:第三步
最后一部分代碼如下所示。復制到文本編輯器中并另存為Animation.java:

/**//*--------------------------------------------------
*?Animation.java
**
顯示動畫精靈
*-------------------------------------------------*/
import?javax.microedition.midlet.*;
import?javax.microedition.lcdui.*;

public?class?Animation?extends?MIDlet?implements?CommandListener
{
????private?Display?display;?
????private?AnimationCanvas?canvas;?//?游戲畫布
????private?Command?cmExit;?//?退出按鈕


????public?Animation()
{
????????display?=?Display.getDisplay(this);
????????cmExit?=?new?Command("Exit",?Command.EXIT,?1);
????????//?創建游戲畫布和退出按鈕

????????if?((canvas?=?new?AnimationCanvas())?!=?null)
{
????????????canvas.addCommand(cmExit);
????????????canvas.setCommandListener(this);
????????}
????}


????public?void?startApp()
{

????????if?(canvas?!=?null)
{
????????display.setCurrent(canvas);
????????canvas.start();
????????}
????}


????public?void?pauseApp()
{
????}


????public?void?destroyApp(boolean?unconditional)
{
????????canvas.stop();
????}


????public?void?commandAction(Command?c,?Displayable?s)
{

????????if?(c?==?cmExit)
{
????????????destroyApp(true);
????????????notifyDestroyed();
????????}
????}
}
編譯和預校驗
單擊
Build
按鈕完成編譯、預校驗和打包。入圖
12
所示。然后點擊
Run
啟動應用管理器。
(圖12)
啟動MIDlet
(圖13)
單擊Launch啟動Aninate MIDlet,如圖13所示。啟動以后你將會看到如圖14所示的一系列屏幕輸出畫面。
(圖14)
代碼回顧:創建精靈
讓我們回去一下創建動畫精靈的代碼。這一節以及后面
3
節的代碼片段均來自
AnimationCanvas.java.
文件
//
?一幀精靈圖像的尺寸
private
?
static
?
final
?
int
?FRAME_WIDTH?
=
?
57
;
private
?
static
?
final
?
int
?FRAME_HEIGHT?
=
?
53
;



//
?創建動畫精靈
spSpiral?
=
?
new
?AnimationSprite(Image.createImage(
"
/spiral.png
"
);
精靈通過一個已經存在的
PNG
文件創建。
FRAME_WIDTH
和
FRAME_HEIGTH
表示圖像中每一幀的寬度和高度。圖
15
是同于創建精靈的實際圖片,而圖
16
把圖像拆分成一個個獨立的幀。
(圖15)
(圖16)
代碼回顧:設置參考像素
下面代碼的第一行將精靈的參考像素移到了精靈的中間,緊接著調用setRefPixelPosition()將新的參考像素放置到設備屏幕的中心,最后的結果就是精靈的參考像素和設備屏幕的中心重合。
//
?將精靈的參考象素移到精靈的中間
spSpiral.defineReferencePixel(FRAME_WIDTH?
/
?
2
,?FRAME_HEIGHT?
/
?
2
);
//
?將精靈放置在屏幕中心
//
?(精靈的中心和屏幕的中心重合)
spSpiral.setRefPixelPosition(getWidth()?
/
?
2
,?getHeight()?
/
?
2
);
//
?創建圖層管理器
lmgr?
=
?
new
?LayerManager();
lmgr.append(spSpiral);
上面代碼的最后兩行定義了一個圖層管理器
(
layer manager
)
并且將精靈添加到管理器中。圖層是游戲開發中的個基本的概念,它允許你靈活的將可視對象呈現在屏幕上。圖層管理器處理圖層的顯示以確保圖層能按適當層次顯示到屏幕上。深入探討圖層的使用已經超出了本教程的范圍,但是本教程卻包含了創建
MIDlet
所需的全部知識。
代碼回顧:運行動畫
萬事具備,下一步要做的就是開啟一個線程,輪流畫出精靈的圖像幀。

????/**//*--------------------------------------------------
????*?啟動線程
????*-------------------------------------------------*/

????public?void?start()
{
????????running?=?true;
????????Thread?t?=?new?Thread(this);
????????t.start();
????}

????/**//*--------------------------------------------------
????*?主循環
????*-------------------------------------------------*/

????public?void?run()
{
????????Graphics?g?=?getGraphics();

????????while?(running)
{
????????????//?刷新屏幕
????????????drawDisplay(g);

????????????try
{
????????????????Thread.sleep(150);

????????????}?catch?(InterruptedException?ie)?
{
????????????????System.out.println("Thread?exception");
????????????}
????????}
????}
線程運行時,RUN()控制著多長時間更新一次屏幕。每一次循環運行到drawDisplay()就畫出下一幀圖像。下一節你將會看到drawDisplay()的內部細節。
代碼回顧:畫出圖像幀
前面我們用FRAME_WIDTH和FRAME_HEIGHT定義了幀的寬度和高度。利用這些信息MIDlet能夠計算出圖像中有多少幀圖像。知道了有多少幀圖像,nextFrame()就能恰當的循環遍歷每一幀圖像,并且當達到最后一幀時跳回到第一幀重新開始。

/**//*--------------------------------------------------
????*?刷新屏幕
????*-------------------------------------------------*/

????private?void?drawDisplay(Graphics?g)
{
????????//?顯示下一幀精靈圖像
????????spSpiral.nextFrame();
????????//?繪制圖層
????????lmgr.paint(g,?0,?0);
????????//?將屏幕緩沖刷新到屏幕
????????flushGraphics();
????}
圖層管理器在指定位置繪制每一個圖層,圖層的位置取決于圖層相對于屏幕的位置。在這個
MIDlet
中,你要求圖層繪制在(0,0
)處。
如果你利用屏幕的頂部顯示其他信息,例如顯示分數,你可以改變傳遞給
Paint
()函數的
x,y
坐標值來適應這個要求。例如圖
17
中,坐標設置在了(
17,
17
)處以便統計附加信息顯示到屏幕頂部。這張圖片直接從
Sun Microsystems
的
MDIP2.0? API文檔里截取而來。

????????????????? to be continue...
posted on 2006-04-27 09:19
學二的貓 閱讀(2755)
評論(6) 編輯 收藏 所屬分類:
J2ME