对象事件

那么,什么是对象事件?基本上,这些都是游戏循环中的谨慎时刻,事情会根据你为它们编程的内容发生。GameMaker与这些事件的循环一起工作-从房间开始的那一刻到它结束的那一刻,有一个游戏循环在运行,每一都会运行或检查一系列事件,您可以选择将GML代码GML视觉动作放置在响应这些事件的对象中(每秒游戏帧数是游戏时间中的一个时刻,由每秒游戏帧数设置控制,也可以称为)。

让我们看看一个有事件和代码的典型对象设置。

Object Editor Events ViewAs你可以看到在我们的例子对象中列出了许多它应该响应的事件,但是最初当你创建一个对象时,这个列表是空的,你必须决定你需要哪些事件以及当这些事件被触发时该对象的实例应该做什么。要向对象中添加事件,按下事件列表底部的添加事件按钮,将弹出以下窗口:

Object Editor Events List这是一个对象可以响应的所有基本事件和事件类别的列表,每个类别中都有子事件来进一步细化行为。例如,如果你点击Key Press Key Press Icon 事件类别,你就会弹出一个进一步的窗口,让你选择对象应该对哪个键做出响应。

一旦你选择了你的事件,事件的编辑窗口 将被链到它,并在右边打开。

在这一点上,你可能会被要求在 GML Visual 和 GML Code之间选择。请参阅 GameMaker语言了解更多信息。

现在,您可以编辑GML代码(或块),以给予对象对该事件的特定行为或反应。

你可以在任何已添加到对象的事件上点击鼠标右键RMB Icon ,以获得以下菜单选项。

Object Editor Events Menu这些选项是:

删除事件时,您可以使用Shift Icon+LMB Icon选择多个事件,然后将它们一起删除。您创建的每个对象都有自己的独立事件列表,这些事件是从对象编辑器添加到其中的。这些事件分为两类:

事件的完整列表如下:

Create Event Icon创建创建

这个事件发生在对象的一个实例被首次创建时,也是通过房间编辑器放置在房间里的实例在进入房间时发生的第一件事。这意味着该事件是初始化变量、启动时间线、设置路径 等......以及其他任何通常只需要做一次或只在房间中首次创建实例时做的事情的理想场所。如果你的对象在对象编辑器或房间编辑器中添加了任何对象变量实例变量,那么这些变量将首先被初始化,然后创建事件将被运行。

记住,你可以从房间编辑器中的实例创建代码 中修改你在创建事件中设置的任何内容,因为那是在实例的创建事件之后直接运行的,可以用来创建实例变量 或覆盖作为对象变量或在实际创建事件中添加的任何变量。

注意 房间中的实例是按照一定的顺序创建的,它们的创建事件也是在逐一创建时执行的。这意味着,当你在创建事件中从其他实例中读取变量时,必须小心谨慎,因为其他实例可能还没有运行其创建事件!

例如:假设ObjectAObjectB之前被创建,而你在这些对象的创建事件里有以下代码:

ObjectA Create - myValue = objectB.myValue;
ObjectB Create - myValue = 10;

ObjectA先被创建,它的创建事件运行,然后游戏崩溃:

"Variable objectB.myValue(100003, -2147483648) not set before reading it."

这只是因为ObjectB还没有被创建,所以在其创建事件中初始化的任何变量还不存在。这就是为什么当你在创建事件中引用其他实例 时必须谨慎,包括在with()块内运行的任何代码。

 

Destroy Event Icon销毁销毁

这个事件是一个实例被销毁时要执行的事件。在给对象添加行为时,它经常被忽略,但它可以非常有用,例如,当敌人被杀死时,它可以产生爆炸或粒子效果,或者在房间的另一个地方重新生成对象的新实例,甚至可以在分数上加分。

 

Clean Up Event Icon清理清理

此事件将在任何从房间中删除对象实例的事件之后调用。因此,如果出现以下情况,则会触发此事件:

它被设计用于"清理"游戏中可能存在的任何动态资源(如表面、数据结构等),或者在实例以任何方式从游戏中移除时执行需要执行一次的任何任务。

请注意,此事件将在触发它的事件之后立即被调用,但直到当前事件结束时,实例才会实际从游戏中移除。例如,如果您在Step Event中调用instance_destroy(),则会调用Destroy Event,然后是Clean Up Event,然后步骤事件的其余部分将完成运行。这意味着在调用instance_destroy()之后,您拥有的任何代码仍将运行,并且如果您已经清理了代码所需的数据结构或其他资源,则可能会导致错误,因此在使用此事件时必须小心。

 

