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

Java 2D 動畫:基於無損圖像的路徑控制實戰

     編輯:Java 相關知識

核心課題

2D 動畫中,物件需沿預定義軌跡移動。需解決:

  1. 如何定義控制路徑?
  2. 如何驅動物件沿路徑運動?

本文採用無損圖像 + Swing + 自定義動畫引擎方案。

無損圖像優勢

  • 像素級精確,無壓縮失真(BMP、PNG)。
  • 可用繪圖工具可視化編輯路徑,所見即所得。
  • 顏色編碼行為,支援多層疊加、位掩碼擴展。

案例:火災逃生模擬

背景圖與控制路徑圖層疊加

背景圖部分 控制路徑部分 疊加效果

顏色-行為映射表

顏色 (RGB)行為常量含義
白 (255,255,255)STATE_NONE無映射/可通行區域
黑 (0,0,0)STATE_HALLWAY走廊,沿當前方向前進
綠 (0,255,0)STATE_START起點
紅 (200,0,0)STATE_EXIT出口
紅 (255,0,0)STATE_HINT方向提示(優先轉向)
藍 (0,0,255)STATE_INTERSECTION十字路口

圖像處理核心代碼

void processControl(Image img, int x, int y, int w, int h) {
    int[] pmap = new int[w * h];
    PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pmap, 0, w);
    pg.grabPixels();
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < pmap.length; i++) {
        int r = (pmap[i] >> 16) & 0xff;
        int g = (pmap[i] >> 8) & 0xff;
        int b = pmap[i] & 0xff;
        if (r == 255 && g == 255 && b == 255) continue; // STATE_NONE 不入表
        else if (r == 0 && g == 0 && b == 0) map.put(i, STATE_HALLWAY);
        else if (r == 0 && g == 255 && b == 0) map.put(i, STATE_START);
        else if (r == 200 && g == 0 && b == 0) map.put(i, STATE_EXIT);
        else if (r == 255 && g == 0 && b == 0) map.put(i, STATE_HINT);
        else if (r == 0 && g == 0 && b == 255) map.put(i, STATE_INTERSECTION);
    }
    // map 供運行時查詢 stateAt(x,y)
}

動畫引擎設計

實體接口

interface Entity {
    void addToPanel(JPanel panel, boolean shared);
    void updateTick(); // 每幀調用
}

Person 移動邏輯(節選)

public void updateTick() {
    // 處理延遲啟動、停留點
    Point2D loc = getPosition();
    int x = (int)loc.getX(), y = (int)loc.getY();
    switch (manager.stateAt(x, y)) {
        case STATE_EXIT: atExit = true; break;
        case STATE_START:
        case STATE_INTERSECTION:
            // 掃描四鄰域尋找 HINT 或可通行方向
            // 設定方向 DIR_NORTH/EAST/SOUTH/WEST
        case STATE_HALLWAY:
        case STATE_HINT:
            // 按方向移動一步,若撞牆則嘗試轉向
            setNextPoint(new Point(x, y));
    }
}

幀渲染循環

public void prepareNextFrame(boolean update, boolean shared) {
    if (update) manager.moveEntities();
    mainPanel.removeAll();
    for (Person p : manager.getPeople()) p.addToPanel(mainPanel, shared);
    for (Entity e : manager.getEntities()) e.addToPanel(mainPanel, shared);
}

public void runUpdates(int delay) {
    new Timer(true).scheduleAtFixedRate(new TimerTask() {
        public void run() {
            SwingUtilities.invokeLater(() -> { prepareNextFrame(true, true); repaint(); });
        }
    }, 0, delay);
}

進階擴展

  • 顏色範圍匹配:降低繪圖精度要求。
  • 多層疊加路徑:RGB 三通道各自編碼獨立路徑,交疊處混色(如黃=紅+綠)。
  • 位掩碼模式:32 位顏色可編碼 32 種獨立狀態。
  • 歷史軌跡:Person 留下漸變殘影,增強視覺效果。

完整代碼下載

j-animat-source.zip

總結

無損圖像作為控制路徑載體,結合 Swing 輕量級組件與定時器驅動,實現了直觀、可擴展的 2D 動畫框架。適合遊戲原型、模擬演示、教學演示等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved