自从很久很久以前迷你世界开放脚本功能开始,直到现在,很多小伙伴对脚本也仅仅停留在“噢我听说过”的阶段,甚至更多连听都没听说过!更别提用脚本做游戏了。就算是在“听说过也用过”的玩家群体里,也只有极少一部分愿意自己查资料搜教程来学习,提升自己的脚本水平。所以你能点开篇教程,看到这里,我很幸运!我幸运的是终于有小伙伴愿意主动学习脚本;相信我,这个系列的教程不会让你失望;不管你是零基础的小白玩家,还是有基础的脚本大神,跟着我的节奏一步一步来,不说满载而归,但一定能让你收获颇丰!
那么,我们开始吧!
特别提醒:
①极力推荐边看边实际操作,效果提升百分百;
②一定不要急躁,静下心慢慢来,别担心,我们有时间,一步步来;
③一定要认真,要用心,要理解;
④遇到不理解的地方也不要急,可以放一放,或者记下来问问别的小伙伴。
咱们通过几个基础案例开始了解把~
事件系统是玩法的根本,几乎所有的玩法都要依赖于事件得以实现。所以理解事件系统是学习脚本的首要任务。
要求:玩家做哭泣表情输出“12”,做生气表情输出“34”。
先看代码:
function ppa(e)
if e.act==3 then print("12")
elseif e.act==4 then print("34")
end
end
ScriptSupportEvent:registerEvent([=[Player.PlayAction]=],ppa)
这段代码是什么意思呢?我们来分析一下:
首先我们创建了一个盒子(函数),名字叫ppa。这个盒子(函数)有几个入口(参数)呢?只有一个入口e。然后盒子里有什么我们先不管。再往下,可以发现这个盒子没有吐出东西就关闭了,也就是没有出口(返回值)。
最后一行是什么意思呢?叫监听事件,就是每当这件事发生的时候,就打开某个盒子。在这里就表示:每当“Player.PlayAction”发生的时候,就打开盒子ppa。
那么Player.PlayAction是什么事件呢?我们打开左侧目录,找到迷你世界接口列表→事件,翻到玩家事件:Player,可以看到:
所以,
ScriptSupportEvent:registerEvent([=[Player.PlayAction]=],ppa)
这行代码的意思就是:
每当玩家做动作表情的时候,就打开盒子ppa(执行函数ppa)
再看:
右面是这个事件附带的表格。eventobjid和act就是这个事件包含的东西,它们会作为一个表格塞进我们的盒子里。还记得我们讲过的表格是什么吗?
表格包括名字和内容。在这里,这个表格就是:
注意内容含义不是内容,指的是内容代表的东西。那么
ScriptSupportEvent:registerEvent([=[Player.PlayAction]=],ppa)
这行代码完整的意思就是:
每当玩家做动作表情的时候,就打开盒子ppa,然后把上面的表格塞进盒子的入口。
那么盒子ppa里面是什么呢?我们回过头去看一下:
function ppa(e)
if e.act==3 then print("12")
elseif e.act==4 then print("34")
end
end
首先这个盒子有一个入口e。然后呢,里面是三行条件语句。最后直接就关闭了盒子。这三行条件语句是什么意思呢?
if e.act==3 then print("12")
elseif e.act==4 then print("34")
end
意思就是:
如果 表格e中名为act的内容 等于3,就输出“12”
否则如果 表格e中名为act的内容 等于4,就输出“34”
结束判断
下面我们重点看一下“表格e中名为act的内容”指的是什么。上面我们说了,
每当玩家做动作表情的时候,就打开盒子ppa,然后把上面的表格塞进盒子的入口。
所以,现在e就是这个事件塞进来的表格。e的里面就是:
所以,e[act]就是玩家所做的表情id。如果e[act]等于3,就意味着玩家做的表情id是3。打开左侧目录,找到迷你世界ID列表→玩家动作列表,可以看到:
所以如果玩家做的表情id是3,就代表这个玩家做的表情是哭泣。如果是4呢,就是生气。
到现在基本讲完了事件系统。如果哪里不理解先别回去看,继续往下,我们来梳理一遍。
首先是代码:
function ppa(e)
if e.act==3 then print("12")
elseif e.act==4 then print("34")
end
end
ScriptSupportEvent:registerEvent([=[Player.PlayAction]=],ppa)
这个代码分为两部分,一部分是前5行,我们创建了一个名字为ppa、入口为e的盒子。
另一部分是最后一行,我们添加了一个Player.PlayAction(玩家做动作表情)的事件,每当事件发生时,我们就打开盒子ppa,然后把这个事件附带的表格塞进盒子的入口。
所以这段代码整体的意思就是:
每当有玩家做动作表情,就打开盒子ppa,把事件附带的表格填进盒子。
盒子含义:
盒子ppa(入口e):
如果玩家做的表情是哭泣,就输出“12”
否则如果玩家做的表情是生气,就输出“34”
然后结束判断
最后关闭盒子
对照一下(模糊的话请点开图片查看):
特别注意,
if e.act==3 then print("12")
本意应当是:
如果 表格e中的act等于3 那么就 输出“12”
在这里,表格e中的act等于3意味着什么呢?意味着事件里附带的表格里的act是3,上面我们查表看到,玩家做动作表情的事件里act等于3就代表玩家做的表情是哭泣。所以上面就可以直接理解为:
如果 玩家做的表情是哭泣 那么就 输出“12”
最后,我们把代码复制到游戏里面:
转为玩法模式,做个“哭泣”的表情,看一下输出:
本节内容到这里就结束了。再次强调,事件系统是学习脚本必须掌握的东西,一定要理解。一时半会不理解的话就自己动手尝试,多练习。
上节我们通过分析代码了解了事件。这节我们通过需求来思考代码。
我们来看几个常用的事件:
需求1:任意玩家点击方块,输出被方块的坐标。
需求2:任意玩家丢弃物品,输出被丢弃的物品id和丢弃数量。
**需求3:任意玩家移动一格,输出玩家已经移动了多少格。
首先看需求1。打开目录,翻到事件。我们需要监听的事件是“玩家点击方块”,所以从玩家事件里找:
第二个就是我们要找的事件。这个事件附带的表格里都有哪些东西呢?看右面:
那么要实现需求1(任意玩家点击方块,输出被方块的坐标),我们可以:
【解决方案】
创建一个名字为click、入口为m的盒子:
输出表格m里的x
输出表格m里的y
输出表格m里的z
关闭盒子
添加事件:每当玩家点击方块时,就打开盒子click
对应代码:
【源代码】
function click(m)
print(m.x)
print(m.y)
print(m.z)
end
ScriptSupportEvent:registerEvent([=[Player.ClickBlock]=],click)
需要注意一点,盒子的名字和入口的名字都是随便取的,什么名字都行。但是一般来讲,要以简单、易读为主,也就是说你一眼看到这个名字就能理解它的意思,以及它要实现的功能,但是不宜太长造成累赘。
比如上面的盒子click,一眼就能看出来它的意思是“点击”,代表“玩家点击方块”时要打开的盒子。但是如果你命名为“wan_jia_dian_ji_fang_kuai”,虽然也能看出来表达的意思,但是非常影响代码的可读性,不太实用。
我们把代码复制到游戏里:
转成玩法模式,随便点击一个方块:
意思就是,刚刚有玩家点击了位于(3.5 , -5.5)高度6.5处的方块。这里的“.5”不用在意,可以直接向下取整(就是取小于这个数的最大整数)。在小地图中显示的坐标就是(3 , -6)高度6。
再来看需求2:任意玩家丢弃物品,输出被丢弃的物品id和丢弃数量。同样先找到事件:
事件附带的表格:
解决方案:
创建一个名字为dis、入口为m的盒子:
输出表格m里的itemid
输出表格m里的itemnum
关闭盒子
添加事件:每当玩家丢弃物品时,就打开盒子dis
源代码:
function dis(m)
print(m.itemid)
print(m.itemnum)
end
ScriptSupportEvent:registerEvent([=[Player.DiscardItem]=],dis)
复制到游戏里面:
转成玩法模式,丢弃一组石头:
重点来看需求3:任意玩家移动一格,输出玩家已经移动了多少格。
首先找到事件:
可以看到,这个事件附带的表格里,只有一个数据:eventobjid,表示移动的玩家迷你号。那么怎么输出玩家已经移动了多少格呢?我们需要一个未知数(变量)来记录。
【解决方案】
新建一个未知数(变量)p=0
创建一个名为move、入口为e的盒子:
把p的值加1
输出p
关闭盒子
添加事件:每当玩家移动一格,就打开盒子move
这样一来,每当玩家移动一格,都会把p加1,p就成为记录玩家移动格数的东西。那么代码怎么写呢?
【源代码】
p=0
function move(e)
p=p+1
print(p)
end
ScriptSupportEvent:registerEvent([=[Player.MoveOneBlockSize]=],move)
先别急着复制到游戏里,我们来思考一下。这个解决方案乍一看是没什么问题,但是仔细想想,如果你开了一个房间,有很多玩家进来玩,那么这个变量p记录的还是某个玩家的移动格数吗?不是。因为任意玩家移动一格都会打开盒子move,都会把p加1。所以这个p实际上记录的是当前存档中所有玩家的移动格数。
那么如果我们想要分别记录每个玩家的移动格数,该怎么办呢?用表格。
假设存档里有迷你号分别为1000、12345和666666的三个玩家。我们建立一个表格ps:
如上表,我们用ps[1000]来记录迷你号为1000的玩家移动的格数,用ps[12345]记录迷你号为12345的玩家移动的格数,以此类推。这样,哪个玩家移动了,就给表格ps里对应迷你号的值加1,把每个玩家分开来记录。就有:
【解决方案】
新建一个空表格ps
创建一个名为move、入口为e的盒子:
让a等于表格e中的eventobjid
如果表格ps中没有名为a的内容,就让ps中的a等于0
结束判断
把表格ps中a对应的值加1
输出a和ps中的a对应的值
关闭盒子
添加事件:每当玩家移动一格,就打开盒子move
这里要注意,表格e中的eventobjid就是移动一格的玩家迷你号,这个在事件附带的表格里有说明:
所以,把表格ps中a对应的值加1意思就是把表格ps中移动的玩家迷你号对应的值加1。
这样表格ps就成为单独记录每个玩家移动格数的表格。代码如下:
【源代码】
ps={}
function move(e)
a=e.eventobjid
if ps[a]==nil then ps[a]=0
end
ps[a]=ps[a]+1
print(a,ps[a])
end
ScriptSupportEvent:registerEvent([=[Player.MoveOneBlockSize]=],move)
对照一下(图片不清晰可点开查看):
如果结合事件来解释盒子move的含义,可以这么理解:
新建一个空表格ps
创建一个名为move、入口为e的盒子:
让a等于移动的玩家迷你号
如果这个玩家还没有移动过,就把他新记录到表格ps里,对应移动格数为0
结束判断
把这个玩家的移动格数加1
输出这个玩家迷你号和他的移动格数
关闭盒子
添加事件:每当玩家移动一格,就打开盒子move
比如,玩家1000移动了一格。那么他触发了“玩家移动一格”这个事件,会怎么样呢?会打开盒子move。然后呢?然后:
盒子里发生的事:
a=1000
如果ps中还没有1000,就给它加上去,移动格数等于0
结束判断
然后ps[1000]=ps[1000]+1,就是记录这个玩家的移动格数增加了1
再输出1000和ps[1000],就是1000的移动格数
最后关闭盒子。
把代码复制到游戏里:
转成玩法,走几步看看:
本节到这里就结束了。这部分内容是重点。不强求现在马上理解,但要想灵活运用脚本做玩法,这部分是必须要理解的。哪里不理解记下来问问周围的小伙伴,或者一起讨论一下。也可以带着疑问继续往下看,说不定就突然理解了。重点还是边看边实际操作和练习。