# 08 实体受伤


实体受伤是各类地图中常见的设定,无论是PVP、射击类、闯关类等等地图类型都需要用到

(点击->高清B站视频) (opens new window)



本节所使用的代码如下:

1.用entity.hurt()让玩家进入地图后就受到伤害

console.clear()
world.onPlayerJoin(({ entity }) => {
    entity.enableDamage = true //允许这个实体 受伤/死亡/复活
    entity.hurt(50) //去掉玩家半管血
    console.log('hp:'+entity.hp) //现在受伤后只剩50了
    console.log('maxHp:'+entity.maxHp) //生命值上限, box3里所有实体默认maxHp是100
})


2.恢复玩家血量

console.clear()
world.onPlayerJoin(({ entity }) => {
    entity.enableDamage = true //允许这个实体 受伤/死亡/复活
    entity.hp -= 100 //让玩家受100点伤害当场去世
})

world.onChat(({ entity }) => {
    entity.hp = entity.maxHp * 0.5 //复活至一半最大生命值
})


3.让其他模型实体受到伤害

for (const e of world.querySelectorAll('*')) { //遍历每个实体
    e.enableDamage = true //允许这个实体 受伤/死亡/复活
    e.hurt(50) //把实体打剩半条命
}


4.点击其他实体,让其受到伤害

for (const e of world.querySelectorAll('*')) { //遍历每个实体
    e.enableDamage = true //允许这个实体 受伤/死亡/复活
}
// 利用点击事件对点中的实体造成伤害
world.onClick(({ entity, clicker }) => { //entity是被点击的实体, clicker是点击了这个实体的玩家
    if (entity.isPlayer) { //如果被点击的是个玩家实体
        world.say(`${clicker.player.name} 击中 ${entity.player.name}`) //显示玩家的名字
    } else {
        world.say(`${clicker.player.name} 击中 ${entity.id}`) //显示实体的id
    }

    entity.hurt(20)
})


5.碰到某个特定的方块受到伤害或回血(如岩浆)

// 碰到岩浆受伤, 碰到字母H恢复生命
world.onVoxelContact(({ entity, voxel, x, y, z }) => { //当触碰方块
    if (voxel === voxels.id('lava02')) { //如果方块类型是岩浆
        entity.hurt(20) //受伤
    } else if (voxel === voxels.id('H')) { //如果方块类型是H字母
        entity.hp = entity.maxHp //恢复满血
        voxels.setVoxel(x, y, z, '') //消掉H方块
    }
})


6.触碰实体怪物受到伤害或回血(记得给实体打上相应标签)

for (const e of world.querySelectorAll('*')) { //遍历每个实体
    e.enableDamage = true //允许这个实体 受伤/死亡/复活
    e.collides = true //允许实体被碰撞
    e.gravity = true //开启重力, 这样实体才不会一碰就飘走
}
// 碰到僵尸受伤, 碰到急救包恢复生命
world.onEntityContact(({ entity, other }) => { //other是被触碰的实体
    if (other.hasTag('僵尸')) { //当被碰实体有僵尸标签
        entity.hurt(20) //受伤
    } else if (other.hasTag('急救包')) { //当被碰实体有急救包标签
        entity.hp = entity.maxHp //恢复满血
        other.destroy() // 把急救包从地图删除, destroy()只能删除非玩家实体
    }
})


7.加入不同类型的伤害(触碰伤害和点击伤害)

for (const e of world.querySelectorAll('.僵尸')) { //遍历每个僵尸实体
    e.enableDamage = true //允许这个实体 受伤/死亡/复活
    e.collides = true //允许实体被碰撞
    e.gravity = true //开启重力, 这样实体才不会一碰就飘走
}

world.onPlayerJoin(({ entity }) => {
    entity.enableDamage = true //允许这个实体 受伤/死亡/复活
    entity.id = entity.player.name //喵家名字赋值到id, 以便和其它实体一样可以统一通过entity.id获取名字
})

world.onEntityContact(({ entity, other }) => {
    if (other.hasTag('僵尸')) { //如果被碰实体有僵尸标签
        entity.hurt(30, {
            damageType: '病毒', //伤害类型为病毒
            attacker: other, //告诉引擎攻击者是被碰到的这个实体
        })
    }
})

world.onClick(({ entity, clicker }) => {// entity是被点击的实体, clicker是点击了这个实体的玩家
    entity.hurt(20, {
        damageType: '枪击', //伤害类型为枪击
        attacker: clicker, //告诉引擎攻击者是触发点击的这个玩家实体
    })
})

world.onTakeDamage(({ entity, attacker, damage, damageType }) => { //每次地图里有实体受伤
    world.say(`${attacker.id}${entity.id} 造成${damage}${damageType}伤害`)
})


8.不同伤害导致的game over这样表示

world.onDie(({ entity, attacker, damageType }) => { //每次地图里有实体死亡
    if (entity.isPlayer) { //如果是玩家实体
        if (damageType === '病毒') { //如果是病毒致死
            entity.player.color.set(0, 1, 0) //玩家实体颜色变绿
        }
    } else { //如果非玩家实体
        if (damageType === '枪击') { //如果是枪击致死
            entity.destroy() //从地图上消失
        }
    }
})