回合制、益智類可容忍百毫秒延遲;但實時動作遊戲(STG、ACT、格鬥)需 ≥10 FPS、輸入響應 < 100 ms。J2ME 裝置:慢 CPU(50-200 MHz)、無 JIT、小堆(200-500 KB)、無 GPU。每一個 CPU 週期都要算在刀刃上。
paint() 40-60%、gameLoop() 20-30%、其餘 10%鐵律:只優化佔比 > 10% 的熱點,其餘是微優化,收益極低。
| 技術 | 說明 | 收益 |
|---|---|---|
| 空間換時間 | 預計算三角函數、查表法碰撞、查表法隨機數 | CPU ↓ 30-50% |
| 物件池 | 子彈、粒子、敵人複用,消除 GC 尖峰 | GC 暫停 ↓ 90% |
| 狀態機替代多態 | switch-case 替代虛擬呼叫,消除方法分派開銷 | CPU ↓ 10-15% |
| 圖層合併渲染 | 背景靜態圖預合成至單一 Image,每幀僅繪動態層 | 繪圖呼叫 ↓ 50% |
| 固定時間步長 | 邏輯與渲染解耦,避免幀率波動導致物理穿透 | 穩定性 ↑ |
int[] 優於 Vector / ArrayList(無裝箱、連續記憶體)new 在循環內:預分配 int[] buffer = new int[MAX] 重複使用x * 2 → x << 1、x / 2 → x >> 1、x % 16 → x & 0xF// 差:虛擬呼叫
public void update() { move(); checkCollision(); render(); }
// 好:final 方法 + 內聯(ProGuard 會自動內聯 final 私有方法)
final void move() { ... }
final void checkCollision() { ... }
final void render() { ... }
drawImage > drawRGB > fillRect + drawLine(硬體加速可能性遞減)drawString 在遊戲主循環(字體光柵化極慢),改用圖集字體(參考 Article 78370)setClip 限制繪製區域,減少像素填充量int/long 在前,Object 在後(減少對齊填充)static 宣告 → 類載入時分配,避免運行時 OOMSystem.gc() 僅在關卡切換、大量物件釋放後呼叫,平時禁用| 版本 | 100 幀總耗時 (ms) | 平均幀時間 (ms) | 主要優化 |
|---|---|---|---|
| 原始 | 6,407 | 64 | — |
| 物件池 + int[] | 4,210 | 42 | GC 消除 |
| 查表法三角函數 | 3,580 | 36 | CPU ↓ |
| 圖層合併渲染 | 2,950 | 30 | 繪圖呼叫 ↓ |
| 最終版 | 2,410 | 24 | 綜合 |
真機 Motorola i85s:原始 52 秒 → 最終 18 秒(2.9× 加速)。
System.currentTimeMillis() 手動埋點)。sin[360] 佔 1.4 KB,若堆 < 100 KB 需權衡。J2ME 遊戲優化是工程權衡藝術:Profiler 定位熱點 → 高層優化優先 → 低層優化驗證真機 → 保留可讀版。沒有銀彈,只有不斷測試、數據驅動的迭代。記住:**過早優化是萬惡之源,但不優化在 J2ME 上就是死路一條。**