首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 遊戲教學 (五):動畫系統核心設計與模組化合成

     編輯:J2ME

動畫播放基本原理

動畫由離散幀組成,連續播放產生動態視覺。每幀在遊戲迴路中繪製一次。

速度控制:若不控制,快手機播放過快、慢手機過慢。解決方案:鎖定遊戲 FPS (教學二),使單幀時間固定,動畫在所有裝置速度一致。

幀索引播放器 (基礎版)

int frameIndex = 0;
Image[] animFrames = new Image[12]; // 預載 12 幀圖片

public void playAnimation() {
    Image current = animFrames[frameIndex];
    drawImage(current, x, y); // 繪製到螢幕
    frameIndex++;
    if (frameIndex >= animFrames.length) {
        frameIndex = 0; // 循環播放
        // 或 frameIndex = animFrames.length - 1; // 停在最後一幀
    }
}

進階:幀率獨立的動畫速度控制

若遊戲 FPS=20,動畫想每秒播 10 幀,需每 2 遊戲幀推進 1 動畫幀。

int animFrame = 0;
int animDelay = 2; // 每 2 遊戲幀換一次動畫幀
int animCounter = 0;

public void updateAnimation() {
    if (++animCounter >= animDelay) {
        animCounter = 0;
        animFrame = (animFrame + 1) % animFrames.length;
    }
    drawImage(animFrames[animFrame], x, y);
}

動畫資源組織:模組化合成 (Module System)

為什麼要拆分模組?

  1. 記憶體極限:J2ME JAR 體積限制 (通常 64KB~200KB)。完整角色動畫若每幀存全身圖,幾組動作即爆倉。
  2. 組合靈活:將角色拆解為 頭、軀幹、左臂、右臂、左腿、右腿 等模組,每模組獨立動作序列。跑步 = 腿部跑步動畫 + 手臂擺動動畫 + 身體微晃動畫。
  3. 碰撞精度:碰撞檢測針對具體肢體 (如拳頭、腳) 而非整體包圍盒,拳打腳踢才真實。

模組資料結構

class AnimModule {
    Image[] frames;      // 該模組的動畫幀陣列
    int frameIndex;      // 當前幀
    int delay;           // 幀延遲
    int counter;         // 計數器
    int xOffset, yOffset; // 相對角色原點偏移
}

class Character {
    AnimModule head, body, leftArm, rightArm, leftLeg, rightLeg;
    int x, y; // 角色世界座標

    void update() {
        head.update(); body.update(); // ... 更新各模組幀索引
    }
    void draw(Graphics g) {
        // 依繪製順序 (如腳→身→手→頭) 繪製各模組
        leftLeg.draw(g, x, y);
        rightLeg.draw(g, x, y);
        body.draw(g, x, y);
        leftArm.draw(g, x, y);
        rightArm.draw(g, x, y);
        head.draw(g, x, y);
    }
}

圖集打包

所有模組幀圖打包成單一大圖 (Texture Atlas),載入後用 Image.createImage(src, x, y, w, h, transform) 切割,或直接由 Sprite/TiledLayer 管理。

動畫系統應用場景

1. 片頭 Logo 動畫

while (state == STATE_LOGO) {
    logoAnimation.update();
    logoAnimation.draw(g);
    if (logoAnimation.isFinished()) state = STATE_MENU;
}

2. 主角行走

// 遊戲迴路
player.setAction(ACTION_WALK);
player.update(); // 內部播放走路動畫模組

// 輸入控制位移
if (keyHeld(GAME_LEFT)) { player.x -= 2; player.setFlip(true); }
if (keyHeld(GAME_RIGHT)) { player.x += 2; player.setFlip(false); }

// 更新時同步動畫與位移
// 走路動畫模組的腿部位移量需與 player.x 速度匹配,防止滑步 (參考教學一步長算法)

3. 簡易 AI 行為樹雛形

class Enemy {
    int state = STATE_PATROL;
    void update() {
        switch (state) {
            case STATE_PATROL:
                playAnimation(walkAnim);
                movePatrol();
                if (seePlayer()) state = STATE_CHASE;
                break;
            case STATE_CHASE:
                playAnimation(runAnim);
                moveTowardPlayer();
                if (distance < ATTACK_RANGE) state = STATE_ATTACK;
                break;
            case STATE_ATTACK:
                playAnimation(attackAnim);
                if (animFinished()) state = STATE_CHASE;
                break;
        }
    }
}

總結

  • 動畫 = 幀陣列 + 幀索引 + 速度控制 (幀延遲計數器)。
  • 模組化合成是 J2ME 記憶體受限環境下的必然選擇,兼顧體積、靈活度與碰撞精度。
  • 將動畫封裝於物件 (Player/Enemy),遊戲迴路僅呼叫 update()/draw(),職責清晰。
  • 下一步:碰撞檢測系統、場景管理、存檔系統。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved