move_and_collide

此函数将实例在 X 轴和 Y 轴上移动给定的距离,同时避开给定的对象或图块地图。

它允许您的实例在导航坡度或小步骤时移动,否则它将无法移动。

该函数返回一个 数组 ,其中包含与其发生碰撞的实例和图块地图的 ID。

对象参数

除了对象和实例之外,该函数还接受:

传递数组允许您在一次调用中检查多个对象和 / 或图块地图的碰撞。

它是如何工作的?

该函数将逐步移动您的实例,在每个步骤 / 迭代中检查碰撞。obj 参数是它应该避免的对象、实例或 图块地图 ,默认情况下,该函数分 4 步移动您的实例 (您可以使用 num_iterations 参数进行更改)。

在每一次迭代中,它都会按 point_distance(0, 0, dx, dy) / num_iterations 像素向指定方向移动你的实例,然后检查是否有碰撞。如果 num_iterations 是 4,而你想移动 (8, 0),  它将在检查碰撞之前,每次迭代将你的实例移动 2 像素。

如果在迭代过程中发现了碰撞,它将尝试在垂直于dx, dy的方向上移动你的实例,或者朝着可选的xoff, yoff参数中给出的矢量移动,从而绕过它。

如果在任何迭代中,函数在 dx, dy方向发现了碰撞,并且能够绕过它(无论是在垂直方向还是在xoff, yoff方向)移动,在该其他方向的移动将被算作一次迭代。

速度限制

可选参数 max_x_movemax_y_move 允许您指定实例可以在 X 和 Y 轴上移动的最大距离。

这可以避免跳台中的一个常见问题,即玩家落地时向下的速度(重力)与其水平速度相加,使其在一帧中走得更快。

NOTE 该函数使用实例的精灵碰撞遮罩(sprite mask)来检查碰撞(详见The Sprite Editor )。

 

语法:

move_and_collide(dx, dy, obj, [num_iterations], [xoff], [yoff], [max_x_move], [max_y_move]);

参数类型描述
dxReal试图沿X轴移动的距离
dyReal试图沿Y轴移动的距离
objObject Asset or Object Instance or Tile Map Element ID or Array对象、实例、图块地图 ID、所有 / 其他关键字或包含这些项目的数组
num_iterationsReal可选 的步数,例如,如果(dx, dy)(10, 0),步数是5,那么每次迭代时,在检查碰撞之前,实例将移动10/5=2像素。默认值是4。
xoffReal可选 碰撞时移动方向的 X 分量指定 0 将使用默认行为 (垂直移动方向)
yoffReal可选 碰撞时移动方向的 Y 分量指定 0 将使用默认行为(垂直移动方向)
max_x_moveReal可选 实例应在 X 轴上移动的最大速度指定,-1 表示没有限制(这是默认行为)
max_y_moveReal可选 实例应在 Y 轴上移动的最大速度指定,-1 表示没有限制(这是默认行为)

 

返回:

Array of Object Instances

 

例1:基本运动

move_and_collide(8, 0, all);

上述代码将尝试把调用的实例移到右边8个像素处,并避开任何对象的实例(用 all 关键字表示)。由于没有提供num_iterations参数,迭代次数为4。

 

例2:显示与之碰撞的实例

var _colliding_instances = move_and_collide(speed_x, speed_y, obj_terrain);

for (var i = 0; i < array_length(_colliding_instances); i++)
{
    var _collider = _colliding_instances[i];
    with (_collider)
    {
        show_debug_message("Collision with instance {0}", id);
    }
}

上述代码在调用实例中执行了move_and_collide 函数。它试图使用自定义的speed_xspeed_y变量来移动它,并试图避免obj_terrain的实例。调用实例所碰撞的实例被存储在一个临时数组_colliding_instances 并通过for循环和show_debug_message来显示。

 

Example 3: Tile Map

var _tilemap = layer_tilemap_get_id("Tiles_1");

move_and_collide(8, 0, _tilemap);

上面的代码将尝试将调用实例向右移动 8 个像素,并避免与 "Tiles_1" 层中的图块发生碰撞。

由于您只需要获取一次图块地图 ID,因此您可以将第一行移至 Create 事件。