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
相关产品推荐
相关产品推荐