Alarm Event Icon计时器计时器

计时器类别被分成12个事件,每个事件对应一个实例中可能设置的计时器。因此,当你点击添加计时器类别时,你会看到这个窗口。

Object Editor Alarm Events在这里,你选择你想创建的计时器,一旦完成,你会看到它已经被添加到事件窗口,允许你像平常一样向它添加代码。但什么是计时器打响?嗯,它是一个特殊的事件,除非事先设置了计时器,否则它不会做任何事情,它将等待计时器倒计时到0,然后再运行你添加到它的动作或代码。

一旦计时器达到0并运行代码,它就会倒数到-1,在那里它将一直保持,直到再次设置(意味着你可以检查计时器的值是否大于-1,这将告诉你它是否正在运行)。所以,假设你在对象的创建事件中把alarm[0]设置为30,这意味着GameMaker将在运行放在alarm[0]事件中的动作或代码之前倒数30步。注意,将计时器设置为0将不会运行计时器代码,因为虽然事件被触发了,但计时器被立即设置为-1,所以代码被跳过。如果你需要一个计时器来运行下一个步骤,那么你应该把它设置为1。

这可能非常有用,因为它允许你用精确的时刻设置事物的运动,你甚至可以让它们重复,因为没有什么可以阻止你在计时器的事件中设置一个计时器。想象一下,你有一个怪物,你想让它每隔三秒钟向右转......好吧,你可以在它的创建事件中设置一个计时器,以room_speed*3(如果房间速度是30,那就是每秒30步,所以乘以3,你就得到了3秒!)然后在计时器事件中,你会有代码或动作来设置它的方向,以及动作(或代码)来设置其计时器为房间速度*3 ;再者。通过这种方式,你可以设置简单的游戏循环,事情只在特定的时间间隔发生。

值得注意的是,一个没有任何动作或代码的计时器将不会倒数。但是,如果 只有注释,没有代码或动作,那么计时器也会继续倒计时,可以像平时一样进行设置和检查。

 

Step Event Icon

GameMaker将时间划分为,游戏速度定义了每秒应该有多少步(一个步骤也可以被称为)。一个步骤,基本上是一个循环,不断运行的所有事件被检查和触发的必要,而游戏运行,所以你可以想象,步骤事件是当实例存在时在游戏的每一步都检查的事件。

步骤事件实际上由三个子事件组成,概述如下。

Object Editor Step Events

注意首先,所有实例运行其开始步骤事件。然后,所有实例运行其步骤事件。之后,所有实例运行其结束步骤事件。

对于大多数情况,使用标准步骤事件都很好,但有时您需要对运行的代码和运行时间进行更多控制,因此为您提供了开始结束步骤事件。每一步都会检查这三个事件,但它们的顺序永远不会改变,即使将来对GameMaker引擎的更新更改了其他事件,这意味着这是唯一可靠的方法来确保某件事总是在另一件事之前发生。

步骤事件可以用来做什么?嗯,它可以用于需要连续执行的动作或代码。例如,如果一个物体应该跟随另一个物体,在这里你可以对我们所跟随的物体的运动方向进行调整,以保持它在后面平稳地移动。不过要小心处理这个事件,不要在物体的步骤事件中放入很多复杂的动作,尤其是当你打算在游戏室里有很多物体的实例时,因为这可能会使游戏变慢。许多事情都可以放入计时器,或者使用一些其他事件设置为触发,而不是一直发生。

 

Collision Event Icon碰撞碰撞

显然,在制作游戏时,你必须知道一个物体的两个(或多个)实例发生了碰撞,为此我们有碰撞事件。这是一个你放置在一个对象中的事件,然后指定你应该针对哪个其他对象来检查碰撞。

当你没有开启物理时,这些碰撞将根据两个物体的遮罩(遮罩在精灵属性中定义,或者可以在物体属性中独立分配)以及它们是否重叠来计算。请注意,如果碰撞中的一个或另一个实例没有分配掩码(或者精灵掩码被设置为无),即使它正在绘制什么东西也不会被检测到碰撞。

