用户:
神岛吉吉喵查看:39 回复:87 评论:39 创建时间:2020-11-29T17:32:18

你知道怎么在岛3上做互动的功能吗?
比如,在哈哈农场的交易员,你按下E(互动键)他就会说话;
在故宫开车里,你碰一下车,就能变身一辆车
...
这些要怎么做呢?
这些都会用到【事件】类型的API
什么叫做事件呢?
(看视频找答案)
本次教程会学到3个事件API
1. onVoxelContact 触碰方块
2. onInteract 与实体互动
3. onEntityContact 触碰实体
学会这3个API,
你就能在岛3做出各种有趣的互动玩法了。
请看视频
👇👇👇👇
视频1. 用onVoxelContact触碰方块事件,
做一个欢迎灯
https://www.bilibili.com/video/BV1fi4y1L7gm

视频2. 用onInteract与实体互动事件
做一个电灯开关
https://www.bilibili.com/video/BV1Ft4y1Y7FD

视频3. 用onEntityContact触碰实体事件,
做一台升降电梯
https://www.bilibili.com/video/BV1Ft4y1Y7FD?p=2
视频4:建造一栋漂亮别墅
(美术喵特别献上)
https://www.bilibili.com/video/BV1fi4y1L7gm?p=2
本次教程所用到的代码
1. 欢迎回家
world.onVoxelContact(({ x, y, z, voxel }) => {
const voxelName = voxels.name(voxel); // 将方块id转换名称
if (voxelName === 'board5'){ // 如果方块名称是 5号木板
voxels.setVoxel(46, 11, 52, 'lantern_02'); // 在门口顶部生成一个灯箱
const meshScale = 1/16 //默认模型方块大小倍数为地图方块的1/16
const man = world.createEntity({
mesh:'mesh/人物.vb',
position:[44, 14, 52],
meshScale:[meshScale,meshScale,meshScale],//xyz放大倍数
fixed:true,//固定
});
man.say('欢迎回家')
world.sound('audio/欢迎回家.mp3')
}
});
2. 电灯开关

const lampSwitch = world.querySelector('#灯开关-1') // 用查看实体面板获得开关的实体名, 通过实体名查询得到开关实体。注意查询实体名要前置#号
lampSwitch.enableInteract = true // 允许灯开关被玩家触发交互
lampSwitch.interactRadius = 2 // 交互半径
lampSwitch.interactHint = lampSwitch.id // 交互提示文本内容改为实体名字
lampSwitch.interactColor = new Box3RGBColor(0,1,0) // 交互提示文本绿色
lampSwitch.onInteract(()=>{ // 在游戏中走近开关按E键触发
lampSwitch.meshOrientation = lampSwitch.meshOrientation.rotateZ(Math.PI) // 开关实体旋转180度(PI表示180度), 模拟开关上下切换
lampSwitch.sound('audio/开关灯声音.mp3') // 添加开关灯的音效
floor1ToggleLamps() // 反复开关1楼灯光
})
let floor1LampIsOn = true // 1楼灯的开关状态
function floor1ToggleLamps() { // 定义 反复开关1楼灯光 的函数
if(floor1LampIsOn){
// 换成 地砖方块模拟关灯
voxels.setVoxel(37,12,喵,'carpet_07')
voxels.setVoxel(37,12,59,'carpet_07')
voxels.setVoxel(28,12,65,'carpet_07')
voxels.setVoxel(28,12,59,'carpet_07')
}else{
// 换成 灯箱方块模拟开灯
voxels.setVoxel(37,12,喵,'lantern_01')
voxels.setVoxel(37,12,59,'lantern_01')
voxels.setVoxel(28,12,65,'lantern_01')
voxels.setVoxel(28,12,59,'lantern_01')
}
floor1LampIsOn = !floor1LampIsOn // 反复反转 开关状态
}
world.placeVoxelSound = '' // 关掉方块替换时的默认声音
3. 升降电梯
const elevator = world.querySelector('#电梯地板-1') // 获取电梯地板实体
elevator.collides = true // 电梯开启碰撞检测
elevator.fixed = true // 电梯不受外力影响
world.onEntityContact(({entity, other})=>{ // 实时监测整个世界的实体碰撞事件。entity指被碰撞的实体, other则是主动撞过来的实体
if(entity.id=='电梯地板-1' && other.isPlayer){ // 如果 玩家踏上了电梯
if(entity.position.y<14){ // 如果玩家y低于2楼地板, 则判定玩家在1楼
entity.velocity.y = 0.1 // 电梯持续上移
world.say(other.player.name+' 坐电梯上楼')
}
}
})
world.onTick(()=>{ // 实时检测电梯位置, 进行检测是否到达1楼或2楼
if(elevator.position.y>14){ // 如果电梯y坐标高于2楼的地板, 电梯到达2楼
elevator.position.y = 14 // 复位到2楼的准确位置
elevator.velocity.y = 0 // 电梯停止移动
}
})

