# 范围伤害
console.clear()
const mscale = 1 / 16
const n = [-4, -3, -2, -1, 0, 1, 2, 3, 4]
// 生成一堆小人
for (let x of n) {
for (let y of n) {
for (let z of n) {
const e = world.createEntity({
mesh: 'mesh/小人.vb', //地图中需有一个名称为“小人”的模型
fixed: true,
collides: false,
position: [x * 4 + 64, y * 3 + 16, z * 4 + 64],
meshScale: [mscale, mscale, mscale],
})
e.enableDamage = true
e.onDie(() => {
e.destroy()
})
}
}
}
world.onPlayerJoin(({ entity }) => {
entity.enableDamage = true
})
function killZone(pos, radius, fn) { //球状AOE
for (const e of world.querySelectorAll('*')) {//遍历所有实体
const dist = e.position.distance(pos)//计算作用点与当前实体的距离
if (dist <= radius) {//当距离小于等于有效作用半径
fn(e, dist)//传递当前实体和距离到回调函数并执行
}
}
}
async function killBox(pos, size, fn) { //盒状AOE
//搜索包围盒内的所有实体
const entities = world.searchBox({
lo: [pos.x - size, pos.y - size, pos.z - size], //包围盒下边界
hi: [pos.x + size, pos.y + size, pos.z + size], //包围盒上边界
})
for (const e of entities) { //遍历所有找到的实体
fn(e)
}
}
async function makeDamage(e, dmg, color) {
e.hurt(Math.max(1, dmg)) //max用于防止负数伤害
e.meshColor.copy(color) //当前实体变色
await sleep(500)
e.meshColor.set(1, 1, 1, 1) //恢复正常颜色
}
const RED = new Box3RGBAColor(1, 0, 0, 1)
const GREEN = new Box3RGBAColor(0, 1, 0, 1)
const BLUE = new Box3RGBAColor(0, 0, 1, 1)
world.onPress(({ entity, button, raycast }) => {
if (button === Box3ButtonType.CROUCH) { //下蹲键触发自身球状AOE
const range = 8//AOE有效作用半径
killZone(entity.position, range, async (e, dist) => {
if (e === entity) return//如果当前实体是AOE施放者, 就不继续执行, 避免伤到自己
const ratio = (range - dist) / range //计算距离百分比, 离得越近ratio越趋向1, 离得越远ratio越趋向0
makeDamage(e, 100 * ratio, RED)
})
}
else if (button === Box3ButtonType.ACTION0) { //左键触发远距离球状AOE
const range = 8//AOE有效作用半径
killZone(raycast.hitPosition, range, async (e, dist) => {
if (e === entity) return//如果当前实体是AOE施放者, 就不继续执行, 避免伤到自己
const ratio = (range - dist) / range //计算距离百分比, 离得越近ratio越趋向1, 离得越远ratio越趋向0
makeDamage(e, 100 * ratio, GREEN)
})
}
else if (button === Box3ButtonType.ACTION1) { //右键触发远距离盒状AOE
const size = 7 //AOE盒的大小
killBox(raycast.hitPosition, size, (e) => {
if (e === entity) return//如果当前实体是AOE施放者, 就不继续执行, 避免伤到自己
makeDamage(e, 20, BLUE)
})
}
})