• 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!

Windows COLLISION PROBLEM (HELP)

Hi, I´m making a plataformer game and in my character I put this in the Step event:
GML:
var hor = keyboard_check (vk_right) - keyboard_check (vk_left)

if (hor != 0) {
    if (place_free(x + hor * 2,y)) {
    x += hor * 4;
    }
    image_xscale = hor * 2;
    sprite_index = sPersonajeWalk;
} else {
    sprite_index = sPersonaje;
}

if (keyboard_check_pressed(vk_up) && collision_rectangle(x-8,y,x+8,y+1,oColision,false,false)) {
    vspeed = -10;
}
And this on the End Step event:
GML:
if (!collision_rectangle(x-8,y,x+8,y+1,oColision,false,false)) {
    gravity = 0.8;
}

if (vspeed > 0) {
    var ground = collision_rectangle(x-8,y,x+8,y+vspeed,oColision,false,false)
    if (ground) {
        y = ground.y;
        vspeed = 0;
        gravity = 0;
    }
}

OColision is the Solid block object. And I use another object as a rectangle collision mask for the player. The problem is that when I touch the ground (made by the oColision object) my character can´t move, and the character´s origin is on it´s feet and the collision mask´s origin is down in the center.
Another problem is that when I´m falling after a jump, part of the character gets inside the block. In other words, the collision mask changes when I´m falling, but I don´t have any different sprite for the jumps and falls, apart from the walking sprite.
I don´t know where´s the problem, can somebody help me please?
Let me know if you need more information about this.

Thank you.

Moderator EDIT: Moved here from Community Tech Support forum.
 
Last edited:

Roldy

Member
In the future post you code within the forums code snippet tool. When you post it is on the toolbar:
1623016812027.png

As well this topic is most likely better suited in the 'Programming' forum. Possibly a moderator will move it for you.
 

Roldy

Member
Hi, I´m making a plataformer game and in my character I put this in the Step event:
GML:
var hor = keyboard_check (vk_right) - keyboard_check (vk_left)

if (hor != 0) {
    if (place_free(x + hor * 2,y)) {
    x += hor * 4;
    }
    image_xscale = hor * 2;
    sprite_index = sPersonajeWalk;
} else {
    sprite_index = sPersonaje;
}

if (keyboard_check_pressed(vk_up) && collision_rectangle(x-8,y,x+8,y+1,oColision,false,false)) {
    vspeed = -10;
}
And this on the End Step event:
GML:
if (!collision_rectangle(x-8,y,x+8,y+1,oColision,false,false)) {
    gravity = 0.8;
}

if (vspeed > 0) {
    var ground = collision_rectangle(x-8,y,x+8,y+vspeed,oColision,false,false)
    if (ground) {
        y = ground.y;
        vspeed = 0;
        gravity = 0;
    }
}

OColision is the Solid block object. And I use another object as a rectangle collision mask for the player. The problem is that when I touch the ground (made by the oColision object) my character can´t move, and the character´s origin is on it´s feet and the collision mask´s origin is down in the center.
Another problem is that when I´m falling after a jump, part of the character gets inside the block. In other words, the collision mask changes when I´m falling, but I don´t have any different sprite for the jumps and falls, apart from the walking sprite.
I don´t know where´s the problem, can somebody help me please?
Let me know if you need more information about this.

Thank you.

Moderator EDIT: Moved here from Community Tech Support forum.

I would suggest walking through the code with the debugger. If you are not familiar with the debugger then this is the best time to get familiar:
Debugger

Place a break point in your event (within your first conditional) and step through the code. Inspect the variables and watch which conditional block it enters or does not enter.

There is some skill to using a debugger. Take the time to develop the skill and become proficient with it. This will pay unlimited dividends in the future.
 

TheouAegis

Member
And I use another object as a rectangle collision mask for the player.
You use sprites for masks, not objects. If you are using a player object AND a hitbox object, you need to delete that hitbox object from your life. Unless it's for melee attacks.

You are using collision checks for horizontal movement and proximity checks for vertical. You should use one or the other. Also, collision_rectangle is (or was) significantly slower than place_meeting().

if (place_free(x + hor * 2,y)) { x += hor * 4;
You are checking 2 pixels ahead, but moving 4 pixels. That will get you stuck inside walls.

Is oCollision's sprite origin in the top-left, or is it centered? It MUST be in the top-left, since you are setting the player's y to oCollision's y.


!collision_rectangle(x-8,y,x+8,y+1,oColision,false,false))
And in the case of this collision_rectangle use specifically (the "y+1" lines), the way your code is set up, you should be using collision_line(x-8,y,x+8,y,oColision,false,false).
 

Pixel-Team

Master of Pixel-Fu
Separate your character's behavior into states, so that you don't end up with dozens of systems all competing with one another. For example, check to see if a tile is under you in a falling state. When you finally hit it, set the y position to the top of the tile you collided with and switch to a landing or standing state, where you are no longer testing for collisions. When the player moves, change to a running state, where you test to see if a tile is NOT under you, at which time you can change back to a falling state again. State machines are your friend. Study state machines.
 

Reprom

Member
GML:
if (vspeed > 0) {
    var ground = collision_rectangle(x-8,y,x+8,y+vspeed,oColision,false,false)
    if (ground) {
        y = ground.y;
        vspeed = 0;
        gravity = 0;
    }
}
you said that "character´s origin is on it´s feet and the collision mask´s origin is down in the center". That plus this "y = ground.y;", I am guessing, is cause of your problem.

You can try "y = ground.bbox_top-1;"? My reasoning is that bbox_top will always be the top of a collision mask, well, it literaly is a top of a collision mask. And "-1" so it is atleast one pixel above the wall, not directly inside it.
 
Last edited:
Top