如果物理是启用的,那么碰撞将基于你在物体的物理属性中为其定义的碰撞形状Fixture)的类型,以及它对碰撞的反应。这意味着你可能不需要任何代码来处理碰撞,但这个事件仍然需要至少有一个注释在里面,以便检测碰撞。

最后,应该注意的是,在碰撞事件被触发之前,所有的碰撞将在每个游戏步骤中被计算一次,这样,当碰撞事件运行时,所有的碰撞都已经被计算并预先分配了。这意味着,如果你在这个事件中创建了一个实例,然后试图用它来检查碰撞,那么在游戏循环的下一次迭代之前,碰撞将不会被检测到或解决。

 

Keyboard Icon键盘,键盘,   Keyboard Press Icon键盘按下,键盘按下,  Keyboard Release Icon 键盘松开键盘松开

让玩家控制你游戏的不同方面是非常重要的,为此GameMaker为你提供了一个非常全面的键盘事件列表,可以在三个主要的键盘类别中的任何一个使用。对于一般的键盘类别,只要选定的键被按下,它就会被连续触发 每一步 ,而按压和释放类别的事件只会在最初按压或释放键时被触发一次。

应该注意的是,每当使用一个键时,键盘事件实际上会在房间里的所有活动实例中被触发,但只有那些为该特定键定义了事件的实例才会做出反应,你可以在任何对象中创建多个键盘事件,在游戏运行时,该对象的实例会对所有事件做出反应。

当你向一个对象添加任何键盘事件时,你会看到键盘子事件菜单,你可以指定你要检查的键:

Object Editor Keyboard Events它们中的大多数是相当明显的,但让我们简单地浏览一下这些部分--在顶部我们有方向键,其次是最常用的修改键,然后是键盘的其他部分(分成更多的子部分,这样你就可以得到所需的确切键,如Escape Icon 或 Insert Icon),最后是两个非常特殊的子事件,No KeyAny Key。正如它们的名字所暗示的,这些是检查键被按下时或任何键被按下时的子事件。请注意,数字键盘上的按键只有在数字锁被启用时才会产生相应的事件。

键盘的PressRelease 事件与常规键盘事件几乎完全相同,只是它们不是连续触发,而是只触发一次。当键盘第一次记录到一个键被按下时,它将产生一个键盘按下事件(以及一个常规的键盘事件),之后第一次不再检测到一个键被按下时,它将触发一个键盘释放事件。

重要调试覆盖层打开并接管键盘和/或鼠标输入时,GameMaker不会执行键盘和鼠标事件。模拟按键也不会执行事件。但是,您仍然可以在Step事件中使用键盘输入鼠标输入功能,例如,检查输入。您还可以使用event_perform功能及其类似的。

 

 Mouse Icon鼠标鼠标

鼠标类别被分成一系列的事件,可以选择这些事件来给你一个更精确的控制你的游戏中发生的事情。在这里你可以看到这些事件到底是什么。

Object Editor Mouse Events左边LMB Icon,右边RMB Icon 和中间MMB Icon 按钮事件(无论是正常的,按下释放)都对具有事件的实例的遮罩起作用。这意味着当这些按钮被用于具有鼠标事件的实例的碰撞遮罩时,GameMaker将检查鼠标在房间中的位置。如果与实例边界框有"碰撞",则事件将被触发,因此,请确保具有这些事件的任何实例都有一个带有有效碰撞遮罩的精灵,或者对象有一个在对象属性中选择的遮罩精灵。正如它们的名称所暗示的那样,这些事件将在第一次按下或释放所选鼠标按钮时触发一次,或者在按钮保持不变的每一步中连续触发。

鼠标进入和离开事件也与按钮事件类似,它们也依赖于实例的掩码来工作,但这次它们是在鼠标第一次 "进入"(触摸)实例或鼠标 "离开"(停止触摸)实例时触发的。然而,这些事件不是连续的,每当鼠标进入或离开对象时只被触发一次--所以它们是一种理想的方法,例如,创建需要在鼠标悬停时改变的按钮,当鼠标移开时又恢复正常。

最后,我们还有一个鼠标事件的部分,叫做全局鼠标。在这个子菜单中,你会发现有一些事件是用来记录实例中的鼠标事件的,即使鼠标不在它们上面,甚至不在它们附近。这些事件是为所有实例生成的,如果有为指定事件定义的动作或代码,那么它将被运行,无论鼠标在游戏中的位置如何。

