用户:
神岛吉吉喵查看:42 回复:25 评论:42 创建时间:2021-05-18T10:28:12

AOE,强力有效的范围性技能
能够作用于多个目标
是游戏中居家旅行打架必备之技能
今天喵师傅就传你这招!
https://www.bilibili.com/video/BV1W54y1L7VD
所需代码:
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 + 喵, y * 3 + 16, z * 4 + 喵],
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)
})
}
})
学会了这个技能
无论是法师还是奶妈
你想要的职业都能实现!

开发API文档:https://docs.box3.codemao.cn/
加入代码岛3.0官方内测Q喵
下面的二维码会扫出来什么呢?( =•ω•= )m

聪明的编程猫@飞熊jSrt *本代码实现的功能: 1.僵尸追杀玩家,并会对玩家造成伤害 2.玩家可以点击僵尸进行反击 3.玩家喵三秒后在空中随机的地点复活 4.僵尸会复活!!! 使用说明: 请先在模型库中搜索一个叫做“僵尸"的模型,并放进地图里!不然会出错 */ constMeshScale=[0.0625,0.0625,0.0625] functionspawn(){//把生成僵尸的代码封装成函数 conste=world.createEntity({ mesh:'mesh/僵尸.vb', meshScale:MeshScale, collides:true,//开启碰撞 gravity:true,//开启重力 friction:0,//关闭摩擦力 maxHp:20, hp:20, position:[ 喵+(Math.random()-0.5)*60, 24+Math.random()*50, 喵+(Math.random()-0.5)*60, ], }); e.addTag('僵尸'); e.enableDamage=true; e.onVoxelContact(({x,y,z,voxel})=>{ e.velocity.y=0.3+Math.random()*0.7//碰到砖块就跳一下 }) e.onEntityContact(({other})=>{ if(other.isPlayer){//僵尸撞到玩家 other.hurt(5)//对玩家造成伤害 } }) e.onDie(()=>{ e.destroy()//僵尸喵掉,实体消失!谢谢@1232RvE反馈 for(leti=0;i<1;i++){//僵尸复活 spawn() } varfi=fi-1 vara=a+1 world.say("消耗了一发子弹") }) } for(leti=0;i<90;i++){//开局生成一堆僵尸 spawn() } constQuat=newBox3Quaternion(0,0,0,1)//box引擎默认的旋转朝向 letallPlayers=[]//所有玩家 letallZombies=[]//所有僵尸 world.onTick(async({tick})=>{//每秒16个tick if(tick%16===0){//每16个tick运行一次,而不是每个tick都运行,节省性能 allPlayers=world.querySelectorAll('player') allZombies=world.querySelectorAll('.僵尸') } allZombies.forEach(async(e)=>{ letzomPos=e.position if(tick%11===0){//每11个tick运行一次,而不是每个tick都运行,节省性能 lettarget=allPlayers.sort((a,b)=>{//僵尸寻找距离最近的玩家 returna.position.distance(zomPos)-b.position.distance(zomPos) })[0] if(target){//地图如果还有玩家 e.target=target//让僵尸记住要追杀的玩家 } } if(e.target&&!e.target.destroyed){//如果要追杀的玩家还没有离开地图 vardirection=e.target.position.sub(zomPos);//僵尸往玩家的方向矢量 vardist=direction.mag()//矢量的长度 varspeed=0.2+Math.random()*0.3//速度0.2~0.5随机 e.velocity.x=direction.x*speed/dist e.velocity.z=direction.z*speed/dist //让僵尸面向自己的前进方向 varorientation=Quat.rotateY(Math.atan2(e.velocity.z,e.velocity.x)) e.meshOrientation.copy(orientation) } }) }) world.onPlayerJoin(({entity})=>{ entity.enableDamage=true; entity.onDie(async()=>{ world.say(`${entity.player.name}被袭击身亡,3秒后复活`) awaitsleep(3000) entity.player.forceRespawn(); }) }) world.onClick(({entity})=>{ if(fi>1){ entity.hurt(15) //被点中的实体会掉血 } else{ world.say("没子弹了") } }) world.onPlayerJoin(({entity})=>{ entity.player.addWearable({ bodyPart:Box3BodyPart.HEAD, mesh:'mesh/三级盔.vb', orientation:newBox3Quaternion(0,1,0,0).rotateY(-Math.PI/2), offset:newBox3Vector3(0,0.4,0.1), }); entity.player.addWearable({ bodyPart:Box3BodyPart.RIGHT_HAND, mesh:'mesh/喵[精美].vb', orientation:newBox3Quaternion(0,1,0,0).rotateY(Math.PI), offset:newBox3Vector3(-0.05,-0.1,0.5), scale:Box3Vector3=newBox3Vector3(0.3,0.3,0.3), }); });
点赞0
评论
聪明的编程猫*本代码实现的功能: 1.僵尸追杀玩家,并会对玩家造成伤害 2.玩家可以点击僵尸进行反击 3.玩家喵三秒后在空中随机的地点复活 4.僵尸会复活!!! 使用说明: 请先在模型库中搜索一个叫做“僵尸"的模型,并放进地图里!不然会出错 */ constMeshScale=[0.0625,0.0625,0.0625] functionspawn(){//把生成僵尸的代码封装成函数 conste=world.createEntity({ mesh:'mesh/僵尸.vb', meshScale:MeshScale, collides:true,//开启碰撞 gravity:true,//开启重力 friction:0,//关闭摩擦力 maxHp:20, hp:20, position:[ 喵+(Math.random()-0.5)*60, 24+Math.random()*50, 喵+(Math.random()-0.5)*60, ], }); e.addTag('僵尸'); e.enableDamage=true; e.onVoxelContact(({x,y,z,voxel})=>{ e.velocity.y=0.3+Math.random()*0.7//碰到砖块就跳一下 }) e.onEntityContact(({other})=>{ if(other.isPlayer){//僵尸撞到玩家 other.hurt(5)//对玩家造成伤害 } }) e.onDie(()=>{ e.destroy()//僵尸喵掉,实体消失!谢谢@1232RvE反馈 for(leti=0;i<1;i++){//僵尸复活 spawn() } varfi=fi-1 vara=a+1 world.say("消耗了一发子弹") }) } for(leti=0;i<90;i++){//开局生成一堆僵尸 spawn() } constQuat=newBox3Quaternion(0,0,0,1)//box引擎默认的旋转朝向 letallPlayers=[]//所有玩家 letallZombies=[]//所有僵尸 world.onTick(async({tick})=>{//每秒16个tick if(tick%16===0){//每16个tick运行一次,而不是每个tick都运行,节省性能 allPlayers=world.querySelectorAll('player') allZombies=world.querySelectorAll('.僵尸') } allZombies.forEach(async(e)=>{ letzomPos=e.position if(tick%11===0){//每11个tick运行一次,而不是每个tick都运行,节省性能 lettarget=allPlayers.sort((a,b)=>{//僵尸寻找距离最近的玩家 returna.position.distance(zomPos)-b.position.distance(zomPos) })[0] if(target){//地图如果还有玩家 e.target=target//让僵尸记住要追杀的玩家 } } if(e.target&&!e.target.destroyed){//如果要追杀的玩家还没有离开地图 vardirection=e.target.position.sub(zomPos);//僵尸往玩家的方向矢量 vardist=direction.mag()//矢量的长度 varspeed=0.2+Math.random()*0.3//速度0.2~0.5随机 e.velocity.x=direction.x*speed/dist e.velocity.z=direction.z*speed/dist //让僵尸面向自己的前进方向 varorientation=Quat.rotateY(Math.atan2(e.velocity.z,e.velocity.x)) e.meshOrientation.copy(orientation) } }) }) world.onPlayerJoin(({entity})=>{ entity.enableDamage=true; entity.onDie(async()=>{ world.say(`${entity.player.name}被袭击身亡,3秒后复活`) awaitsleep(3000) entity.player.forceRespawn(); }) }) world.onClick(({entity})=>{ if(fi>1){ entity.hurt(15) //被点中的实体会掉血 } else{ world.say("没子弹了") } }) world.onPlayerJoin(({entity})=>{ entity.player.addWearable({ bodyPart:Box3BodyPart.HEAD, mesh:'mesh/三级盔.vb', orientation:newBox3Quaternion(0,1,0,0).rotateY(-Math.PI/2), offset:newBox3Vector3(0,0.4,0.1), }); entity.player.addWearable({ bodyPart:Box3BodyPart.RIGHT_HAND, mesh:'mesh/喵[精美].vb', orientation:newBox3Quaternion(0,1,0,0).rotateY(Math.PI), offset:newBox3Vector3(-0.05,-0.1,0.5), scale:Box3Vector3=newBox3Vector3(0.3,0.3,0.3), }); });
点赞2
评论
所以这串代码哪里错了 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) var aoe = 1 world.onPlayerJoin(({ entity }) => { entity.player.onPress(async ({ button }) => { if (button == Box3ButtonType.ACTION1) { let sel = await entity.player.dialog({ type: Box3DialogType.SELECT, content: '选择AOE', options: ['自身', '球状', '盒子',] })
if(sel.value === '自身'){ aoe = 1 } if(sel.value === '球状'){ aoe = 2 } else{ aoe = 3 } }
else if(button == Box3ButtonType.ACTION0) { if(aoe === 1){ 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(aoe === 2){ 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{ const size = 7 //AOE盒的大小 killBox(raycast.hitPosition, size, (e) => { if (e === entity) return//如果当前实体是AOE施放者, 就不继续执行, 避免伤到自己 makeDamage(e, 20, BLUE) }) } } }) })
点赞0
评论