物体是用来控制游戏各方面的具体事件的特殊资源。大多数时候它们有一个与它们相关的精灵,以便你在游戏房间里看到他们,但有时候它们被用作“幕后”控制器来做与用户相关的事情或时间等... 它们可以被给予行为,并能对事件和它们自己做出反应。你在游戏看到的大多数事情都是基于物体和它们的相互作用。现在,我们说“基于”,因为你实际上并没有将物体直接放入游戏房间,而是放置这些物体的 实例,这些物体基本上是物体资源的副本(或者如果你愿意的话也可以称作克隆)。这很重要,因为这意味着物体和实例 不同,每一个实例均有自己的一套功能。
为了说明这一点,想想用 GameMaker Studio 2 制作的游戏。所有的角色,怪物,球,墙壁等都是你在资源树中创建的物体。然后,将物体拖动到 房间编辑器 中的房间,以创建从基本物体模板复制的 实例。然后可以在编辑器本身或通过代码更改房间中的实例,以便可以缩放或着色,或从“基础”物体修改其他详细信息。所以当我们谈论影响或改变一个实例的东西时,我们的意思是它会影响 一个房间中一个物体的特定副本。只有那一个单一的实例受到影响,而其余的都不受影响。但是,当我们谈论影响或改变 物体 时,我们意味着我们正在修改资源树中的物体,并且我们所做的任何事情也将反映在从该物体创建的所有实例中。所以,物体是实例的模板,实例是我们放置在房间中制作游戏的实例。
要在游戏中创建一个物体,你可以右键单击 物体资源文件夹,然后单击 创建 选项。这将打开此页面顶部的窗口,具有以下部分:
在这里你可以给你的物体一个名字。该名称不应包含空格或未授权的字符(只允许使用字母数字字符和下划线 “_”),并且应该简短但难忘,以便稍后在可能有许多文件时可以轻松识别资源。例如,许多人使用前缀或后缀来识别资源之间的差异,如“obj_Ship”或“Ship_obj”。
接下来你可以选择你想要的物体的精灵。点击精灵框上的鼠标左键,资源浏览器 将显示资源树中所有可用的精灵列表:
然后,你可以选择一个用于该物体。使用分配给物体的精灵,你可以单击编辑编辑精灵按钮 来更改精灵属性,或者该物体没有精灵,但你希望它拥有,那么你可以单击添加精灵按钮 将精灵分配给该物体。你还可以通过单击编辑图像按钮 来打开图像编辑器,来编辑已分配的精灵资源图像。
在精灵分配区域下方,你可以选择一个特定 碰撞遮罩 的按钮。默认情况下,一个物体将使用分配给它的精灵的碰撞属性,但是有时你可能希望碰撞有不同的遮罩形状。例如,在你的竖版游戏中,主要的精灵有一个矩形的碰撞遮罩,但是使碰撞更平滑的圆形遮罩可能会更好。在这些情况下,你可以单击 “碰撞遮罩” 按钮并选择另一个精灵资源,因此现在该物体的实例将使用指定的精灵 绘制 ,但碰撞基于 遮罩 精灵。
在这里,你将看到物体的以下选项:
可见 表示房间启动时此物体的实例是否可见。通常选择可见,但是有时不可见也是有用的 - 例如,可以使用点方式控制怪物移动,或者跟踪并进行一定的动作。不可见的物体仍然会对事件作出反应,如果它们有精灵或者遮罩也会发生碰撞事件,它们只不过是不可见并且不会执行 绘制 事件。该选项默认勾选。
当你将实例标记为固体时,你会告诉 GameMaker Studio 2 它应该在触发 碰撞事件 之前尝试解决任何碰撞。这是一个 非常 基本的功能,实际上它所做的只是将实例移回到检测到碰撞之前的那一刻,然后再执行事件本身中的任何代码或 DnD™,因此它的用处有限。
持久化 - 持久化物体是房间改变时不会消失的物体,而是“持续存在”并被转移到新房间中。只有当你手动地销毁它或者使用销毁动作或代码时,它才会消失。这意味着如果将永久物体放在一个房间中,它仍然可以在所有后续房间中使用,并将继续执行分配给其物体属性中的事件的任何操作,除了 创建事件,这只是在最初创建时才被触发一次,而不是当你更改为新房间时才被触发。
当你的主角从一个房间移动到另一个房间,并且你想保持某物体中的变量不变的时候,使用“持久化”很方便。但你应该非常小心地创建和销毁持久性物体,因为这很容易出错。
还要注意,持久化物体仍然会触发游戏开始、游戏结束、房间开始和房间结束事件,但是如果你重新启动游戏(例如,使用game_restart() 函数),所有保持物体都将被删除,并且只有在游戏再次创建时才存在。另请注意,如果你释放持久性物体,它将不会再从一个房间传递到另一个房间,除非在客户端事件触发之前重新启动。
当你勾选 使用物理 选项时,你告诉 GameMaker Studio 2 该物体应该是 物理世界 的一部分。检查此操作还将打开一个进一步链接的窗口,你可以在其中定义该物体的所有实例的物理属性。有关这方面的更多信息,请参见下一页的 物理学 部分。
选项部分定义物体的不同属性选项,以及实例放置在房间中时的行为方式。在这里,你可以添加事件,即游戏代码的“构建块”,设置物体是否具有父物体,如果要启用物理功能,还可以设置物理属性。
那么,什么是事件?基本上,事件是在游戏循环中重要的时刻,根据你为它们编程的内容而发生事情。GameMaker Studio 2 适用于这些事件的循环 - 从房间开始到完成的那一刻,每一 步 (步是游戏时间的一个时刻,由房间速度设置决定)都有一个游戏循环运行或检查一系列事件,你可以选择在物体中放置响应这些事件的代码或 DnD 动作。
我们来看一个典型的物体设置,包括事件和代码:
正如你可以在我们的示例物体中看到的那样列出了许多应该响应的事件,但是最初当你创建一个物体时,这个列表是空的,你必须决定你需要哪些事件,那些物体应该做什么事件被触发。要将事件添加到物体中,请按事件列表底部的 添加事件 按钮,弹出以下窗口:
这是物体可以响应的所有基本事件的列表,尽管其中一些事件还具有 子事件 以进一步改进行为。例如,如果你添加一个按键 事件,你将会再次弹出一个子事件,让你选择该物体应该响应的键。选择你的事件后,代码窗口 将被链接到右侧并打开。你现在可以编辑代码,为你的物体提供特定的行为或对该事件的反应。
任何事件都可以单击鼠标右键 获取以下菜单选项:
这些选项是:
- 添加事件 - 从事件列表中添加新事件。
- 剪切/复制/粘贴事件 - 剪切,复制或粘贴所选事件。你也可以使用标准键盘快捷键: / + X、/ + C 和 / + V。
- 重复事件 - 复制所选事件。这将取代所选事件的内容,并在你指定的另一个事件中复制它们。
- 更改事件 - 更改事件。这将提示选择另一个事件类别,,一旦选中,当前事件的内容将更改为新事件(删除过程中的原始事件)。
- 转换为拖拽 / 代码 - 将使用你在创建项目时选择的方法(使用代码或使用拖拽动作)创建物体事件。使用此选项,无论项目类型如何,都可以将其从一个转换为另一个。
- 删除事件 - 删除事件(或多个事件)。
删除事件时,可以使用 + 选择多个事件,然后将它们全部删除。
你还应该注意,你可以 命名事件,或至少给它们一个简短的描述性文本,将在事件编辑器旁边显示。为此,只需将以下内容添加到事件代码编辑器的第一行:
/// @description 在这里输入你的文本
所以,你可能会有这样的东西 - 例如 - 一个计时器事件
/// @description 这是 AI 战斗计时器
现在在你的事件编辑器中,你将看到:
请注意,上面的事件部分简要概述了它们的工作原理,但是有关所有可用事件的详细信息,请参阅以下部分:
物体的其他选项是:
使用 GameMaker Studio 2 IDE 中的物体时,可以设置父/子层次结构。这可以通过单击物体编辑器中的 “父物体” 按钮,然后从资源树中选择另一个物体作为正在编辑的物体的“父”:
所以,游戏项目中的每个物体都可以有一个父物体,但这是什么意思?那么当一个物体分配了一个父物体时,它可以与该父物体共享代码,动作和事件。这种共享称为“继承”,具有父物体的物体称为“子”物体。子物体不仅可以与父物体共享代码,而且可以在父物体上执行检查和运行代码,并且还会自动包含子物体,从而节省了大量的时间和精力。
如果这听起来很复杂,那么另一种查看父物体的方法就是将物体“组合”在一起,同时保持共享,让它们分享某些东西,而不会失去自己独特的身份。也许这还没有说清楚事情,所以让我们举一些例子
假设你有一个“玩家”物体和四个不同的“敌人”物体。现在,如果他触摸到这四个物体中的任何一个,你想要玩家死亡,这通常会导致四个不同的碰撞事件与四个不同的动作或代码集合,一个对于每个敌人物体。但是,如果我们为所有敌人设置一个 父 物体,那么我们可以仅使用父物体创建一个碰撞事件。这样,无论是哪个“子”敌人碰到了主角,都将触发碰撞事件。贼方便!在实际的 GameMaker Studio 2 物体中,你会看到如下所示的内容:
在左边,我们有四个单独的碰撞事件,右边我们有一个碰撞事件,因为我们创建了一个“父”物体,并分配了所有的敌方物体。请注意,父物体不必在其中包含任何事件或代码...
父物体的另一个例子是:在你的游戏中,如果你想要创建 10 个不同的外观物体,但你要它们它们都以相同的方式运行。为此,你将创建一个父物体,并在其中包含所有行为操作或所需事件中的代码,然后你将创建 没有 动作或代码但具有不同精灵的十个物体,并将它们分配给你的父物体。现在,当你把这些实例放在一个房间里时,它们都会表现得相同(它们的父物体相同),但是看起来是不同的(它们的精灵不同),因为它们会“继承”父物体的事件。
最后,你可以使用父物体处理来“混合搭配”事件和行为。我们将用一个最后的例子说明这一点... 假设你想要两个怪物:一个上下移动,另一个是左右移动,但是你也希望它们中的两个人具有相同的生命值、射击玩家动作,并且如果与它们碰撞,会伤害到玩家。在这种情况下,你可以看到几乎所有事件应该具有相同的操作,除了那几个移动的控制。因此,我们可以使一个物体成为另一个物体的父物体,但在这种情况下,我们也定义子物体的某些事件。这些事件“覆盖”父事件,这意味着每当一个子物体的事件包含操作时,这些事件将被执行,而不是父事件中包含的操作。如果你还想执行父事件,则可以使用函数 event_inherited() 或 DnD™ 动作调用父事件来调用 所谓的“继承”事件。
在左上方是其中有 5 个事件的父物体,右边可以看到“子”物体。子物体中还有 5 个事件,但其中两个 覆盖 父物体中的继承事件(步 和 回执 事件),其他三个灰显,因为它们是从父物体继承的事件。在事件编辑器中,继承的事件旁边还会有“父覆盖”图标:
当你单击 已继承的事件时,它将打开代码编辑器以显示继承的父代码,但你将 无法 编辑此代码,因为你只能在父物体本身中编辑它。 你可以在任何父事件上单击鼠标右键 以打开以下选项菜单:
在这里,你可以选择两个 打开 父事件来检查代码,或者你可以选择 继承 事件或 覆盖 事件。 如果选择 继承,则代码编辑器将打开,其中已添加了函数 event_inherited()(如果使用 DnD™,则为 调用父事件 动作)。现在将运行你在此事件中放置的任何其他代码 以及 父物体具有的代码。如果你选择 覆盖 事件,那么代码窗口也将打开,只是现在不会调用 event_inherited() 函数,因此将运行你在此处添加的任何内容 而不是 父物体中的代码。
注意:在代码编辑器中,你可以通过单击鼠标右键 并从弹出菜单中选择 转到物体 快速导航到父物体,或者(如果事件已被覆盖),你可以选择 打开继承事件 直接进入到包含父事件代码的代码编辑器。
每当你在代码中定位父物体时,代码也将应用于父物体的“子物体”。如果在操作中指示操作必须应用于某个物体的实例,并且在代码中使用 with() 语句时会发生这种情况,则会发生这种情况。 当你调用代码函数时,它也会像这样工作,比如 instance_position、instance_number 等......如果你提供父物体,那么父 和 子实例的所有实例都将包含在检测中。最后,如果将敌人 1 的速度设置为 10,敌人 2 的速度也将变为 10,因为它是敌人 1 的子物体,所以在你参考其他物体中的变量时,父物体也可以工作。在大多数情况下,通常认为创建一个基本父物体是良好做法,并且该基础物体包含所有默认行为,但不要在游戏中使用它的一个实例。而是使用所有子物体,仅在我上面概述的情况下使用父物体,用于冲突,引用变量等... 你也应该意识到,父物体也可以有父物体!显然你不能创建一个循环 “父物体 1 是父物体 2 的孩子,而父物体 2 又是父物体 1 的孩子”,但是你可以创建所谓的“物体层次结构”,其中 “父物体 3 是父物体 2 的孩子,父物体 2 是 父物体 1 的孩子”。这对于保持游戏结构非常有用,并且强烈建议你学习使用此机制。
当你首次创建新物体资源时,会有一个名为为 使用物理 的复选框,默认情况下不会勾选。选择此选项将会将物体的实例放置在房间中时彻底改变物体的行为,因为它会切换物体的物理属性,并意味着其“传统”运动和碰撞功能不再有效(但只有当被放置的房间也被标记为物理时)。请参阅 - 房间编辑器)。检查时,物体资源窗口将打开物理编辑器的新链接窗口:
在开始编辑物理行为的值之前,首先设置 碰撞形状 是个好主意。使用“正常”碰撞系统,你的碰撞是基于分配给物体的精灵,但是当物理启用时不再是这样。我们需要自己为物体分配一个 碰撞形状(这被称为固定装置,有关更多信息,请参阅 物理函数),它可以是你自己定义的圆形、矩形或多边形。单击 修改碰撞形状 按钮将打开以下链接窗口以编辑形状:
这看起来与 路径编辑器 类似,并且功能大致相同。然而,根据你选择的遮罩,它可能会更具限制性:
- 如果你选择 圆形 遮罩,则只能拉任何路径点,使圆直径更大或更小
- 如果你选择 矩形 遮罩,则可以移动四个角中的任何一个,但相应的角将自动调整位置,以始终保持矩形
- 如果你选择 自定义(多边形)遮罩,它必须至少有 3 个点,最多有 8 个点,并且必须为凸面(请参见下图)。
一旦你设置了你的形状,你需要定义你的物体的基本物理属性。这些通过更改以下参数进行配置:
某物的密度定义为其 每单位体积的质量,也就是说它在游戏世界中占据的空间应该有多少质量。所以气球的密度很小,因为它的质量很小,占据很大的空间,而铅棒的密度很高,因为它的质量很大,而且空间很小。在 GameMaker Studio 2 2D 物理世界中,质量是根据你为密度输入的值和你为固定装置定义的形状的表面积自动计算的。这将直接影响固定装置具有多少惯性以及如何对碰撞和力产生反应,因此,如果你制造出高密度的小形状,则会产生非常大的质量效应(如铅棒)但是如果你定义了一个较小密度的大形状,那么它的质量效应会更小(像一个气球)。
在物理学中,恢复原则被定义为 “弹性变形后物体或系统返回到原始状态”,但是由于 GameMaker Studio 2 中的固定装置实际上是 刚体,不能形变,所以恢复实际上是一种表示固定装置有多大“弹性”的方式。此设置将影响物体在与其他物体碰撞时 “弹跳” 多少,并且与重力和摩擦力作用于实例上的其他力相配合。
默认情况下,所有物理物体的碰撞组是 0,这意味着它们将正常相互作用,这又意味着它们 必须有一个碰撞事件进行交互 (一个简单的解释是将会触发碰撞),否则不会发生碰撞。但是,你也可以指定物体应属于特定的 碰撞组。通过将物体分配给一个正面的碰撞组(例如:三个物体全部在组 “2” 中),则你是在告诉 GameMaker Studio 2 这些物体的实例即使在碰撞事件中没有任何东西也应该 总是碰撞 的,服从你分配的物理属性和他们所在的空间。相反,如果你有具有负碰撞组的物体(例如:四个物体分配为 “-1”),则你是在告诉 GameMaker Studio 2 这物体象 永远不会发生碰撞,并且它们之间的任何碰撞事件都将被忽略。
注意: 使用碰撞组会大大增加物理系统所需的处理能力,并且只有在绝对必要时才能使用,并且你应该尽可能少地使用组。
阻尼用于降低实例的物理世界速度,并且与摩擦不同,因为摩擦力仅在碰撞形状(弹性)的两个实例接触时才发生。模拟阻尼比摩擦要容易得多,但请注意,阻尼不是摩擦的替代品;这两个效果可以而且应该一起使用。
如果你考虑“现实世界”中的任何旋转物体,除非有电机或空间,否则由于外力(如与其周围的空气的摩擦)的影响,它会随着时间的推移而减慢。我们可以设置这个选项来模拟这个效果,减少物理世界中的实例的旋转速度,因为没有它,任何旋转的实例将继续无限旋转。
摩擦力是抵抗物质元素彼此滑动的相对运动的力量,在 GameMaker Studio 2 物理世界中,由于两个实例与固定装置之间的撞击而造成的动量损失,这种力量将会转化为物理因素。所以当两个实例碰撞时,它们的运动受到这个值的影响,高摩擦力将导致更大的动量损失。
最后,固定装置有三个额外的选项可以标记为打开或关闭,即:感应器、初始唤醒和运动这些选项中的每一个将通过以下方式改变你的固定装置的行为:
选中此框,你就告诉了 GameMaker Studio 2 基本上 “忽略” 物体的物理属性,但仍会返回与其周围的物体的碰撞事件。以这种方式,你可以拥有一个在房间中没有物理存在的实例,但是可以对另一个实例(如玩家)的碰撞做出反应,并依次执行某些操作,例如打开门,或与放在房间中的另一个实例触发某种动作。
注意: 当碰撞 首次发生时,感应器固定装置将触发碰撞事件,这意味着当两个物体继续重叠时,你不会得到碰撞事件流。(一般来说是这样)。如果它们停止重叠并且随后再次重叠,则会触发另一个碰撞事件。
默认情况下是勾选的,它表示在其放置的房间开始处的固定装置的初始“状态”。通常你希望它从一开始处于激活状态(即:参与物理世界),但是由于物理模拟的突然启动,有时这可能会导致某些不稳定和不必要的影响。为了避免这些影响,你可以取消选中此标志,并使用固定装置创建实例让实例暂时睡眠(即不激活)。除非有事情和该实例有关联,否则它不会参与物理模拟。
基于物理的游戏将会有一些你想要移动的实例,但不希望被诸如重力等力和与动态物体碰撞所产生的力量所影响(例如,在平台游戏中考虑移动平台)。对于这样的物体,简单地将固定装置的密度设置为 0 将意味着,在物理学上将假定该物体不会对任何事情产生反应。但是,勾选此框将使静态物体能够运动,这样你可以可以使用适当的变量去移动或旋转它,尽管它不会受到重力和碰撞的影响。
当你单击 变量 按钮时,它将打开 物体变量 窗口,然后你可以在 创建事件 之前 使用该窗口生成任意数量的变量:
在此窗口中,你可以单击 添加新变量 按钮 将新变量添加到列表中。然后,你可以命名变量,并设置它必须使用的变量 类型 并调整其属性:
变量名必须以字母开头,并且 只能包含字母,数字和下划线符号 “_”,最大长度为 64 个字符。因此,有效变量是诸如 fish、foo_bar 和 num1 之类的东西,无效变量将是 6fish、foo bar 或 *num。一旦给出了变量的名称,就需要设置其类型,可以是以下任何一种:
值得注意的是,在使用父/子实例时,此功能特别有用 - 因为你可以拥有一组带有一组已定义变量的父物体,然后只需在子物体中修改它们(更多细节请参阅下面的 物体变量和子物体) - 以及何时将实例添加到 房间编辑器 中(请参阅层 > 实例层 部分),因为你还可以为放置在房间中的各个实例修改这些变量。
你可以创建的不同类型的变量如下所示:
- 实数型(Real): 实数是任何非整数的数字,可以是正数或负数。所以,124.5、45639.566546456、0.9、-45.5等......都是实数的例子。所有实数都存储为 64 位双精度浮点型。 请注意,你可以从 变量选项 中设置输出实数型的值范围(有关详细信息,请参见下文)。
- 整型(Integer): 整型是整数,可以是正数或负数,例如 30004、19、0、-300。请注意,你可以从 变量选项 中设置输出整型的值范围(有关详细信息,请参见下文)。
- 字符串型(String): 字符串是放在双引号内的内容,例如“fish”、“Hello World” 或 “12345”。
- 布尔型(Boolean): 布尔值是 true 或 false 的值。 在 “物体编辑器变量” 窗口中,这只显示为一个框,你勾选时为 true,取消勾选时为 false。
- 表达式(Expression): 表达式是一个数学短语,可以包含普通数字、变量、字符串或 GML 函数以及一个或多个 运算符。 例如,sqrt(85 * 6) + 5.5 是表达式。
- 资源(Resource): 资源是你在资源树中定义的任何一种资源。选择资源类型后,可以单击 打开资源浏览器 按钮 以打开 “资源浏览器” 并选择所需的资源。 请注意,你可以从 变量选项 中为资源浏览器中显示的资源设置过滤器(有关详细信息,请参见下文)。
- 列表(List): 选择输入的列表类型意味着你可以创建一个可选值(这些可以是字符串、实数、表达式等...),然后你可以为要返回的变量选择一个或多个值。要定义列表中的项目,你需要先将它们添加到 变量选项 中(有关详细信息,请参见下文),然后你能够从主窗口下方菜单中选择一项作为变量的默认值: 请注意,如果在列表选项中 多选(见下文),则变量将成为所有选定选项的数组。
- 颜色(Colour): 颜色类型用于定义要存储在变量中的颜色值。你可以输入实数(从 0 到 16777216,这将具有 255 的透明度),或十六进制值(格式为 $RRGGBBAA),或者你可以双击 颜色样本以打开 颜色选择器 并在那里定义颜色。
一些不同类型的变量将为你提供定义输出值的选项,你可以通过 单击 按钮打开这些选项:
- 实数型 / 整型选项(Real / Integer Options): 实数和整数数据类型可以选择设置值 范围。 检查时,你可以输入起始值和结束值,而不是在“对象变量”窗口中显示变量的固定值,你将有一个限制这些值的滑块:
- 资源选项(Resource Options): 将打开资源选项,其中包含所有可用资源类型的列表,默认情况下将全部选中。但是,你可以单击 其中任何一个以仅选择该类型,也可以使用 / + 或 + 选择多种资源类型。 设置此选项后,资源浏览器中只会显示所选资源类型的变量。
- 列表选项(List Options): 在这里,你可以添加要包含的不同值作为列表类型变量的可能返回值。 你只需单击 添加列表项 按钮即可添加新值(可以是字符串、实数型、整型或资源名称),然后在物体编辑器 “变量” 窗口中,它将显示在默认值的下拉列表中,无论需要哪个你都可以选择: 如果你已选中 多选 选项,则下拉列表将在列表变量返回的每个值旁边都有复选框(变量将成为保存每个值的数组):
物体变量的一个重要特性是它们由资源树中的任何子物体 继承(请参阅上面的 父物体 部分),这意味着你可以选择覆盖或更改它们中的任何一个或全部。当你创建另一个为其定义了变量的物体资源的子物体时,它们将显示在 “物体变量” 窗口中,如下所示:
你可以在顶部图像中看到父物体具有四个物体变量,在底部图像中也显示这些物体变量,仅显示 “灰色” 并具有 从父物体继承 图标 以指示它们已被继承。如果单击 覆盖变量 按钮 ,则可以编辑这些继承的变量,这样你就可以调整范围滑块或值,或者从列表中选择不同的项目等等。请注意,编辑父变量时只能更改定义的值而不能更改名称,也不能更改变量选项。另请注意,你也可以向子物体添加新的物体变量(在上面的示例图像中,你可以看到 “字符类型” 仅是子物体的新物体变量)。
如果已编辑了继承的物体变量,则可以单击 删除 按钮 以删除编辑过的内容,但不删除变量。该变量仍将从父物体继承,但将再次使用父物体默认值。 如果需要完全删除变量,则必须从父物体执行此操作。