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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:52:05