我刚刚开始使用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);
}
目前,房间中只有一个敌人实例记录了攻击,当我攻击该实例时,所有实例都会被摧毁,而我只想摧毁一个实例。
提前感谢任何帮助!
发生这种情况的原因是您使用的是对象索引,而不是特定实例的索引。当您执行以下操作时:
<object_index>.<object_property> eg. obj_enemy.hp
可能发生两种情况:
- 如果游戏中当前有一个实例处于活动状态,则 将引用实例的变量。
- 如果有两个或更多实例,则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 抢先体验中,您可以向它传递要销毁的实例的附加 ID)。