Legacy GM [SOLVED] Interact with an enemy with a precise collission

ruwcom

Member
So I made a state where you grab an enemy and throw it away, this happens when the character is directly in front of the enemy, touching it, this works fine but when I'm walking over them, having the foot of the character touching the enemy, the code detects a collision and activates the throw state, how can I make it so it only activates when it's in front and in the center of the enemy?
The code looks like this right now

Code:
if (place_meeting(x-24*dir,y,obj_enemy))
{
state = scr_throw;
}
-24 is so it react in the center and "dir" is so it detects where the character is facing.
 

YoSniper

Member
In order to better help you, please define what "dir" is in your code, and what you mean by "in front". Screenshots would also help.
 

ruwcom

Member
"dir" is a variable for where the character is facing and moving, if the character is facing left then dir is -1, right is just 1, multiplying 24 * dir will make the value positive or negative, so the game will define if it's 24 pixels to the left or to the right from the x of the object.

And I mean in front when the character is facing the enemy, coincide in the x position and they are in the same point in the Y axis.
My problem is that the code activates when they are in the same x position but in any Y position as long as any pixel is touching.

For example in this image, the state of grabbing an enemy activates in the first picture and that's fine, but it also activates when the character is far away in the Y axis, and that's what I don't want to happen.
It's kinda hard to explain with a capture but in that state the player stays quiet until you press a button to throw the enemy, so if I go over the enemy or under it then the character just stops moving, because it's in that grabbing state.
 

Attachments

YoSniper

Member
Here's my first idea for how to fix this. In order to check the enemy's y coordinate, you need the enemy's instance ID as reference. place_meeting won't give you that information, as it only returns a boolean.

A function like collision_line or collision_rectangle would return the instance ID of the enemy instance.

This code uses a rectangle the size of the player's hitbox, but shifted 24 pixels in the appropriate direction.
Code:
var inst = collision_rectangle(bbox_left + 24 * dir, bbox_top, bbox_right + 24 * dir, bbox_bottom, obj_enemy, true, true);
if instance_exists(inst) and inst.y == y {
    state = scr_throw;
}
Please let me know if this works, and if you have any questions regarding it.
 

ruwcom

Member
Mmmh no, it seems like right now it doesn't detect the enemy at all and it doesn't change the state.
 

YoSniper

Member
Well, I did use "+24" instead of "-24" because based on your description of "dir", that seemed the more logical choice.

But maybe your code is built differently. Try changing the plus to a minus and see if that works.
 

ruwcom

Member
Yeah that's the first thing I tried and it doesn't seem to fix the problem, even with changing the value of one and not the other.
 

YoSniper

Member
Here's Plan B.

I'm going to use a "with" statement to determine the ID of an instance of obj_enemy that is in the right position, but level with the player.
Code:
var my_id = id; //Keeps track of the player's instance ID
with(obj_enemy) {
    if place_meeting(x + 24 * my_id.dir, y, obj_player) and y == my_id.y {
        my_id.state = scr_throw;
    }
}
This seems to be a roundabout way of doing things, but it should be similar enough to your original code that it should work better.
Also, if "+ 24" doesn't work, try "- 24". But I think the + 24 is correct in this instance because we're looking from the perspective of the enemy, and not the player.
 

ruwcom

Member
Oh wait sorry, I forgot to say that the code is running as a script for the player, not the enemy, i got the enemy to try to grab and throw himself.
I twisted the code a bit to work with the player, and it detects the enemy and goes to the throw state, though the problem of activating even if the Y position isn't the same it's still there.
So it looks like this now

Code:
var my_id = id; //Keeps track of the player's instance ID
    if place_meeting(x - 24 * my_id.dir, y, obj_enemy) and y == my_id.y {
        state = scr_throw;
}
Don't use y==, use something like
abs(y-my_id.y)<4
I don't know how that function works but it doesn't seem to make a difference.
 

TheouAegis

Member
Your code isn't the same, that's why it's not working.
Code:
var my_id = id; //Keeps track of the player's instance ID
with(obj_enemy) {
   if place_meeting(x - 24 * my_id.dir, y, obj_player) and abs(y - my_id.y) < 4 {
       my_id.state = scr_throw;
   }
}
That code goes in the player, he's not saying to put it in the enemy.
 

ruwcom

Member
No, because I already tried that and the enemy starts running scripts for the player, it even crashes because the enemy looks for a variable that doesn't exist for him but the player uses to check damage. That's why I changed it.
 

TheouAegis

Member
THAT code doesn't cause those errors. Whatever code you ended up using does. The only thing the enemy runs is a place_meeting() check. The only variables are my_id, which is local, and x and y, which are built in.

Edit: He should also have not used obj_player, technically.
if place_meeting(x - 24 * my_id.dir, y, my_id)
 
Last edited:
Top