You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phaser3 2D游戏炮弹抛物线射击实现问题求助

解决Phaser3中炮弹抛物线轨迹异常问题

问题原因分析

你当前的Phaser3代码通过固定速度值手动控制位置,还在达到阈值后反转竖直方向速度,这种逻辑不符合抛物线运动规律——真实抛物线中,水平方向速度恒定,竖直方向受重力持续加速(速度线性变化),或直接遵循二次函数位置关系(如你Unity代码中的实现),因此导致轨迹出现异常突变。

解决方案一:利用Phaser物理引擎实现(推荐)

Phaser的Arcade物理引擎已内置重力和速度处理,能自动生成自然的抛物线轨迹,无需手动计算位置:

import { ActorProps, ICollectable, IDieable, IMoveable } from "@games/common/interfaces";
import { Actor } from "@games/common/objects";

export default class Cannon extends Actor implements IMoveable, IDieable, ICollectable {
  declare body: Phaser.Physics.Arcade.Body;

  private isMoving: boolean;

  constructor(props: ActorProps) {
    super(props);
    this.scene.physics.add.existing(this);
    
    // 开启竖直方向重力(Phaser中y轴向下为正,重力值为正代表向下加速)
    this.body.setGravityY(300);
    // 设置初始速度:水平向左100,竖直向上200(负号对应Phaser中向上的方向)
    this.body.setVelocity(-100, -200);
    
    this.isMoving = true;
  }

  update(time: number, delta: number): void {
    if (this.isMoving) {
      // 自定义停止条件:比如炮弹回到初始高度以下时停止
      if (this.y >= this.y + 500) {
        this.isMoving = false;
        this.body.setVelocity(0, 0);
      }
    }
  }

  die(): void {}
  move(): void {}
  collect(...props: any[]): void {}
}

解决方案二:手动实现Unity式抛物线公式

如果需要完全自定义轨迹逻辑,可复刻你Unity中的二次函数计算方式:

import { ActorProps, ICollectable, IDieable, IMoveable } from "@games/common/interfaces";
import { Actor } from "@games/common/objects";

export default class Cannon extends Actor implements IMoveable, IDieable, ICollectable {
  declare body: Phaser.Physics.Arcade.Body;

  private currentX: number;
  private a: number = 0.001; // 抛物线弯曲系数,需根据游戏缩放调整(Phaser y轴向下,符号与Unity相反)
  private b: number = 0.5;    // 轨迹倾斜系数
  private c: number;          // 初始y坐标
  private speed: number = 100; // 水平移动速度

  constructor(props: ActorProps) {
    super(props);
    this.scene.physics.add.existing(this);
    this.body.setAllowGravity(false);

    this.currentX = this.x;
    this.c = this.y; // 初始位置作为抛物线常数项
  }

  update(time: number, delta: number): void {
    // 更新水平位置(向左移动)
    this.currentX -= this.speed * (delta / 1000);
    
    // 用二次函数计算竖直位置:y = a*(偏移量)^2 + b*(偏移量) + 初始y
    const offsetX = this.x - this.currentX;
    this.y = this.a * offsetX * offsetX + this.b * offsetX + this.c;

    // 自定义停止条件:比如向左移动500单位后停止
    if (this.currentX <= this.x - 500) {
      this.currentX = this.x - 500;
    }
  }

  die(): void {}
  move(): void {}
  collect(...props: any[]): void {}
}

说明

  • 方案一依赖Phaser物理引擎,自动处理时间差、加速度等细节,还能无缝对接碰撞检测,稳定性更高。
  • 方案二完全手动控制轨迹,适合需要高度自定义抛物线形状的场景,需调整a、b、speed等参数匹配预期效果。

内容的提问来源于stack exchange,提问作者yunusemre agdin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:45:56