这个系列教程一共有 3 个章节,这是其中的第三篇,推荐完整阅读全部三篇的内容哦。
第一篇 - 匹配系统
第二篇 - 消息系统
开始之前,你需要……
在正式开始学习之前,你需要做好一些准备~
这篇教程中,我们主要会用到两个扩展模块,分别是 Gandi Simple MMO v1.0.3 和 Gandi 数据助手 v1.1。
数据助手中,我们使用到的主要是处理 JSON 的语句。
如果你还不知道怎么使用 JSON,也不用担心哦,教程中的用法并不会很复杂。不过还是建议你去找教程学习一下 JSON,以后一定会用的上哦~
全局积木
在案例作品中,我已经把“同步系统”做成了一系列的全局积木,放在了“🔃同步系统”中。
你可以直接将这个角色加载到自己的程序中,使用其中的全局积木。(注:全局积木是指,在所有角色中都可以调用的积木)
你可以不用理解这些全局积木是如何编写的。当然,如果你感兴趣的话,也可以读读代码。
案例作品
同步系统 主要用于同步联机时的数据,例如玩家、子弹的位置等。
同步系统主要实现了 3 个功能:
- 生成克隆体时,使其他玩家也能看到这个克隆体;
- 玩家之间、克隆体之间的交互(如子弹使玩家扣血);
- 一些其他需要同步的内容。例如播放声音时,使其他玩家能够听到声音。
准备工作
在教程开始前,我们需要先导入角色 “🔃同步系统”。其中包含了所有需要的全局积木。
(记得去案例作品中下载角色👇)
接下来,我将详细讲解“同步系统”中涉及到的变量、列表、以及全局积木的含义和用法;在后面还会有如何用“同步系统”制作联机射击游戏的详细例子。
数据含义:
- 克隆体 ID。 私有变量,用于存放当前克隆体的ID。
ID被用于区分不同的克隆体,可以通过 ID 来查找和修改对应的克隆体。
(克隆体 ID 通常是随机生成的一串乱码,但是也可以指定,下面会讲到)
- 克隆体类别。 私有变量,用于存放当前克隆体的类别。
有4种不同的克隆体类别,分别是:
云 | 云克隆体的信息会被实时同步给其他玩家。通常用于玩家控制的克隆体、AI 等。 |
显示 | 只用于显示其他玩家控制的云克隆体,不执行实际的动作。 |
本地 | 本地克隆体的信息不会同步给其他人,且只有自己能看到。例如一些只有玩家自己可见的文字提示克隆体。 |
广播本地 | 广播本地克隆体和云克隆体类似,所有玩家可见,区别是广播本地克隆体在生成后,就不会同步信息。相当于生成克隆体时,向其他玩家广播,每个玩家生成一个“副本”,各自在本地运行,调用者的克隆体则是“主体”。伤害判定等由主体完成。(由于不同步信息,所以广播本地克隆体可能会出现每个人看到的不一样的情况。通常用于发射后轨迹固定的子弹、或者弹壳、烟雾等对同步要求不高的克隆体) |
- 调用克隆体的玩家 ID。 私有变量,用于存放调用当前克隆体的玩家的会话 ID(MMO 中的会话ID)。
- 刚调用的克隆体 ID。 用于存放刚刚调用的克隆体的 ID。
- 克隆体信息。列表,用于存放所有克隆体的信息。
其中,列表的每一项对应一个克隆体的信息,例如有两项,说明现在有两个克隆体。
对于每个克隆体的信息,形如:
{
"克隆体ID":"DK114F9HMKH",
"名称":"玩家",
"x":10,
"y":20,
"控制者ID":"DK114", //“控制者ID”对应变量“调用克隆体的玩家ID”的值,即储存调用者的会话ID
"克隆体类型":"云",
"大小":100,
"方向":90,
"造型":"造型1",
"血量":100
}
积木含义:
⚓ 基础积木:
1. 初始化。
用于在连入房间后,初始化数据。
2. 一些基础处理动作。
用于处理一些其他复杂的内容。
3. 同步云数据。
用于放在循环中,进行数据同步。
这些基础积木通常是这样用的:
🐱 克隆体相关积木:
1. 生成克隆体积木。
有三类不同的克隆体,他们分别是:云克隆体、本地克隆体、广播本地克隆体。
(关于这三种克隆体的区别,见上面的介绍)
2. 设置要调用的克隆体的信息。
上面的积木调用时只能指定克隆体的名字和坐标。如果还想指定克隆体的大小、方向怎么办?
可以使用下面的积木👇
一种使用的例子如下:
注意到,除了大小、方向、造型,这里还指定了血量。是的,可以指定自定义的数据,这个数据相当于附着在克隆体上的私有变量,可以被获取和修改。
3. 克隆体删除自己。
使用下面的积木来删除克隆体。
4. 删除指定 ID 的克隆体。
用于删除指定 ID 的克隆体。
📄 数据相关积木:
1. 获取克隆体数量。
目前和下面这个积木是等效的:
2. 获取当前克隆体的…
用于获取当前克隆体的各种信息,例如:
- 克隆体 ID。(下面的两个积木等价)
- 克隆体名称。名称在克隆体调用时指定,通过名称来区分克隆体是什么,比如玩家、子弹……
- x、y、大小、方向、造型。获取克隆体的这些信息,也可以直接用原版积木获取。
- 控制者 ID 。获取调用该克隆体的玩家的会话 ID。(下面的两个积木等价)
- 克隆体类型。克隆体类型包括“云”、“本地”、“广播本地”。(下面的两个积木等价)
- 其他玩家自己设置的信息。如血量、速度等自定义信息。
3. 修改当前克隆体的数据
下面两个积木用于修改当前克隆体的数据。例如血量、速度……
- 设置或创建克隆体的数据。
- 增加当前克隆体的数据。
4. 获取 ID 为…的克隆体的…
获取指定 ID 的克隆体的数据。
5. 获取第…个克隆体的…
获取第…个克隆体的数据。
这个积木常常配合“当前克隆体数量”积木一起用,用于遍历所有克隆体。
例如,计算敌人数量:
6. 修改 ID 为…的克隆体的数据
下面两个积木用于修改指定 ID 克隆体的数据。
7. ID 为…的克隆体的是否存在?
判断指定 ID 的克隆体是否存在,存在则返回 1,否则返回0 。
🔊 声音相关积木:
1. 播放声音。
用于播放声音,并且可以指定音量,以及其他玩家能否听到(1可以,0不可以)。
例如:
📐 计算相关积木:
1. 计算两克隆体间的距离。
计算两个指定 ID 的克隆体的距离。
2. 计算克隆体 1 朝向克隆体 2 的角度。
计算克隆体 1 朝向克隆体 2 的角度。例如克隆体 2 在克隆体 1 的右上角,返回结果是45.
3. (废弃)计算角 1 转到角 2 的角度差。
其中计算结果带正负号,顺时针为正,逆时针为负。
例如,179到-179的结果是2,10到-10的结果是 -20.
🚶♂️ 运动相关积木:
1. 朝方向…旋转…度。
朝某个方向旋转一定的角度,用于实现缓慢旋转的效果,例如塔防中的炮塔旋转。
例如,使炮台朝鼠标方向旋转:
2. 朝 ID 为…的克隆体的方向旋转…度。
使当前克隆体朝指定克隆体的方向旋转一定角度。可用于敌人朝玩家方向旋转。
例如,让敌人缓慢面向玩家:
3. 朝某方向旋转,直到面向该方向。
同样,可用于敌人朝玩家旋转。
例如:
实践案例:
上面详细讲了每个积木的用法。你或许还比较困惑。接下来我将结合具体的例子来讲解。我将教你如何用“同步模块”制作“皇牌空战”联机射击游戏。
你可以点击下方下载飞机的素材,当然也可以用自己的素材。
第一步:初始积木
首先,在角色中添加以下三个积木:
他们负责处理一些复杂的内容。不用管他们,把他们拖到角落就好。
接着,在“主要角色”中完成以下代码:
第一段代码,当绿旗点击时,连入房间并等待。
第二段代码:
- ”⚓初始化积木” 用于玩家加入房间后,信息的初始化。
- “🐱生成云克隆体”用于产生玩家克隆体。
- “⚓同步云数据积木” 用于同步云数据。
第二步:编写玩家克隆体的代码
接着,我们来完成玩家克隆体的动作。
首先,有一部分克隆体会负责“显示”,他们不会执行代码。所以每个“当克隆体启动”的积木下都要加入如下积木:
我们为名称为“玩家”的克隆体编写代码,使其通关操纵能够自由移动:
这样,一个基本的联机效果就完成了!可以邀请其他协作者来帮忙测试:
第三步:编写子弹的代码
现在我们让飞机能够发射子弹,且每0.1秒才能发射一个子弹。
为了使发射子弹的“等待0.1秒”不干扰飞机移动的代码,我们编写一个新的“作为克隆体启动”的积木。
注意,“作为克隆体启动”的积木头下必须加上“显示”类克隆体停止脚本的代码。
注:子弹通常使用广播本地克隆体。
例如,我想让生成的子弹,方向和玩家相同,速度为10,则可以写成:
接着,我们来编写子弹的代码。我们可以将子弹的代码接在“玩家”的代码的下方
其中这里获取的“速度”就是之前指定的子弹速度。
注意到下面的“删除克隆体并删除相关信息”积木。以后使用这个积木替代原版的删除克隆体积木,因为删除克隆体的同时还需要删除相关的信息。
这样我们就实现了简单的发射子弹的动作了~
第四步:使加入的玩家获得随机的飞机颜色、使子弹颜色跟随飞机
我们可以在玩家克隆体的代码里加入切换随机造型。(1~4的造型表示切换到编号为1~4的造型)
接着,我们可以让子弹的颜色跟随战机的颜色:
(记得把”子弹”这里设置造型的代码删掉)
完成!
第五步:给玩家飞机加入血量系统
使用下面的代码给玩家飞机加入血量系统。
玩家血量设为100,当血量小于或等于0,删除玩家克隆体。
其中这个积木可以设置当前克隆体的数据(如果数据不存在,将自动创建这个数据)
现在我们再加个飞机爆炸的效果:
注意到这个新积木:播放声音并让其他玩家听到,用于替代原版的播放声音积木。
现在我们再给发射子弹加上音效:
第六步:给子弹加入伤害系统
首先,我们需要让子弹每次循环都检查一次是否碰到了敌人,以及碰到的是哪个敌人。
现在我们来自制一个自定义返回值积木(注意勾选不刷新屏幕、返回值):
这个积木会返回当前克隆体碰到的敌人的ID。
再新建一个私有变量(勾选仅适用于当前角色),命名为*i(前面的 * 号用来标记这个变量是私有变量,方便区分)
然后,代码可以这么写:
- 依次检查每个克隆体。
- 首先判断克隆体是玩家(否则会出现子弹击中子弹的情况)
- 接着计算这个克隆体到子弹的距离,距离<40,判定为击中,返回击中的ID;
- 如果查找了一遍。没找到符合条件的克隆体,则返回空
但是上面的写法还有点问题,因为可能出现发射的子弹击中发射者的情况。
因此,我们给判断条件再加上:
然后,在发射子弹时,给子弹添加数据“发射者ID”。
最后,我们来修改子弹的代码:
- 子弹移动,直到碰到边缘或者碰到的敌人ID不为空(即碰到敌人)
- 如果碰到了敌人,播放击中音效,并且将击中的敌人的血量减10
- 删除克隆体
最后我们可以加一个击中飞机后,被击中者亮度变暗的效果:
完成了!来测试一下:
第七步:加入名字显示
为了方便找到玩家的克隆体,我们可以指定玩家的克隆体 ID。
通常克隆体的 ID 是随机生成的,但是我们也可以提前设为特定值,指定的值会覆盖随机生成的 ID。
例如:将玩家克隆体的 ID 指定为玩家的会话 ID 。这样,通过会话 ID 就可以找到玩家的克隆体。
现在,我们来制作一个自定义积木,这个积木将会给房间的所有玩家贴上名牌。(记得勾上运行不刷新屏幕)
写法如下
(注意,玩家的编号是从0开始的,所以第一个玩家应该是第0个玩家)
然后将写好的积木塞在这里:
除了加入的时候要给已有的人贴名牌,还要给新加入的玩家贴名牌:
(由于进入房间时已经给包括自己在内的玩家贴了名牌,所以这里要判断不是自己才贴名牌)
然后,写名牌的代码:
其中这个积木用于判断某个克隆体是否存在(存在返回1,不存在返回0)。
当名牌跟随的克隆体删除了,那么名牌就也删除自己。
还有个小问题,玩家刚加入房间的时候就贴名牌,可能出现玩家克隆体还没出现,就放名牌的情况。
然后名牌发现自己跟随的克隆体不存在,就删除了自己。等玩家克隆体出来时,就会发现自己的名牌不见了。
因此,我们要在放名牌之前,加一个等待直到玩家克隆体出现:
这样加名牌就完成了!
第八步:加入血条显示
血条显示可以选择用克隆体,也可以选择使用画笔绘制。克隆体的实现方法类似于名牌。
这里我们直接用画笔绘制血条。画笔的优点是可以减少克隆体占用,缺点是,看起来比较模糊,且如果有背景角色,会遮挡住画笔的内容。
血条绘制的代码可以是这样:(创建自定义积木,之后记得勾选不刷新屏幕)
对于每个玩家的血条,分成两个部分:
- 黑色的底:
例如这里血条的长度是80,就从角色的x-40的位置开始绘制。
- 红色的条:
从x-40的位置开始,绘制长度为 (血量/总血量)*80 (这里总血量为100)
接着将制作好的血条代码拖动到重复执行中:
现在让我们来试试效果:
大功告成!
注意事项
这篇教程中,主要介绍了如何利用同步模块来制作联机游戏。除了教程中的飞机大战案例,你也可以举一反三,制作其他类型的联机游戏~
对于教程或者全局积木有任何问题,也可以在评论区告诉我。
创作者学院文章:
到此为止,三篇 MMO 游戏教程系列就完结啦。如果有什么疑问,或者下次希望我们出什么教程或工具包,欢迎在下方留言呀~
— THE END —
加入AI(稍微有点复杂)
除了玩家之间的互动,我们还可以加入AI。
先给AI写个随机乱走的动作:
其中,下面代码的含义是,朝某个方向旋转,直到面向该方向。
(此处是面向随机方向,转速10)
当然,我们的AI不能只会随机乱走,还要学会瞄准敌人。
在此之前,我们要让AI能够找到敌人。
编写一个返回值积木,叫查找最近敌机ID。(勾上返回值和运行不刷新屏幕)
这个积木会返回离当前AI最近的敌人ID,代码可以如下:
- “最近敌机的编号”最开始设为空,表示没找到敌人。
- 查找所有符合条件的敌人
- 找到敌人后:
- 如果“最近敌机的编号”为空,则将“最近敌机的编号”设为该敌人编号
- 如果“最近敌机的编号”不为空,则比较当前敌人和“最近敌机的编号”的敌人到AI的距离,如果当前敌人的距离更近,就将最近的敌人编号设为当前敌人编号。
- 结束后
- 如果最近敌人编号=空,说明没找到敌人,返回空
- 如果最近敌人编号不为空,返回找到的敌人的ID
完成这个积木后,我们可以编写 AI 的代码:
- 克隆体被放出来时,广播生成名牌(让所有人都给AI戴个名牌)
- 随机移动一定的步数
- 判断是否有敌机:
- 如果没有敌机,面向随机方向
- 如果有敌机,面向最近敌人,射击。
其中,克隆体的控制者ID存的是调用这个克隆体的玩家的会话ID。
然后再加上 AI 的死亡判定:
最后,当玩家加入房间的时候,也给在场的AI贴名牌
给AI画血条:(把条件加上AI即可)
给子弹查找敌人的条件加上AI
加上生成AI的代码:
大功告成!