如何在JavaScript中删除死亡怪物对象?游戏怪物清理问题咨询
解决怪物死亡后彻底删除的问题
你之前的操作没生效,核心原因是只修改了怪物对象的属性或引用,但没把它从管理容器(gameObjects)里移除,也没销毁它的渲染元素。下面是具体的修复方案:
核心思路
要彻底删除怪物,必须完成两件事:
- 销毁怪物的精灵(sprite),让它不再显示在画面上
- 从管理容器中移除该怪物对象,避免后续遍历还能触发它的攻击、渲染逻辑
方案一:继续用gameObjects对象管理怪物
修改Person的attack方法
不用纠结delete target.???,只需要正确更新怪物生命值即可:
attack(target){ while (this.sprite.animationFrameProgress === 8 ){ this.sprite.animationFrameProgress -= 0.5; } if (this.sprite.animationFrameProgress === 0){ target.health -= this.attackPower; } console.log(target.health); }
修改OverworldMap的playerAttackNearestMonster方法
先遍历处理攻击,再统一删除死亡怪物,避免遍历过程中修改gameObjects导致的逻辑异常:
playerAttackNearestMonster() { const player = this.gameObjects.hero; const deadMonsterKeys = []; // 遍历处理攻击,收集死亡怪物的key for (const key in this.gameObjects) { if (key !== 'hero' && this.gameObjects.hasOwnProperty(key)) { const monster = this.gameObjects[key]; const distanceX = Math.abs(monster.x - player.x); const distanceY = Math.abs(monster.y - player.y); if (distanceX <= 16 && distanceY <= 16) { monster.sprite.setAnimation("fighting"); monster.attack(player); if (player.attacking){ player.attack(monster); } // 标记死亡的怪物key if (monster.health <= 0) { deadMonsterKeys.push(key); } } } } // 统一销毁并移除死亡怪物 deadMonsterKeys.forEach(key => { // 销毁精灵(根据你用的渲染引擎调整,比如Phaser的destroy方法) this.gameObjects[key].sprite.destroy(); // 从gameObjects中彻底删除该怪物对象 delete this.gameObjects[key]; }); }
方案二:改用数组管理怪物(更直观)
如果觉得对象遍历和删除麻烦,可以把怪物单独存到数组里,操作更简洁:
初始化时调整怪物存储方式
// OverworldMap类的构造函数中 constructor() { this.gameObjects = { hero: new Person(...) }; // 单独用数组存储所有怪物 this.monsters = [ new Monster({ x: utils.withGrid(7), y: utils.withGrid(8), pixelSize: 32, health : 50, attackPower : 15, animations : { "monster" : [[0,0], [1,0],[2,0], [3,0]], "monster-left" : [[0,5], [1,5],[2,5], [3,5]], "monsterWalk-down" : [[0,1], [1,1],[2,1], [3,1],[4,1], [5,1]], "monsterWalk-up" : [[0,1], [1,1],[2,1], [3,1],[4,1], [5,1]], "monsterWalk-right" : [[0,1], [1,1],[2,1], [3,1],[4,1], [5,1]], "monsterWalk-left" : [[0,6], [1,6],[2,6], [3,6],[4,6], [5,6]], }, src: "/images/characters/monsters/slime.png" }) // 其他怪物直接push到数组中 ]; }
修改攻击方法用数组过滤删除
playerAttackNearestMonster() { const player = this.gameObjects.hero; // 用filter过滤掉死亡怪物,同时处理攻击逻辑 this.monsters = this.monsters.filter(monster => { const distanceX = Math.abs(monster.x - player.x); const distanceY = Math.abs(monster.y - player.y); if (distanceX <= 16 && distanceY <= 16) { monster.sprite.setAnimation("fighting"); monster.attack(player); if (player.attacking){ player.attack(monster); } } // 怪物存活则保留,死亡则销毁精灵并过滤 if (monster.health <= 0) { monster.sprite.destroy(); return false; } return true; }); }
为什么之前的操作没生效?
- 把对象置为
null:只是让当前变量不再指向怪物对象,但gameObjects里还存着引用,怪物依然会被遍历和渲染。 delete target.???:只是删除怪物对象的某个属性,对象本身还存在于gameObjects中,依然会参与后续逻辑。
内容的提问来源于stack exchange,提问作者Legend
相关产品推荐
相关产品推荐

