• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker Weird enemy behavior [SOLVED]

Zabicka

Member
Hello everyone, my enemy is acting weird. It should bounce of walls, but when it touches a corner of the wall, it just stops bouncing and goes in straight line. (I would post image here, but it doesn't work, so sorry for that).
There is my enemy code.
Code:
//CREATE EVENT

move_speed = 1;

hspd = choose(-move_speed, move_speed);
vspd = choose(-move_speed, move_speed);
Code:
//STEP EVENT

//Bounce
if (place_meeting(x+hspd, y, obj_collision)) {
    hspd *= -1;
}
if (place_meeting(x, y+vspd, obj_collision)) {
    vspd *= -1;
}


//Movement & Collision
if (place_meeting(x+hspd, y, obj_collision)) {
    while (!place_meeting(x+sign(hspd), y, obj_collision)) {
        x += sign(hspd);
    }
    hspd = 0;
}
x += hspd;

if (place_meeting(x, y+vspd, obj_collision)) {
    while (!place_meeting(x, y+sign(vspd), obj_collision)) {
        y += sign(vspd);
    }
    vspd = 0;
}
y += vspd;
 

jo-thijs

Member
Hello everyone, my enemy is acting weird. It should bounce of walls, but when it touches a corner of the wall, it just stops bouncing and goes in straight line. (I would post image here, but it doesn't work, so sorry for that).
There is my enemy code.
Code:
//CREATE EVENT

move_speed = 1;

hspd = choose(-move_speed, move_speed);
vspd = choose(-move_speed, move_speed);
Code:
//STEP EVENT

//Bounce
if (place_meeting(x+hspd, y, obj_collision)) {
    hspd *= -1;
}
if (place_meeting(x, y+vspd, obj_collision)) {
    vspd *= -1;
}


//Movement & Collision
if (place_meeting(x+hspd, y, obj_collision)) {
    while (!place_meeting(x+sign(hspd), y, obj_collision)) {
        x += sign(hspd);
    }
    hspd = 0;
}
x += hspd;

if (place_meeting(x, y+vspd, obj_collision)) {
    while (!place_meeting(x, y+sign(vspd), obj_collision)) {
        y += sign(vspd);
    }
    vspd = 0;
}
y += vspd;
In your step event, you have 2 main pieces of code:
1) First you have some code to reverse direction (horizontally or vertically) if a collision would happen.
2) Afterwards you check again if some collision would happen and if so, you move until collision.

Now, in most common cases, if the object is about to collide, it reverses direction, after which a collision isn't about to happen any more.
This makes it so that the collision checking in your second part normally doesn't do anything.

When your object is about to hit a corner however, it isn't about to collide horizontally, nor vertically, so movement isn't reversed.
Now the second part of the step event will be able to do something.
Horizontally, no collision is about to happen, so the object moves horizontally over the corner.
Now there is a vertical collision about to happen, so your code moves the object until collision and resets the vertical speed.

You probably don't update the vertical speed anywhere else, so from that point onwards it remains 0 forever.

In short, the second part of your step event is bugged, but by some bad luck it remained hidden from you until now.

There are multiple solutions.
The easiest is to change the second part of your step event to:
Code:
//Movement & Collision
if (place_meeting(x+hspd, y, obj_collision)) {
    while (!place_meeting(x+sign(hspd), y, obj_collision)) {
        x += sign(hspd);
    }
} else {
    x += hspd;
}

if (place_meeting(x, y+vspd, obj_collision)) {
    while (!place_meeting(x, y+sign(vspd), obj_collision)) {
        y += sign(vspd);
    }
} else {
    y += vspd;
}
 

Zabicka

Member
In your step event, you have 2 main pieces of code:
1) First you have some code to reverse direction (horizontally or vertically) if a collision would happen.
2) Afterwards you check again if some collision would happen and if so, you move until collision.

Now, in most common cases, if the object is about to collide, it reverses direction, after which a collision isn't about to happen any more.
This makes it so that the collision checking in your second part normally doesn't do anything.

When your object is about to hit a corner however, it isn't about to collide horizontally, nor vertically, so movement isn't reversed.
Now the second part of the step event will be able to do something.
Horizontally, no collision is about to happen, so the object moves horizontally over the corner.
Now there is a vertical collision about to happen, so your code moves the object until collision and resets the vertical speed.

You probably don't update the vertical speed anywhere else, so from that point onwards it remains 0 forever.

In short, the second part of your step event is bugged, but by some bad luck it remained hidden from you until now.

There are multiple solutions.
The easiest is to change the second part of your step event to:
Code:
//Movement & Collision
if (place_meeting(x+hspd, y, obj_collision)) {
    while (!place_meeting(x+sign(hspd), y, obj_collision)) {
        x += sign(hspd);
    }
} else {
    x += hspd;
}

if (place_meeting(x, y+vspd, obj_collision)) {
    while (!place_meeting(x, y+sign(vspd), obj_collision)) {
        y += sign(vspd);
    }
} else {
    y += vspd;
}
Thank you so much! It works perfectly!
 
Top