注意在移动的或触摸屏设备上,鼠标左键LMB Icon也可用于检查触摸屏上的手指标签,鼠标右键RMB Icon由双击屏幕触发(可使用代码更改此行为)。

重要调试覆盖层打开并接管键盘和/或鼠标输入时,GameMaker不会执行键盘和鼠标事件。模拟按键也不会执行事件。但是,您仍然可以在Step事件中使用键盘输入鼠标输入功能,例如,检查输入。您还可以使用event_perform功能及其类似的。

 

Gestures Icon手势手势

这个事件是由用户触摸屏幕(在手机上)或点击并移动鼠标(在所有其他平台上)而触发的。这些事件类似于鼠标事件,你有常规版本和全局 版本。这些事件的常规版本只有在触摸发生在有精灵(或掩码)的实例上,并且触摸发生在其边界框内时才会被触发。然而,这些事件的全局版本将由用户在屏幕上的任何地方触摸而触发。

手势事件 检测 如下。

Object Editor Gesture Events不同的事件总是包含一个名为"event_data"的DS地图,它将包含一些带有触摸/点击位置和移动数据的键/值对。关于所有可用的子事件以及它们如何工作的全部细节,请参见以下章节。

  

Other Icon其他其他

在用GameMaker制作游戏时,有一些特殊的事件,它们大多被分组在其他事件下,可以从你选择这个时出现的子事件的弹出菜单中选择。下面是所有这些其他事件的图片。

Object Editor Other Events关于上面图片中列出的每个事件的更多信息,请参见以下部分。

 

Draw Event绘制绘制

这个事件类别是支配你在运行游戏时在屏幕上看到的东西,它被分成各种不相关的事件。

Draw Events正如你所看到的,绘制事件类别有多种不同的事件类型。Draw BeginDrawDraw End是 "标准 "的绘制事件,你可能最常使用。默认情况下,每一个实例都会被调用主绘制事件,不管它是否有精灵,不过如果你将实例标记为不可见,该事件将不会被触发(所以如果你在不可见对象的绘制事件中设置了任何游戏逻辑,请记住这一点,因为它不会运行)。主绘制事件也是GameMaker默认绘制实例精灵的地方,当事件中没有代码或动作时(即:你没有把它添加到对象的事件列表中)。默认绘制使用与实例相关联的精灵,并将在代码中设置的任何转换或应用的动作中绘制。

标准的绘制事件是在绘制GUI事件之前Pre DrawPost Draw事件之间,这意味着在这个事件中绘制的所有东西都在绘制GUI事件的下面,而不考虑图层(即:在绘制GUI事件中绘制的东西总是在普通绘制事件中绘制的东西上面,而不考虑图层顺序)。

请注意,以上只是对Draw Events工作方式的概述,但关于所有可用的子活动的全部细节,请参见以下章节。

  

Async Event异步异步

这个事件类别很特别,因为它所包含的事件不是由GameMaker默认触发的,而是由其他一些动作的结束而触发的,比如加载一个文件,或者来自网络服务器的回复。该类别被分割成以下事件。

Object Editor Asynchronous Events

所以,说你想添加一个图像文件到GameMaker。那么,你可以在一个对象的另一个事件(也许是创建事件)中编码,然后让这个对象在等待时画一个加载条(例如),轮询适当的异步事件,直到告诉GameMaker文件已加载的回调。然后你可以使用这个事件中返回的数据来做其他事情,比如换房间,或者购买物品。

请注意,以上只是对异步事件如何工作的概述,但关于所有可用的子事件的完整细节,请参见下面的章节。

 

 

你还应该注意,你可以给事件命名,或者至少给它们一个简短的描述性文本,在事件编辑器中显示在它们旁边。要做到这一点,只需在事件的代码编辑器的第一行添加以下内容(当使用GML代码时)。

/// @description Your text here

因此,你可以在--例如--一个计时器事件中拥有这样的东西。

/// @description This is the AI Fight alarm

现在在你的事件编辑器中,你会看到这个:

Object Editor Named Events

对于 GML Visual用户来说,添加注释需要使用 Execute Code 动作,这个动作应该放在事件的动作的最上面,在所有其他动作之前。当你添加这个动作时,你再给它加上上面显示的那行代码,以命名该事件,例如。

Naming An Event In DnD关于上述一些活动的其他信息和一般活动的运行顺序,请见以下章节: