UID19188性别保密经验 EP铁粒 粒回帖0主题精华在线时间 小时注册时间2020-11-1最后登录1970-1-1
| 本帖最后由 冥王大大 于 2025-9-2 23:07 编辑
前言 | | 预执行模式(Early-execution mode)一直都是一个很神秘的概念。它的影子在SAPI 2.0随处可见,但是更新日志里仅仅潦草地记载了几句。我们甚至连它的作用是什么、它改变了什么都不知道。预执行(Early Execution)又“预”在哪里,“执行”什么?这里根据部分官方的表述和实际应用的效果来解释这个概念。 | 讲述 | 预执行模式在1.21.70的正式版才正式引入,此前的正式版更新日志并没有介绍过。所以我们来看1.21.70的更新日志:

它介绍了哪些类的方法是可以在预执行模式下执行的,但是预执行模式对其他的方法有什么影响呢?我们来看计分板类(Scoreboard Class)的方法.getObjectives(): 
可以看到,没有标注可在预执行模式下执行。于是,以下代码:- import { world } from "@minecraft/server"
- const list = world.scoreboard.getObjectives().map(o => o?.displayName)
- world.getPlayers().forEach(player => {
- player.sendMessage(String(list))
- })
复制代码 在SAPI 1.0执行时应该会在聊天栏显示undefined或你的计分板项目的名称,而在SAPI 2.0中就会报错而不会在聊天栏显示任何信息。这是因为在没有任何方法嵌套的环境下,游戏会在玩家还未完全加载世界的时候执行一次这些代码。也就是说,即使在SAPI 1.0执行上面那些代码,你进入游戏时也不会看见左上角的消息提示,而只能在聊天栏的对话记录看到文字。也就是说,预执行一直存在,只是SAPI 2.0引入了对它的限制而已。而在《Concepts of SAPI: WorldEvents》中,我们留了一个小作业,看看我们在SAPI 2.0中怎么完成它:- import { system, world } form "@minecraft/server"
- world.beforeEvents.playerInteractWithEntity.subscribe(event => {
- system.run(() => {
- if (event.itemStack.typeId === "minecraft:fishing_rod") {
- if (target.typeId === "minecraft:player") {
- event.target.kill()
- } else {
- event.target.remove()
- };
- }
- })
- })
复制代码 其中,因为Entity.remove()方法不适用于玩家,所以专门设计一种用Entity.kill()的情况。因为钓鱼竿其实并不能与实体互动,但是它有一个使用该物品的组件,也就是说,当你用钓鱼竿右键实体时,玩家互动实体前事件(PlayerInteractWithEntityBeforeEvent)也会触发;不过因为钓鱼竿实际上不能与实体互动,这个事件的触发就相当于被“预执行”了。而System.run()方法在上面的更新日志可以看到,是有预执行权限的,它的作用相当于在游戏中运行一次包含的代码,所以我们在这里嵌套一个它,就可以对PlayerInteractWithEntityBeforeEvent.target进行操作了。 | 总结 | | 预执行在网络上被译为早期执行或提前执行,因为它表示的是异步程序中某些片段被提早执行的状态,多数情况下这种状态是一种漏洞,应当避免。然而,在SAPI中,它们其实拓展了常规的用法,不过在SAPI 2.0之后运用它们变得麻烦了些。 |
|
|
评分查看全部评分
|