往期回顾
第七期:触发器与逻辑
本期我们终于要接触到触发器和逻辑。 不废话,让我们先直接从例子开始讲述。
制作一个大门,当克里夫携带钥匙来到大门前时,能够打开大门
打开地形编辑器,找到关尾。
为了让关卡的目的显得更明显,我们不把大门放在 BOSS 的后面,而放在小径的前方。 为此我们需要对场景再做一些修改。
关尾的修改完成。
不过本节要讲述的不是增加一个大门,而是实现一套逻辑。 当勇者携带钥匙大门的钥匙来到门前时,能够打开大门。
在魔兽争霸中,大门只有 2 种方式打开,一种是直接暴力摧毁它,一种是通过触发器逻辑来打开它。
在介绍触发编辑器之前,我们先完成本节的工作。 回到地形编辑器,按 A 打开工具面板,按 R 进入区域面板。
点击矩形区域按钮,进入【添加】模式。
回到场景,鼠标左键拖拽出一个矩形区域。
按下 F4 回到【触发编辑器】。 默认的,我们可以看到如下的窗口。
由于在本教程中我们使用的是魔兽争霸对战平台提供的修改后的魔兽地图编辑器,因而在这里有来自修改后的默认触发器。 我们直接删掉【简介】,然后点击新触发按钮来创建一个新的触发器。
选中该触发后按下 F2 或者用鼠标左键点击一次,进入编辑名字的状态。
如上图,将新创建的触发器名字改为【E00 钥匙开门】,并将其所属目录改为【事件】。 这么改的目的是为了将逻辑分门别类,不过你也可以探索出自己的使用方式。 另外需要一提的是,这里的【E00】前缀是用于防止触发器冲突的。 在触发编辑器中,触发器中的【中文字符】和【特殊字符】都会统一被游戏转换为 “_” 符号,因此即便当我们为触发器修改了不同的中文名字,编辑器本身也会把它们视作相同名字的触发器。
如上图,这里的原理我们暂不多说,但如果想要规避这种冲突,就可以使用阿拉伯数字 + 字母进行名字的区分。
回到正题,我们现在要实现一个游戏逻辑,即当玩家操作的单位【克里夫】来到大门前(我们通过【矩形区域】来判断)时,如果他携带了物品【大门的钥匙】,我们就要打开大门。 我们先忽略这里面涉及的新的概念,先直接完成这个游戏逻辑。
在我们的【触发器】中,在【事件】处右键,选择【新事件】,并找到【单位进入区域】事件。
选中后,我们可以填写这个事件的【参数】。
点击红色的【矩形区域】文字,在弹出的对话框中选择我们先前在场景中创建的【矩形区域 000】。
随后点击确认,我们便为这个触发器创建了一个触发事件。
为了执行后续开门的动作,我们需要先限定条件: 1 进入的单位是克里夫 2 克里夫的物品栏里有【大门的钥匙】
在【条件】处右击,新建条件。
找到【单位】。
在这里,(触发单位) 就是指触发了本触发器事件的单位,即指代进入了矩形区域的单位。 不过为了更清晰的理解,我们可以点击 (触发单位),并在下拉列表中将其替换为 (事件响应 - 进入的单位)。
这些列表中的功能,被定义为【函数】。
函数的概念我们将会在后续讲解,先点击确认,然后继续编辑我们的【条件】。
在这里点击红色的【单位】,在弹出的窗口处点击【选择一个单位】。
随后窗口会自动跳转到【地形编辑器】,通过鼠标右键拖拽,找到【克里夫】,左键点击他。
一个【平凡的勇者 0060 <预设>】现在出现在了【变量】栏中。 点击确定,我们便完成了第一个条件的添加,将其切切实实地录入到了游戏逻辑中。
再创建一个新条件,用于判断克里夫(平凡的勇者)是否携带了【大门的钥匙】。 这一次我们找到【布尔表达式】。
点击第一个参数,在函数列表中找到【英雄 – 持有物品 (指定类型)】。
修改两个参数,第一个参数可以不变,也可以修改为【进入的单位】,也可以改为【平凡的勇者】。 第二个参数必须修改为【大门的钥匙】。
点击确认后,我们完成了 2 个条件的编辑。
随后,我们要完成最后一步:打开大门。 在【动作】处右键,添加新动作。
在弹出的动作窗口,左上角选择【可破坏物】。
然后找到该分类下的【打开/关闭/破坏大门】动作。
点击【大门】,在参数窗口点击【选择可破坏物】。
随后窗口再次被切换到地形编辑器窗口,右键拖拽找到我们的大门,左键点击它。
得到结果如下。
到此,我们完成了一个基本的游戏逻辑的编写。 现在,当我们让克里夫携带钥匙来到大门时,大门就会打开。
让我们来聊聊游戏逻辑和触发器
触发器是技术领域的切入口,无数事件、动作,组合成无数逻辑。 当你按下灯的开关,灯会对应的亮起或关闭。 但如果你按下一个坏掉的开关,灯不会变化。 如果一个开关接触不良,灯会不定时闪烁。 如果开关正常,也有可能电线因为各种问题出现毛病而不定时闪烁。 如果开关和电线都没有问题,但灯也在闪烁,也有可能是电线通道内有老鼠在啃电线。
当然,本教程不是来讲电路的。 上述例子讲的是逻辑规则,如果有某个【结果】发生了,一定存在某个【原因】,无论这个原因是否被我们所知。 因果关系是纵横在这世界的,有些因果不被理解甚至不符合大众常识,有些则显而易见。 前者衍生出魔术、神算之类分支,后者则是常规生活,就像拧开水龙头,通常水就会流出来。
游戏逻辑实际上是从属于程序逻辑的,因而在进入这个领域后,我们已经切切实实地开始了程序世界的旅途。 让我们把话题切回制作。
【触发器】这个词语是一个术语。 在讲述后续的逻辑制作之前,我们得建立对这玩意儿的认知。 就像本教程前言所述,我们会假设正在阅读的你没有什么程序开发经验,是入门级的爱好者。
在魔兽地图中,它是由事件、条件、动作组成的东西。 在【游戏运行的过程】中,如果游戏发生了某个或某几个【特定的事件】,这些事件会被【触发器】发现。 当【触发器】发现这些事件后,它会检查该事件的要素,如时间、地点、人、物,是否符合让自己执行特定【动作】的【条件】。 如果【条件】成立,则触发器会【执行动作】。
通俗的例子:当有人按下门铃时,门铃会响。 在这个例子中,事件是【有人按下门铃】,动作是【让门铃响起来】。 不过实际上,就算按下门铃的不是【人】,只要【门铃被按下】,也会触发【门铃响起来】这么一个结果。 同样,在上述规则中,无论门铃是否损坏,门铃一定会响起来。 但这实际上不符合客观规律。
因而我们应当这样去整理规则。 事件:门铃按钮被按下 条件:门铃是电子铃,并且电子门铃的电路没有损坏,并且电子门铃的电池还有让其响起的电,并且按钮被按下的幅度能够触及电路 动作:让【按钮关联的电子门铃】响铃 显然,这样更符合现实逻辑。
不过,【门铃】并不会自己响起来。 所以事实上人按下门铃按钮并让电子门铃响起来,并非是由【单个触发器】完成的。
我们实际上存在这样的组合。 【触发器 1:通电】 事件:电子门铃按钮被按下 条件:按钮被按下的幅度能够触及电路,并且关联被按下的按钮的电子门铃组件内的电池还有电 动作:电池放电 【触发器 2:响铃】 事件:电池放电 条件:电池所放电流能够触及响铃组件 动作:响铃组件开启电通路,在接下来 5 秒内持续通电 【触发器 3:发音】 事件:响铃组件受到电刺激 条件:无 动作:振动发音组件 以上 3 个触发器,各自包含事件、条件、动作,共同完成了【当电子门铃被按下时,电子门铃响铃】这么一套逻辑。 而在实际的游戏逻辑设计中,我们也经常会出现多个触发器,经历多次判断,共同完成一套逻辑的情况。
到这里,你应该大致理解了触发器的概念,以及它的作用。 在本教程中,我们没有从术语角度明确清晰地规定【触发器】的定义,如果你想要了解相关的严谨术语定义,可以自行搜索。 我们着重于从通俗生活和实际使用的角度进行阐述,让你大致能够理解它是什么。 我们可以通俗地理解为,它是一系列【关系】的组合,按照特定的【规则】, 来达成特定的【结果】。 在实际制作中,我们可以通过魔兽地图编辑器提供的现成的无数【事件】、【条件】、【动作】,来根据我们的需要,组合出不同的结果。
不过不同于现实。 在现实中,【逻辑】用于【描述】客观规律,而在游戏中,【逻辑】用于【定义】客观规律。 换言之,游戏内发生某件事情后诞生的结果,是由游戏制作者【定义】的。 就像现实中,【人被杀,就会死】,这是基本的逻辑。 而在游戏中,我们可以改变这个因果,比如【人被杀,就会爆炸、10 秒后复活并升级】。 这不符合常理对吧?但我们制作的并不是现实世界,而是游戏。 除非我们的游戏需要【常理】,否则常理在这里就没有意义。
如果你对【触发器】和与之相关的【触发】、【事件】、……等等的概念仍然还很模糊,不用担心,在接下来的教程中我们会更频繁地提到它。 不用担心现在不能 100% 理解它的含义,实践会帮助你更充分去理解和消化。
当玩家抵达防线出口时,游戏胜利
让我们继续完成剩余的工作吧。 接下来,如果我们要实现【当玩家抵达防线出口时,游戏胜利】这一功能,我们需要能够捕获到【玩家抵达防线出口】这一事件。
在魔兽地图中,我们有【矩形区域】。 矩形区域可以用于捕获游戏内的单位【进入区域】或者【离开区域】的事件。
让我们回到我们的场景,在最终大门的后方再创建一个矩形区域。
先前我们已经撰写了大门的触发器,当大门没有开启时,勇者并不能穿过大门。 而当大门开启后,我们需要让玩家抵达【出口】。 我们新创建的矩形区域,实际上定义了出口。 即,【新创建的矩形区域所指的范围,在本关卡逻辑中是 “出口”】。 当勇者抵达这个范围内,就算【抵达了出口】。
为此,我们需要用触发器来描述这个逻辑定义。
同先前的触发器,我们定义好进入的单位必须是【勇者】后,再找到魔兽地图编辑器提供的【游戏胜利】动作。
点击确认后,当勇者抵达这个区域,本局游戏便胜利了。
同样,只要这个触发器在,【矩形区域 001】(我们新创建的矩形区域)就永远会触发【让玩家 1 胜利】这个动作。 因而即便我们把这个矩形区域放置到一开始勇者身后,只要他踏入了这个区域,就一定会触发这个动作。
当然,如果我们不希望这结果被投放到最后发布的地图中,我们就得确保不要在哪次编辑中意外地修改了这个矩形区域的位置,否则就可能出现这样的意外。 ——这种意外往往被我们称呼为 BUG,一种在程序世界中喜 (shen) 闻 (wu) 乐 (tong) 见 (jue) 的恼人生物。 如果你不希望体验浪费整整半天时间、甚至完全重构了整个地图逻辑就为了查一个不起眼 BUG 的经历,那么当你对待逻辑的时候可就一定要养成严谨的好习惯。尽管这是几乎是所有尝试在程序世界中前进的人都会体验的经历,但它归根结底并不是我们最终的、即推出游戏作品或游戏产品、这么一个目的。
当克里夫死亡时,游戏失败
废话不多说,让我们直接上图。 除了任意单位事件,在魔兽中我们也有【指定单位事件】。 使用一些便捷的事件往往可以节省我们宝贵的时间。
同样在【游戏】分类中,找到【游戏失败】动作。
创建一个主线任务在任务栏,用于提醒
如果我们不希望玩家进入游戏后一脸懵逼不知道自己干什么,那么我们最好告诉他。 在魔兽游戏中,左上角有任务栏可以供玩家在不知道自己干什么的时候了解自己应该干什么。 本节我们就添加任务,来实现这个功能。
创建一个新的触发器,设置其事件为游戏时间逝去 2 秒。
在触发器动作清单中,有【任务】分类,提供了大量与游戏任务相关的功能。
创建任务:离开森林
“为了从魔王手下救出于水火中的世界,你需要先抵达王国。 但在那之前,你必须先离开你居住的森林。“
除了设置标题和文本,我们还可以修改任务的图标。 点击任务图标后的路径,便可以通过列表查找图标。
在魔兽中,“创建任务” 并不会直接提示玩家获得了新任务,因此我们需要手动向玩家发送信息,告诉他任务内容,以使得玩家能够注意到。 我们可以通过【发送任务信息】来达成这个事情。
此外在发送消息后,如果我们想让玩家知道有【任务栏】的存在,我们还可以追加一个动作,即【闪动任务按钮】。
在这里,我额外设置了 5 秒等待,是因为玩家阅读发现任务信息时,其注意力放到了文字上,很可能不会注意到任务按钮。 而如果等待 5 秒再闪动按钮,便能够在玩家的注意力还在【系统给予的信息】上,但又没有【具体地关注某个信息】时,再次抓住玩家的注意力。
尽管在程序功能上,无论是否有等待,任务按钮一定会闪烁,任务消息一定会发送。 但是,【设计】之所以能够在如今的游戏行业(乃至互联网行业)中成为一门细分的、与【技术】形成不同方向的类目,正是因为它能够让一个游戏不止是程序。
关于设计和技术(制作)的区别,这在实践中已衍生出非常多理论和关系,并且目前仍然有许多从业者、爱好者对此进行讨论。 如果你感兴趣,不妨自行搜索更多相关资料。
到此,我们已经完成了第四期提到的内容,这也宣告我们的入门章节结束。 接下来的更新我们将进行更深入的知识讲解,欢迎关注。