如何在Phaser 3中从已创建的DOM对象创建Group?
解决Phaser中DOM元素加入物理组的问题
Phaser的Group(包括物理组)不需要依赖预加载阶段的资源key,只要是已创建的Phaser GameObject(比如你这里的DOM Element),都可以直接加入组。以下是具体实现方案:
方案一:先创建DOM元素,再加入物理组
调整代码逻辑,将DOM元素创建移到create阶段(preload适合加载外部资源,而非创建DOM元素),之后创建物理组并添加元素:
preload(){ // 若需提前加载图片,可在此执行: // this.load.image('shouko', '/assets/sprites/shouko.png'); } create(){ // 1. 创建并配置span元素 const span = document.createElement('span'); span.style = `background: url("/assets/sprites/shouko.png"); background-size: cover; width: 60px; height: 60px; font-weight: bold`; // 2. 创建Phaser DOM元素 const element = this.add.dom(400, 300, span); // 3. 为DOM元素添加物理体 this.physics.add.existing(element, false); element.body.setOffset(-(element.displayWidth / 2), -(element.displayHeight / 2)); element.body.setVelocity(100, 200); element.body.setBounce(1, 1); element.body.setCollideWorldBounds(true); // 4. 创建物理组并添加DOM元素 this.domGroup = this.physics.add.group(); this.domGroup.add(element); // 如需添加多个DOM元素,重复1-3步骤后调用this.domGroup.add()即可 }
方案二:创建物理组时批量管理元素
如果需要创建多个同类型DOM元素,可以利用Group的createCallback统一配置物理属性:
create(){ // 1. 创建物理组,配置元素回调 this.domGroup = this.physics.add.group({ createCallback: (item) => { // 统一设置组内所有元素的物理属性 item.body.setOffset(-(item.displayWidth / 2), -(item.displayHeight / 2)); item.body.setVelocity(100, 200); item.body.setBounce(1, 1); item.body.setCollideWorldBounds(true); } }); // 2. 封装DOM元素创建逻辑 const createDomElement = (x, y) => { const span = document.createElement('span'); span.style = `background: url("/assets/sprites/shouko.png"); background-size: cover; width: 60px; height: 60px; font-weight: bold`; const element = this.add.dom(x, y, span); this.physics.add.existing(element, false); this.domGroup.add(element); }; // 创建多个DOM元素 createDomElement(400, 300); createDomElement(500, 300); }
关键说明
- Phaser的Group不强制要求使用预加载的资源key,只要是继承自
GameObject的实例(比如DOMElement)都可以直接加入。 - 确保DOM元素已经通过
this.physics.add.existing()添加了物理体,才能被物理组正确管理。 - 建议将DOM元素的创建逻辑放在
create阶段,符合Phaser的生命周期规范,避免预加载阶段做不必要的DOM操作。
内容的提问来源于stack exchange,提问作者Daniel Castro
相关产品推荐
相关产品推荐

