程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> j2me游戲教程(五)——動畫系統

j2me游戲教程(五)——動畫系統

編輯:J2ME

播放動畫為什麼還要有個系統待我慢慢講來。
狀態機大家都知道了,就是無限循環的東西。
動畫是由一桢一桢組成的,這個桢和游戲的桢概念不同。但含義都差不多。
每一桢就是組成動畫的一幅畫,上一桢和下一桢可能相同也可能不同,連續播放就可看到動畫的效果 比如一個動畫由12桢組成:(假設 | \—/都是小棍形狀)

 |, |, |, \, \, \, —, —, —, /, /, /
那麼連續播放的話,就是播完從頭再撥,就可以看到一個小棍兒在不停的轉。
那麼在一個不斷循環的系統中播放動畫,播完一遍需要12次循環,也就是12桢。
為什麼相同的桢要播放三次,那是因為你要控制它播放的速度。
如果每桢播一次,機器又很快,就是FPS很快,你就會看到一個小棍兒在瘋轉。
相同的一個動畫,如果你的機器快,他的機器慢,在上面看起來效果就不一樣。
但是之前我們講過FPS,講過限桢的概念。
就是把一桢的時間控制在相同的范圍。
如果程序限了桢,不管在哪個機器上,繪制一桢的時間都是確定的。
那麼這個動畫在哪看起來速度都一樣。
那麼現在看看代碼怎麼寫呢?
一個動畫有12桢意味著要播12次。

int frameIndex = 0; //用來記錄一個動畫的當前桢。
while (true) {
    if (frameIndex == 0) {
        // 畫 |
    } else if (frameIndex == 1) {
        // 畫 |
    } else if (frameIndex == 2) {
        // 畫 |
    } else if (frameIndex == 3) {
        // 畫 \
    } else ...........
    .................... 
  frameIndex ++; //上面的代碼確保每次只畫一桢,這句話在畫完了之後把frame往下推一個。
}

這樣的代碼很麻煩,也肯定不是一個成熟的游戲需要的。

更簡單些,這樣:

while (true) {
    playAnimation();

}

這個playAnimation() 這樣寫:

int frameIndex = 0;
Image[] animationFrames;
//定義一個圖像數組來存儲一個動畫的每一桢圖像。假設已經被裝載好了。假設是上面那幅動畫,這個數組裡面就存了12幅畫。
(實際不是這樣,還要更仔細一些,例如只存二進制數據而不是一個圖像,到了播放時才即時創建一幅出來。而且相同的桢數據不會重復放在裡面。
現在只是舉個比上面的代碼好點兒的例子。)

public void playAnimation() {
    Image currentFrameImage = animationFrames[frameIndex]; //把當前桢的那幅圖給取出來
    if (playAnimation) { //現在假設沒有這個變量,往後看。
        drawImag(currentFrameImage,...);//畫到屏幕上。(代碼沒寫全,drawImage還有很多參數)
        frameIndex ++; // 桢往後推個1。下次畫就是畫下一桢了。
    }

    if (frameIndex > animationFrames.length) {// 如果播完了12桢怎麼辦?自己決定,是重頭畫還是停止。
        //如果重頭畫
        //frameIndex = 0;

        //如果讓這個動畫畫一遍就停下.
        // playAnimation = false;
//現在知道有什麼用了吧?雖然playAnimation還在被一直調用,但已經沒有東西畫出來了。
    }

}

恩, 動畫的播放原理差不多就這樣。

然後再說說詳細說說動畫的組成。

動畫是由一桢一桢的圖像組成。
而每一桢的圖像又是一塊一塊的小圖拼成。

為什麼要這樣做?
一方面,在J2ME程序中,程序+資源包的大小十分受限。
假如做一個小人兒的動畫,就算10桢,就需要10幅畫。
如果再多做幾個小人兒動畫,就是10xN幅畫,太大了。
這樣,就可以把各種各樣小人兒的頭,不同形狀,不同動作,專門做成一整套,一個一個的,或者說看起來一塊一塊的,拼到一個大圖上。
小人兒們的腿,身子,胳膊等等,也都按不同形狀,不同動作等分別做成一整套。

這樣,就可以從這些胳膊腿兒裡面挑一個形狀,挑一個動作,組成一個小人,這就形成了一桢。
不同的形狀,不同的動作的組合可以做很多個不同的動畫,但是資源大小並沒有改變。(不能貼圖,google應該改進.)

另外一方面,碰撞檢測。
在播放動畫的時候,往往需要檢測一個動畫和另一個動畫是否碰撞在一起。
例如,街霸。
那麼檢測碰撞,不是檢測整個一桢的碰撞,而是這一桢中,人的胳膊腿兒等的碰撞。
這樣,把一大塊桢分開成小的模塊,也更合理。
這個組成桢的基本單位,術語稱作"Module"。
在這裡不多說,其實我也說不出啥東西。還是要自己做,自己研究。

還有動畫的應用。
例如我們要播放一個片頭動畫,這很常見。展示我們的logo之類的。
就這樣。
while (true) {
    playAnimation(mylogo);

}

我們要讓主角行走。

while (true) {
    player.setAction(walk); //把動畫封裝在一個player類中。
    player.update(); // 之前玩家已經把動作設置成為walk了。現在來更新這個動作。其實就是動畫的播放

}

public class Player {
    int action;
    public void update() {
        switch (action) {
        case walk:
            playAnimation(walkAnimation); //呵呵,怎麼樣?這就差不多是AI了,只不過這個AI只是會播放動畫
            //再隨便瞎寫幾句
            if (keyPressed(Num4)) {
               //如果按了四鍵,就讓玩家的位置發生變化。相應的,playAnimation裡繪制桢的坐標就發生了變化。
               //這樣看起來,主角就是一邊做walk的動作一邊移動了。呵呵。像真實世界中的。
               posX -= 20; //往左移動。
            }
        break;
        }
    }

}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved