• 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 Falling Collision Issues

Trying to code a simple platformer and I'm having some issues with falling onto platforms. The player character will either be slightly above the platform when he lands or slightly below. If I use full numbers for the gravity variables (1, 2, etc.) I don't have this problem but then it messes with my jump height. I also have another bug that may or ay not be related but if he falls into the corner of the platform he sort of wedges in and cannot continue moving in that direction. He can only jump or move the other way at that point. The code I used has been placed below.

Create Event:
/// @description Initialize

hsp = 0;
vsp = 0;
fall_spd = 3;
grv = .25;
spd = 1.25;

Step Event:
/// @description Bon's Abilities

//Buttons

key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_jump = keyboard_check_pressed(ord("Z"));

if keyboard_check_pressed(ord("I"))
{
game_restart();
}

//Gravity is a thing

if !place_meeting(x, y + grv, o_collision)
{
if vsp < fall_spd
{
vsp += grv;
}

} else
{
vsp = 0;
if key_jump
{
vsp -= 4
}
}


hsp = (key_right - key_left) * spd;



//Collisions

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

if place_meeting(x, y + vsp, o_collision)
{
while !place_meeting(x, y + sign(vsp) * grv, o_collision)
{
y += sign(vsp) * grv;
}
vsp = 0;
}

x += hsp;
y += vsp;
 

Simon Gust

Member
The collision code you are using only works with integers as you suspected. This also happens if spd is not an integer.
The solution is to just use a better collision code.
 

Slyddar

Member
The collision code you are using only works with integers as you suspected.
Slightly misleading. The code still works fine with reals.

//Collisions

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

if place_meeting(x, y + vsp, o_collision)
{
while !place_meeting(x, y + sign(vsp), o_collision)
{
y += sign(vsp);
}
vsp = 0;
}
y += vsp;
Ensure you apply your hsp to x directly after your horizontal check, and before your vertical check, and remove the grv addition, as vsp already includes it this step.
 

TheouAegis

Member
You already added grv to vsp. Why are you using it in your Collision checks? Remove grv from your collision checks, especially if it's less than 1.00pps.
 
You already added grv to vsp. Why are you using it in your Collision checks? Remove grv from your collision checks, especially if it's less than 1.00pps.
That was part of an experiment. I forgot to remove it before posting and it wouldn't let me edit the post :/
 
Slightly misleading. The code still works fine with reals.


Ensure you apply your hsp to x directly after your horizontal check, and before your vertical check, and remove the grv addition, as vsp already includes it this step.
Hi! So the the grv was part of an experiment and I forgot to remove it before posting. The collision code I have is the same as what you posted here but the problem persists. Do you have any idea why this might be? If I had an understanding as to why it was happening I would probably be able to find a solution on my own but I'm completely stumped.
 

Slyddar

Member
I also have another bug that may or ay not be related but if he falls into the corner of the platform he sort of wedges in and cannot continue moving in that direction.
I've given you the solution to this problem, so did you apply what I said regarding hsp?

For the slightly above or below the platform problem, can you post a picture of what it looks like?
 
I've given you the solution to this problem, so did you apply what I said regarding hsp?

For the slightly above or below the platform problem, can you post a picture of what it looks like?
I applied the hsp to x directly after the collision check and before the vertical check and there was no change. Here are the pictures of what I'm experiencing. You may have to enlarge them to see it (print screen doesn't work on my computer for some reason so I had to use snippet). Thank you for your help!
 

Attachments

Simon Gust

Member
I applied the hsp to x directly after the collision check and before the vertical check and there was no change. Here are the pictures of what I'm experiencing. You may have to enlarge them to see it (print screen doesn't work on my computer for some reason so I had to use snippet). Thank you for your help!
Have you tried my suggestion? It's the first reply of the thread.
 

Slyddar

Member
I applied the hsp to x directly after the collision check and before the vertical check and there was no change.
As my post showed, applying hsp correctly was the answer to getting stuck in the corners when moving diagonally.

When I run your exact (albeit corrected) code on a 16x16 sprite, it works fine. Are you saying the player stays like it is in image 2 when moving around horizontally too, or only for a split second when landing?
 
As my post showed, applying hsp correctly was the answer to getting stuck in the corners when moving diagonally.

When I run your exact (albeit corrected) code on a 16x16 sprite, it works fine. Are you saying the player stays like it is in image 2 when moving around horizontally too, or only for a split second when landing?
First off, I was mixed up on what applying hsp to x earlier was for. I thought it was for the sub pixel issue which is why I didn't notice any change XD. It did fix the diagonal problem so thank you for that! As for your question the player character does stay like it is in images 1 and 2 (it's hard to see but in image 1 he's very slightly sunk into the platform) even while moving until he jumps again.
 

Slyddar

Member
Basically the answer was given by Simon in the first reply. This method applies decimals as gravity, but the sprite must be drawn on an integer based grid. Gamemaker fills in the blanks essentially, by moving the sprite via sub pixel movement when the viewport is scaled up.
You could try checking for 1 pixel instead of grv instead :
GML:
//Gravity is a thing

if !place_meeting(x, y + 1, o_collision)
 
Basically the answer was given by Simon in the first reply. This method applies decimals as gravity, but the sprite must be drawn on an integer based grid. Gamemaker fills in the blanks essentially, by moving the sprite via sub pixel movement when the viewport is scaled up.
You could try checking for 1 pixel instead of grv instead :
GML:
//Gravity is a thing

if !place_meeting(x, y + 1, o_collision)
That's what I have now. The grv was there as an experiment to see if a smaller number would make the collision more precise (which didn't work). Here's my updated code chunk for the step event.


Code:
/// @description Bon's Abilities

//Buttons


key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_jump = keyboard_check_pressed(ord("Z"));



if keyboard_check_pressed(ord("I"))
{
    game_restart();   
}

//Move

hsp = (key_right - key_left) * spd;


//Change Animation

if !place_meeting(x, y + 1, o_solid)
{
    if hsp != 0
    {
        image_xscale = sign(hsp);   
    }
    sprite_index = s_bon_jump;
    image_index = (vsp > 0);
} else
{
    if hsp != 0
    {
        image_xscale = sign(hsp);
        sprite_index = s_bon_walk;   
    } else
    {
        sprite_index = s_bon_idle;   
    }
}



if !place_meeting(x, y + 1, o_solid)
{
    if vsp < fall_spd
    {
        vsp += grv;
    }
    
} else
{

    vsp = 0;
    if key_jump
    {
        vsp -= 4
    }
}
    


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


x += hsp;

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


y += vsp;
 
Top