Legacy GM How can I either conditionally ignore collision event or manually code collision event with bounce?



Hello guys! I have a question regarding collisions, so for my game, I have two objects relevant to this issue:

  1. obj_bound: invisible bound restricting where player can go.
  2. obj_ground: ground obj, player can only walk on obj_ground.
So originally for obj_player, I have a collision event with obj_bound. Even with no code inside, the player cannot move past the invisible bound and cannot get stuck even with dash (which is accomplished by using motion_set()).

Now that I incorporated falling damage, it adds a fake sense of height, therefore when my player falls from a platform with higher Y position, it is supposed to fall through the invisible bound and landed onto the ground to take falling damage.

But with my current set up, it falls straight onto the invisible bound and cannot get past it to the ground awesome demonstration here

My question is then:

  1. Can I do something to the collision event to have the player object ignore the collision and fall through the obj_bound object when it's in a certain state?

  1. Can I hard code the collision event in my step event? I tried something like: if(place_meeting(x, y + 2, obj_bound) || place_meeting(x, y - 2, obj_bound) || place_meeting(x+ 2, y, obj_bound) || place_meeting(x - 2, y, obj_bound)) {speed = 0} But it does not work and everytime I have player dash with motion_set, my player will get stuck in the invisible bound.
My game does not use the physics system, the set up is a dragon's crown like beat em up, where the player can move horizontally and slightly vertically.

Thank you so much!




If part of your concern is that your player is falling so that he's a slight distance above the surface he's supposed to land on, you can do that by moving incrementally towards y + speed instead of instantly. (I cover this at the bottom of this post.)

I am not sure what your invisible bound is supposed to do. Also, the collision event itself usually does not stop an object from passing through another object -- usually one object would have to be solid. Are you sure you didn't put code in the collision event that causes your object to stop? It sounds like colliding with obj_bound is automatically causing your object to stop, which is consistent with "solid." Ordinarily, if you wrote code to stop your object when the collision event gets triggered, all you would have to do is wrap your code in an "if(){}" check that makes sure your code isn't in the state where collisions don't matter.

It sounds like it's supposed to stop motion sometimes, but I'm not sure in which cases, so below I've assumed that the rule you tried to implement is "the player is not allowed to move left or right unless touching an instance of obj_bound."

The normal way of implementing "move until you collide with something" functionality is to define an object type representing the top of a surface the player can land on, and then each step when the player is falling, move the player down pixel-by-pixel, checking before each move if the next move will cause a collision, stopping at the last pixel before.

The logic looks something like this, assuming your horizontal and vertical speed are hsp and vsp respectively:
var x_offset = sign(hsp);

// take abs(hsp) steps of sign(hsp).
// If hsp is 9, this is 9 steps of 1: if hsp is -6, this is 6 steps of -1. And so on.
for (var i = 0; i < abs(hsp); i++) 
  if (
    place_meeting(x + x_offset, y, obj_ground)
    || !place_meeting(x + x_offset, y, obj_bound) // player cannot move right or left unless he is touching obj_bound
  ) { 
    hsp = 0; // stop moving right or left
    break; // don't try to continue the loop
  x += x_offset;

var y_offset = sign(vsp);

// take abs(vsp) steps of sign(vsp).
// If vsp is 9, this is 9 steps of 1: if vsp is -6, this is 6 steps of -1. And so on.
for (var i = 0; i < abs(vsp); i++) 
  if (place_meeting(x, y + y_offset, obj_ground)) {
    ysp = 0; // stop moving up or down
    break; // don't try to continue the loop
  y += y_offset;