0

我刚刚开始使用gamemaker studio 2,我一直在摸索这个。

我需要能够在不使用碰撞事件的情况下销毁我的敌人对象的特定实例。这是我当前的代码:

在我的播放器对象中:

if (sprite_index = spr_player_attack_left) {
    if (obj_enemy.x > x - 25 && obj_enemy.x < x) {
        obj_enemy.hp--;
    }
}

//detect right
if (sprite_index = spr_player_attack_right) {
    if (obj_enemy.x < x + 25 && obj_enemy.x > x) {
        obj_enemy.hp--;
    }
}

//detect up
if (sprite_index = spr_player_attack_up) {
    if (obj_enemy.y > y - 25 && obj_enemy.y < y) {
        obj_enemy.hp--;
    }
}

//detect down
if (sprite_index = spr_player_attack_up) {
    if (obj_enemy.y < y + 25 && obj_enemy.y > y) {
        obj_enemy.hp--;
    }
}

在我的敌人对象中:

if (hp <= 0) {
    var attacked = instance_find(obj_enemy, this.id);
    instance_destroy(attacked);
}

目前房间里只有一个敌人实例记录了一次攻击,当我攻击那个实例时,所有实例都被破坏了,而我只希望一个实例被破坏。

提前感谢您的帮助!

4

1 回答 1

0

发生这种情况的原因是因为您使用的是对象 index,而不是特定实例的索引。当你这样做时:

<object_index>.<object_property> eg. obj_enemy.hp

可能会发生两件事:

  1. 如果游戏中当前有一个实例处于活动状态,则将引用该实例的变量。
  2. 如果有两个或更多实例,则 GameMaker 无法判断您要引用哪一个。

这里有问题的代码是 if 语句:

if (obj_enemy.x > x - 25 && obj_enemy.x < x) {
    obj_enemy.hp--;
}

你可以重写它们的方法是:

with (obj_enemy) {
    if (x > other.x - 25 && x < other.x) hp--;
}

所有其他 if 语句也是如此。关键字在with这里充当循环。您可以将其理解为“遍历 obj_enemy 的每个实例并在 { ... } 之间执行代码”。引用with我们使用的语句之外的实例other(在本例中,other将是播放器)。

而对于敌人对象中的代码,你根本不必使用instance_find。实际上该this.id部分是完全无效的,除非您this在该代码运行之前定义为实例变量。

无论如何,正确的版本是:

if (hp <= 0) {
    instance_destroy();
}

instance_destroy函数销毁当前范围内的实例(在 GMS2 或 GMS1 Early Access 中,您可以向它传递您希望销毁的实例的附加 id)。

于 2018-05-18T11:38:14.400 回答