UID 82897 性别 保密 经验 EP 铁粒 粒 回帖 0 主题 精华 在线时间 小时 注册时间 2021-7-23 最后登录 1970-1-1
本帖最后由 Cat_Anchor 于 2023-8-20 11:08 编辑 前言
上期,我们实现了顺序标记。现在我们就要完成主要的部分了。开始缓动
现在,我们来新增一个事件:start_moving。当我们使用“开始播放”按钮时,实际上是触发了这个事件。
首先,为了实现可切换的速度和缓动类型,需要用tag进行检测。不可避免地,这里需要一些穷举。start_moving首先会触发一个函数,用于检测当前选择的速度。"start_moving": { "run_command": { "command": [ "function moving_speed", //检测速度 "execute if entity @p[tag=!show_mark] run effect @e[type=supplementary:moving_mark] invisibility 8 255 true", //隐藏标记功能 "execute if entity @p[tag=!show_player] run playanimation @a animation.player.hidden", //隐藏玩家功能 "execute if entity @p[tag=auto_tp] run tp @p @s" //自动传送功能 ] } } 复制代码
这时,会执行行为包根目录/functions/moving_speed.mcfunction。它的代码如下。execute if entity @p[tag=speed3] run event entity @s speed3 execute if entity @p[tag=speed4] run event entity @s speed4 execute if entity @p[tag=speed5] run event entity @s speed5 execute if entity @p[tag=speed6] run event entity @s speed6 execute if entity @p[tag=speed7] run event entity @s speed7 复制代码
(其实这里并不需要这个函数,我用这个函数主要是让实体文件更好懂。)
可以看到,当我们使用那些物品改变我们的速度时,实际上是给我们添加一个标签。如果我们有speed5标签,那说明我们设置的速度是5,会触发speed5事件。"speed5": { "add": { "component_groups": [ "speed5" //添加speed5组件组 ] }, "run_command": { "command": "function moving_type5" //检测缓动类型 } } 复制代码
触发speed5事件后,会添加一个组件组,这是用来计时的。过5秒后,它才会触发继续缓动的事件。组件组的代码如下。"speed5": { "minecraft:timer": { //计时器组件 "looping": false, //不循环 "time": 5, //时间 "randomInterval": false, //固定5秒间隔(只有在循环时这个才有用) "time_down_event": { "event": "camera" //倒计时结束后触发事件camera } } } 复制代码
这就开始了5秒计时。同时,speed5事件还触发了一个moving_type5函数,这是检测缓动类型并进行缓动的。由于缓动只能动一次,所以只能采用这种方法。那个文件有点长,我就放一条命令:execute if entity @p[tag=linear] run camera @p set supplementary:player_free ease 5 linear pos ~ ~ ~ rot ~ ~。这意思是如果玩家有linear标签,那么将玩家的摄像机以linear类型、在5秒内缓动到标记的位置上。共有32种缓动类型,都是一样的道理。
那么这次缓动完成了,如何触发下次缓动呢?刚才设置了一个5秒计时器,时间到后触发camera事件。这个事件就用于继续缓动。"camera": { "run_command": { "command": [ "scoreboard players remove @e[type=supplementary:moving_mark] moving 1", //将所有标记的moving分数都减1 "event entity @e[type=supplementary:moving_mark,scores={moving=1}] start_moving", //触发moving分数为1的标记的开始事件 "execute unless entity @e[type=supplementary:moving_mark,scores={moving=1..},c=1] run execute as @e[type=supplementary:moving_mark,scores={moving=0},c=1] run event entity @s end" //如果标记中没有分数为正数的,那么让最后一个标记触发自己的end事件 ] } } 复制代码
这里我使用了moving分数减1的方法来确认顺序。比如,现在有3个标记,moving分数为1,2,3。开始播放,分数变为0,1,2,原先是第二个的标记变成了第一个,所以会继续播放,分数变为-1,0,1。此时第三个标记变为了第一个,继续播放,分数变为-2,-1,0。此时分数为0的是最后一个,它的end事件触发,表示播放结束。
但现在有个问题。主要功能是实现了,但是这个播放是一次性的,只要播放完第一遍,整个系统就废了,无法重新播放。这是个很大的问题,我是必须修复它的。后记
这一期,我们实现了主要的功能。下期,我们解决这期末尾遗留下的漏洞。