手機遊戲中炮彈/導彈/拋射物軌跡模擬,已知:
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
// 代碼實現示例 (雙精度)
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);
}
}
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) {}
}
}
}
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);
}
}

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