事件、时刻和广播消息的序列

除了这里为序列结构列出的所有属性之外,还可以在序列中添加特殊的"动作"属性。有三种不同类型的这些"动作"属性可以添加到序列对象-事件时刻广播消息,以下各节将更详细地解释这些属性。

序列事件

序列对象可以添加事件,这些事件类似于对象资源使用的事件。分配给序列对象的事件将以特定顺序发生,或在序列生命周期中定义的时刻发生一次,或序列正在运行的每个帧发生。在本节中,我们讨论如何使用代码处理这些事件,但也可以使用序列编辑器添加这些事件。 请注意,此处列出的事件顺序不受播放头方向的影响,即使序列正在反向播放,事件仍将按以下顺序运行。

可用的事件包括:

所有事件都需要与在脚本中定义的函数相关联,因此要设置事件,必须将方法变量分配给具有正确名称的属性,该属性告诉事件调用该函数的顺序。其语法如下:

<sequence_struct>.<event_property> = method(<sequence_struct>, <function_name>);

不同事件的序列结构属性如下:

举一个使用的例子,假设我们想要序列在检测到鼠标左键单击时反转方向。我们首先需要创建一个脚本,其中包含我们想要调用的函数,如下所示:

/// @function seq_reverse();

function seq_reverse()
{
    if (mouse_check_button_pressed(mb_left))
    {
        if (self.headDirection == seqdir_right)
        {
            self.headDirection = seqdir_left;
        }
        else self.headDirection = seqdir_right;
    }
}

在这个函数中,我们所做的就是听鼠标按一下,然后反转方法绑定到的序列的播放方向。您会注意到,当前您无法向链接到这些属性的函数传递任何参数,并且在所有情况下,函数范围内的self变量都被指定为序列实例。

注意 值得注意的是,在上述脚本中,self 标识符可以省略,仅用于显式显示本示例中使用的方法变量的范围。

要将其分配给序列,您需要执行以下操作:

var _seq = sequence_get(Sequence1);
_seq.event_step = method(_seq, seq_reverse);

现在,我们已经为序列对象分配了一个步骤事件,该事件具有一个函数,用于检测何时按下鼠标,然后在房间中创建序列实例后更改其播放头方向。

序列时刻是在播放序列时在一个或多个指定帧上触发的唯一代码操作。这些代码矩类似于在给定帧上触发的事件(上面解释的)简单预定义的方法变量。例如,假设您想要在动画的特定帧上创建"项目符号"实例的序列首先需要创建用于此操作的函数,如下所示:

/// @function seq_shoot();

seq_shoot = function()
{
    instance_create_layer(sequence.xorigin, sequence.yorigin, "Instances", obj_Bullet);
}

然后,您可以将此添加到序列结构的momentKeyframes属性中的帧中。这本质上是一个"特殊"轨迹,仅用于此目的,因此只能获取与您希望序列具有的瞬间操作相关联的关键帧数据。通过创建关键帧结构并填充关键帧数据(通道 0 是唯一可以使用的通道,轨迹类型为seqtracktype_moment),创建此轨迹的方式与创建任何其他轨迹的方式基本相同。 下面是如何使用我们上面定义的函数在给定时刻(帧)上激发该值的示例:

var _seq = sequence_get(my_Seq);
var _k = array_create(3);
_k[0] = sequence_keyframe_new(seqtracktype_moment);
_k[0].frame = 60;
_k[1] = sequence_keyframe_new(seqtracktype_moment);
_k[1].frame = 120;
_k[2] = sequence_keyframe_new(seqtracktype_moment);
_k[2].frame = 180;
var _d = array_create(1);
_d[0] = sequence_keyframedata_new(seqtracktype_moment);
_d[0].channel = 0;
_d[0].event = method(_d[0], seq_shoot);
_k[0].channels = _d;
_k[1].channels = _d;
_k[2].channels = _d;
_seq.momentKeyframes = _k;

上述代码将简单地设置"时刻"轨道的帧60、120和180,以调用方法seq_shoot。 您会注意到,当前您无法将任何参数传递给用于每个时刻的函数,并且在所有情况下,函数范围内的self变量都被指定为序列实例(通常不需要使用self,但在某些特殊情况下,它可能很有用)。

序列可以生成广播消息,这些简单字符串沿动画时间线添加到特定帧,当到达时间线中的该点时,该字符串将被广播到监听该消息的所有对象实例。您可以使用序列编辑器将这些消息添加到 IDE 中,但也可以使用代码创建和编辑这些消息。

要使用GML在序列上创建广播消息,需要将它们添加到序列结构的messageEventKeyframes属性中的帧中。这本质上是一个"特殊"轨迹,仅用于此目的,因此只能获取与您希望序列具有的广播消息相关联的关键帧数据。通过创建关键帧结构并用关键帧数据填充关键帧数据,创建此轨迹的方式与创建任何其他轨迹的方法基本相同,其中通道 0 是唯一可以使用的通道,轨迹类型为seqtracktype_message。 下面是如何创建示例:

var _seq = sequence_get(my_Seq);
var _k = array_create(2);
_k[0] = sequence_keyframe_new(seqtracktype_message);
_k[0].frame = 60;
_k[1] = sequence_keyframe_new(seqtracktype_message);
_k[1].frame = 120;
var _m1 = array_create(2);
_m1[0] = "Hello";
_m1[1] = "World";
var _m2 = array_create(1);
_m2[0] = "This is a Broadcast Message";
var _d1 = array_create(1);
_d1[0] = sequence_keyframedata_new(seqtracktype_message);
_d1[0].channel = 0;
_d1[0].events = _m1;
var _d2 = array_create(1);
_d2[0] = sequence_keyframedata_new(seqtracktype_message);
_d2[0].channel = 0;
_d2[0].events = _m2;
_k[0].channels = _d1;
_k[1].channels = _d2;
_seq.messageEventKeyframes = _k;

您将注意到,消息文本作为数组传递到关键帧数据通道。这是因为您可以在同一帧上广播多条消息,并让不同的对象实例侦听它们,并根据它们实际期望的消息做出不同的反应。

序列发出广播消息后,您可以使用对象实例中的Other>广播消息事件对其进行解析,此处将对此进行详细说明