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

Phaser中Projectile加入Group后无法移动的问题求助

解决Phaser中Projectile加入物理组后无法移动的问题

问题原因

当你在Projectile构造函数中手动调用scene.physics.add.existing(this)启用物理体,随后再将其加入this.projectiles(physics.add.group()创建的组)时,Phaser会重新初始化该sprite的物理属性,覆盖之前通过physics.moveTo()设置的移动指令,导致projectile停止移动。


修复方案(两种可选)

方案一:移除Projectile构造函数中的物理体手动添加

让物理组自动处理sprite的物理体初始化,避免重复操作:

修改Projectile类:

import Phaser from "../lib/phaser.js";

export default class Projectile extends Phaser.Physics.Arcade.Sprite {
  constructor(scene, position, target) {
    super(scene, position.x, position.y, "basic");
    this.target = target;

    // 移除手动添加物理体的代码,交给组处理
    // scene.physics.add.existing(this);

    scene.add.existing(this);
  }

  static preload(scene) {
    scene.load.image("basic", "../../assets/Projectiles/rocket.png");
  }

  create() {
    // 加入组后,在create方法中设置移动
    const speed = 800;
    this.scene.physics.moveTo(this, this.target.x, this.target.y, speed);
  }

  update() {
    if (
      this.x < 0 ||
      this.x > this.scene.cameras.main.width ||
      this.y < 0 ||
      this.y > this.scene.cameras.main.height
    ) {
      this.destroy();
    }
  }
}

Game场景的shoot方法无需修改,保留this.projectiles.add(this.projectile)即可。


方案二:加入组后重新设置移动指令

如果不想修改Projectile类,可在将projectile加入组后,重新调用physics.moveTo()恢复移动设置:

修改Game场景的shoot方法:

shoot(pointer) {
    const worldX = this.cameras.main.getWorldPoint(pointer.x, pointer.y).x;
    const worldY = this.cameras.main.getWorldPoint(pointer.x, pointer.y).y;

    const diffX = worldX - this.player.x;
    const diffY = worldY - this.player.y;
    const angleRadian = Math.atan2(diffY, diffX);
    const angleDegre = (angleRadian * 180) / Math.PI;

    const offsetX = 40;
    const offsetY = 40;
    const position = {
      x: this.player.x + offsetX * Math.cos(angleRadian),
      y: this.player.y + offsetY * Math.sin(angleRadian),
    };
    const target = { x: worldX, y: worldY };
    const speed = 800;

    this.projectile = new Projectile(this, position, target);
    this.projectile.angle = angleDegre;
    this.projectile.create();
    this.projectiles.add(this.projectile);

    // 重新设置移动,覆盖组初始化时重置的物理属性
    this.physics.moveTo(this.projectile, target.x, target.y, speed);
}

额外优化建议

使用物理组的create方法直接创建sprite,更符合Phaser最佳实践:

shoot(pointer) {
    // ... 位置、角度计算代码不变 ...
    const speed = 800;

    // 直接通过组创建projectile,自动加入物理世界和组
    const projectile = this.projectiles.create(position.x, position.y, "basic");
    projectile.angle = angleDegre;
    projectile.target = target;
    this.physics.moveTo(projectile, target.x, target.y, speed);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:27:02