你学会了吗?
- 本期互动作业-
1. 拆屋小队
结合onVoxelContact和setVoxel
怎么实现玩家撞毁房子墙壁?
(不能让角色陷进地里)
2. 泳池机关
结合教程1的cube函数,
如何在开灯瞬间同时给别墅门前生成一个泳池?
3. 电梯改建
电梯代码目前只能上楼,
怎么能让电梯下降?
(要让玩家出电梯门才能动哟)
答案下期揭晓~

相关文档:
- API文档:https://docs.box3.codemao.cn/
加入代码岛3.0官方内测Q喵
(づ。◕‿‿◕。)づ
Vicent轩电梯改造作业:
const elevator = world.querySelector('#电梯地板-1') // 获取电梯地板实体
move = 0 //用于判断电梯是否正在移动的变量
elevator.collides = true // 电梯开启碰撞检测
elevator.fixed = true // 电梯不受外力影响
world.onEntityContact(({entity, other})=>{ // 实时监测整个世界的实体碰撞事件。entity指被碰撞的实体, other则是主动撞过来的实体
if (move == 0){ //避免重复引发事件带来的电梯鬼畜
if (entity.id=='电梯地板-1' && other.isPlayer){ // 如果 玩家踏上了电梯
if (elevator.position.y<=9){ // 如果电梯y低于2楼地板, 则判定玩家在1楼
entity.velocity.y = 0.1 // 电梯持续上移
world.say(other.player.name+' 坐电梯上楼')
move = 1 //设置值为1,表示电梯开始移动
}else{
entity.velocity.y = -0.1 // 电梯持续下移
world.say(other.player.name+' 坐电梯下楼')
move = 1 //设置值为1,表示电梯开始移动
}
}
}
})
world.onTick(async()=>{ // 实时检测电梯位置, 进行检测是否到达1楼或2楼
if (elevator.position.y>14){ // 如果电梯y坐标高于2楼的地板, 电梯到达2楼
elevator.position.y = 14 // 复位到2楼的准确位置
elevator.velocity.y = 0 // 电梯停止移动
await sleep(1000) //等待1秒,避免电梯停止时玩家弹起再次与电梯发生碰撞让电梯下行
move = 0 //设置为0,表示电梯停止移动
}
if (elevator.position.y<9){ // 如果电梯y坐标低于1楼的地板, 电梯到达1楼
elevator.position.y = 9 // 复位到1楼的准确位置
elevator.velocity.y = 0 // 电梯停止移动
await sleep(1000) //等待1秒,避免电梯停止时玩家弹起再次与电梯发生碰撞让电梯上行
move = 0 //设置为0,表示电梯停止移动
}
})
//作者:技术喵-Vicent轩
//https://www.bilibili.com/read/cv8568142?//spm_id_from=333.788.b_636f6d6d656e74.41
//出处: bilibili点赞0
评论
该账号已被封禁我先回答作业吧
先说最后一个
只需要先了解一个API:
entity.onEntitySeparate当实体停止触碰另一个实体的时候触发
下降的话就用它好了
然后第一个的话是要加一个IF
如果碰到的方块的Y坐标>地面高度就破坏
第二个可以加一个触发
然后用for(i=0;i<长方形水池的长;i++){for(a=0;a<高;a++){for(x=0;x<长方形水池的宽;x++){voxels.setVoxel(i,a,x,'water')}}}
即可
点赞0
评论
/*作业1*/
world.onVoxelContact(({x,y,z,voxel})=>{
if(voxel==voxels.id('plank_02')/*换成啥都行 */){
voxels.setVoxel(x,y,z,'air')
}
})/*致萌新:把if那行和上面那行删掉,你将会收获皮肤!*/点赞0
评论
/*作业2*/
//为了方便起见就改一个函数
function floor1ToggleLamps() { // 定义 反复开关世界大水 的函数(doge)
if(floor1LampIsOn){
// 换成 水方块模拟发大水了(doge)
for(let i=0;i<128;i++){
for(let j=0;j<128;j++){
for(let k=0;k<128;k++){
voxels.setVoxel(i,j,k,'water')
}
}
}
}else{
// 换成 空气方块模拟大水退了了(doge)
for(let i=0;i<128;i++){
for(let j=0;j<128;j++){
for(let k=0;k<128;k++){
voxels.setVoxel(i,j,k,'air')
}
}
}
}
floor1LampIsOn = !floor1LampIsOn // 反复反转 开关状态
}
/*致萌新:把第一个if下面直到else的代码复制一下,在非运行状态点一下右上的爬虫粘贴进去,然后按下回车,你就有很多皮肤了!*/点赞0
评论