猫史档案馆


【API 教程三连更】 吉吉喵化身电工师傅

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


center_image

你知道怎么在岛3上做互动的功能吗?

比如,在哈哈农场的交易员,你按下E(互动键)他就会说话;

在故宫开车里,你碰一下车,就能变身一辆车

...

这些要怎么做呢?

 

这些都会用到【事件】类型的API

什么叫做事件呢?

(看视频找答案)

 

本次教程会学到3个事件API

1. onVoxelContact 触碰方块

2. onInteract 与实体互动

3. onEntityContact 触碰实体

 

学会这3个API,

你就能在岛3做出各种有趣的互动玩法了。

 

请看视频

👇👇👇👇

视频1. 用onVoxelContact触碰方块事件,

做一个欢迎灯

https://www.bilibili.com/video/BV1fi4y1L7gm

center_image

 

视频2. 用onInteract与实体互动事件

做一个电灯开关

https://www.bilibili.com/video/BV1Ft4y1Y7FD

center_image

 

视频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. 电灯开关

center_image

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 // 电梯停止移动
  }
})

 

emotion_编程猫_加油

你学会了吗?

- 本期互动作业- 

1. 拆屋小队

结合onVoxelContact和setVoxel

怎么实现玩家撞毁房子墙壁?

(不能让角色陷进地里)

 

2. 泳池机关

结合教程1的cube函数, 

如何在开灯瞬间同时给别墅门前生成一个泳池?

 

3. 电梯改建

电梯代码目前只能上楼,

怎么能让电梯下降?

(要让玩家出电梯门才能动哟)

 

答案下期揭晓~

emotion_编程猫_紧张

相关文档:

- API文档:https://docs.box3.codemao.cn/

 

加入代码岛3.0官方内测Q喵

官网:box3.codemao.cn

(づ。◕‿‿◕。)づ


回复

上一页第 1 页 / 共 3 页下一页
春絮春絮

沙发

点赞0


评论

认证

。。。。。。。。。。。


阳光的流熔怪Uyt5阳光的流熔怪Uyt5

地板

点赞0


评论


程序侯程序侯

哇塞!捕捉纪念!

点赞0


评论


神岛吉吉喵神岛吉吉喵

萌新集合,哪里没看懂的在这里留言

点赞1


评论

萌新露个头

萌新冒泡


神岛吉吉喵神岛吉吉喵

进阶集合,说说你是怎么理解【事件】的?

emotion_编程猫_紧张

点赞3


评论

就是一个封装函数嘛,花括号里面的就算参数,触发条件已经内置,函数里面就算函数的内容,各个事件都一样,就是触发条件和可用参数不同

吉吉喵在吗,岛3权限审核啊。。。

“事件”这块东西包括玩家动作,触碰东西,互动……简单来说,玩家在地图里的一举一动对于地图而言,都是时刻发生的“事件”(大概是这样……对代码好像不是很来电懵懵的)

吉吉喵!!!!!!!!!!!!!! 为什么漏发我的狼人皮肤!!!!!!!!!!!!!!!!??????? 快发给我!!!!!别人都有了!!!作品:万圣节跑酷

快点给我!!!!!!!!!!!!!!!!!!!!!!!!!!!

监听着地图中的一举一动

事件,英文Event,是地图中一切代码的开始事件,作用吧……相当与if

怎么进不去BOX

哪里进不去

不会观察全部的动作,只会观察预设好的关键事件,比如玩家之间的碰撞、玩家和实体的碰撞、玩家和方块的碰撞等等,就是API文档里面介绍的事件

没毛病

谢谢某吉!学到了

妙啊,支持吉吉

吉吉喵,复制的代码粘不进去

吉吉喵,为啥哈哈农场里的装糖果的南瓜都没了?

我也进不去

就是游戏中发生了什么事,事件发生后就执行下一段代码,一环扣一环

无法粘贴啊!!!

吉吉喵 为什么我做不了地图?我有权限啊?

能不能把所有教程弄在一起,好看

吉吉,我在岛三被天梦莫名其妙的禁言了,没骂人没说脏话,他把我故意禁言了,有啥办法吗

捉!!


高贵的木叶龙A35d高贵的木叶龙A35d

第八

点赞0


评论


该账号已被封禁该账号已被封禁

来了

点赞0


评论


魔以侵心魔以侵心

第九

 

 

点赞0


评论


Architect_海绵Architect_海绵

前排

点赞0


评论


NobelNobel

前排

点赞0


评论


Vicent轩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


评论

优秀, Vincent同学注意到了电梯在上升停下的瞬间会触发不必要的EntityContact事件, 并找到了自己的解决方案

WOW

VIP!!!!!!!!


该账号已被封禁该账号已被封禁

我先回答作业吧

先说最后一个

只需要先了解一个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


评论


高贵的木叶龙A35d高贵的木叶龙A35d

/*作业1*/
world.onVoxelContact(({x,y,z,voxel})=>{
    if(voxel==voxels.id('plank_02')/*换成啥都行 */){
        voxels.setVoxel(x,y,z,'air')
    }
})/*致萌新:把if那行和上面那行删掉,你将会收获皮肤!*/

点赞0


评论


诸沧海诸沧海

前排

点赞0


评论


拾柒丶拾柒丶

emotion_编程猫_加油

点赞0


评论


Chengxuyee_已退Chengxuyee_已退

前排

点赞0


评论


umbrallawwumbrallaww

前排

点赞0


评论


高贵的木叶龙A35d高贵的木叶龙A35d

/*作业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


评论

...危


望_庐山望_庐山

最后一个前排()

点赞0


评论


seven葫中葫seven葫中葫

来晚了(擦汗)

点赞0


评论


隐日青空隐日青空

阁楼还有吗,挤一挤

点赞0


评论


凌_墨水凌_墨水

前排

点赞0


评论


༺༽༾ཊ源代码(养佬中)ཏ༿༼༻༺༽༾ཊ源代码(养佬中)ཏ༿༼༻

前排

点赞0


评论


IaeaIaea

666

点赞0


评论


蒟蒻OIer1048576蒟蒻OIer1048576

后排

点赞0


评论


正在加载中。。正在加载中。。

前排!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

点赞0


评论


哦那咋了哦那咋了

前排

点赞0


评论


指令者指令者

啊啊啊

点赞0


评论


洛亦ly洛亦ly

前排

 

点赞0


评论


蓝冰_E蓝冰_E

前排

点赞0


评论