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

手機遊戲開發:拋物線軌跡數學建模與 Canvas 繪製實戰

     編輯:Java 程式設計入門

業務場景

手機遊戲中炮彈/導彈/拋射物軌跡模擬,已知:

  • 發射點 P1(x1, y1)
  • 射程 R(水平飛行距離)
  • 最大高度 H(頂點高度)

假設理想條件(無風阻、重力均勻),軌跡為拋物線,三點確定二次曲線。

數學建模:三點求二次函數系數

三個關鍵點

  • P1(x1, y1) 發射點
  • P2(x1 + R/2, y1 + H) 頂點(最高點,水平中點)
  • P3(x1 + R, y1) 落點(同高度)

建立方程組

a*x1² + b*x1 + c = y1
a*x2² + b*x2 + c = y2
a*x3² + b*x3 + c = y3

求解 a, b, c (克拉默法則/矩陣求逆/消元法)

// 代碼實現示例 (雙精度)
double x1 = ..., y1 = ...;
double x2 = x1 + range/2, y2 = y1 + height;
double x3 = x1 + range, y3 = y1;

double denom = (x1 - x2) * (x1 - x3) * (x2 - x3);
double a = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom;
double b = (x3*x3 * (y1 - y2) + x2*x2 * (y3 - y1) + x1*x1 * (y2 - y3)) / denom;
double c = (x2*x2 * (x3*y1 - x1*y3) + x3*x3 * (x1*y2 - x2*y1) + x1*x1 * (x2*y3 - x3*y2)) / denom;

軌跡點生成與繪製

// 根據 x 計算 y
public int calculateY(int x) {
    return (int) (a * x * x + b * x + c);
}

// 遊戲主循環中繪製
public void paint(Graphics g) {
    // 繪製背景、飛船等...
    for (int x = startX; x <= endX; x += step) {
        int y = calculateY(x);
        g.drawImage(bulletImg, x, y, Graphics.TOP | Graphics.LEFT);
    }
}

完整 MIDP Canvas 實現核心代碼

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.game.*;

public class GameCanvas extends GameCanvas implements Runnable {
    // 遊戲對象
    private Sprite ship;
    private TiledLayer background;
    private Image shipImg, seaImg, bulletImg;
    private BulletManager bullets; // 管理多發炮彈
    
    public GameCanvas() {
        super(true); // 雙緩衝
        // 初始化資源、精靈、圖層...
        new Thread(this).start();
    }
    
    public void run() {
        while (running) {
            // 1. 處理輸入
            int key = getKeyStates();
            if ((key & LEFT_PRESSED) != 0) shipX -= 2;
            if ((key & RIGHT_PRESSED) != 0) shipX += 2;
            if ((key & FIRE_PRESSED) != 0) bullets.fire(shipX, shipY);
            
            // 2. 更新邏輯
            bullets.update(); // 內部按拋物線更新每顆子彈坐標
            background.update();
            
            // 3. 渲染
            Graphics g = getGraphics();
            background.paint(g);
            ship.paint(g);
            bullets.paint(g);
            flushGraphics();
            
            // 4. 幀率控制
            try { Thread.sleep(40); } catch (InterruptedException ignored) {}
        }
    }
}

BulletManager 關鍵邏輯

class BulletManager {
    private static class Bullet {
        int x, y, startX, range, height;
        double a, b, c; // 拋物線系數
        boolean active;
    }
    private Bullet[] bullets = new Bullet[MAX_BULLETS];
    
    public void fire(int sx, int sy) {
        // 找空閒槽位,計算 a,b,c,設置 active=true
    }
    
    public void update() {
        for (Bullet b : bullets) if (b.active) {
            b.x += SPEED_X;
            b.y = (int)(b.a * b.x * b.x + b.b * b.x + b.c);
            if (b.x > b.startX + b.range) b.active = false; // 超出射程回收
        }
    }
    
    public void paint(Graphics g) {
        for (Bullet b : bullets) if (b.active)
            g.drawImage(bulletImg, b.x, b.y, Graphics.TOP | Graphics.LEFT);
    }
}

效果圖展示(文中圖片保留)

效果1 效果2 效果3 效果4 效果5

擴展優化方向

  • 風阻/重力變化:引入物理引擎 (Box2D J2ME 移植版) 或數值積分 (Verlet/Runge-Kutta)
  • 導彈追蹤:每幀重新計算指向目標的拋物線/直線
  • 軌跡預測線:發射前用虛線繪製完整拋物線輔助瞄準
  • 性能優化:定點數替代浮點、預計算查表、減少對象創建(對象池)

總結

拋物線三點建模是 2D 遊戲拋射軌跡的經典數學解法,計算量極小、無需物理引擎、適合 J2ME/早期 Android 等資源受限平台。掌握「三點求系數 → 運行時逐幀求值 → 對象池管理」完整鏈路,可快速實現炮彈、手榴彈、噴泉、噴射等多樣化視覺效果。

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