GameMaker [SOLVED] Can't figure out how to do collision for accelerated movement

G

GhastlyMicrowave

Guest
As the title says, I quite suck at doing collision, mainly because my movement code includes accelerating and decelerating hspeed and vspeed and all the fixes i've looked for rely on the fact that the movement speed is fixed and doesn't change.
In the step command of obj_player:
Code:
maxspeed = 6             // maximum speed cap
speedrate = 1.5        // the rate the player accelerates
slowdownrate = .4       // the rate that the player slows down when not moving
stoppingspeed = 1.4   // the parameter where the speed is automatically set to 0

vspeed += (keyboard_check(ord("S")) - keyboard_check(ord("W"))) * speedrate
hspeed += (keyboard_check(ord("D")) - keyboard_check(ord("A"))) * speedrate
if !keyboard_check(ord("W")) and vspeed < 0 then vspeed = vspeed + slowdownrate
if !keyboard_check(ord("S")) and vspeed > 0 then vspeed = vspeed - slowdownrate
if !keyboard_check(ord("A")) and hspeed < 0 then hspeed = hspeed + slowdownrate
if !keyboard_check(ord("D")) and hspeed > 0 then hspeed = hspeed - slowdownrate
if vspeed > -stoppingspeed and vspeed < stoppingspeed then vspeed = 0
if hspeed > -stoppingspeed and hspeed < stoppingspeed then hspeed = 0
if speed > maxspeed then speed = maxspeed
Sorry it looks messy, I'm not new to gm, just bad at it.

Anyways, so I've been trying to write something that will do pixel perfect collision and still allow the player to move diagonally against walls instead of stopping them flat. I've done some research and found some possible fixes, but they were all designed for movement at fixed speeds.

this was my last tried fix, and it didn't really work, I was still getting stuck in objects and getting trapped there.

in the step command of obj_player:
Code:
//Horizontal Collision
if (place_meeting(x + hspeed, y, obj_obstacle)) { //about to collide
    while (!place_meeting(x + sign(hspeed), y, obj_obstacle)) { //loop if condition is not true
        x += sign(hspeed);
    }
    hspeed = 0;
}
x += hspeed;

//Vertical Collision
if (place_meeting(x, y + vspeed, obj_obstacle)) {
    while (!place_meeting(x, y + sign(vspeed), obj_obstacle)) { 
        y += sign(vspeed);
    }
    vspeed = 0;
}
y += vspeed;

// Both 
if (place_meeting(x + hspeed, y + vspeed, obj_obstacle)) {
    while (!place_meeting(x + sign(hspeed), y + sign(vspeed), obj_obstacle)) { 
        y += sign(vspeed);
        x += sign(hspeed);
    }
    vspeed = 0;
    hspeed = 0;
}
y += vspeed;
x += hspeed;
It's an edited version of a platformer collision script I found on another forum post (which I would link to if this wasn't my first post, it's not that important anyway).

As a side note, this is improved and recovered code from a few years ago, and I remember I fixed the collision problem then by slowly pushing the player out of a wall, I need a better and more reliable fix that will probably prevent the player from even entering walls.

I *had* a *working* collision code before, but I saved over it by accident after changing it to fix a minor bug where the player would be able to pass though objects if it was clear on the other side- and I screwed everything up. Anybody who knows better than me, if you could give me some pointers, that would help a lot. Thanks for your time.
 

Bentley

Member
I noticed that you're using the built in variables, "hspeed" and "vspeed", as if they weren't built-in (if that makes any sense). Why not use "hspd" and "vspd" instead. That way, this line won't move you twice the distance:
Code:
x += hspeed;
Let's say your hspeed is 5. Your x will change by 5, and then hspeed, because it's a built-in variable that moves you horizontally, will change your x by an additional 5. And as a side note, you actually have it coded twice (once under the collision code and once at the end). So you'd actually move 4 times the amount you want.

I hope I read your code correctly and I hope my reply helps.
 
Last edited:
G

GhastlyMicrowave

Guest
ah, I see what you mean. That was a fault of rushing through and trying to desperately find a solution while being very frustrated.
sorry bout that, now I feel pretty stupid.
In the meantime I think I might have fixed the problem, but per your advice I'll change hspeed to hspd and have it update at the end of the step command.

Code:
//    Collision
//right
if collision_rectangle(x,y-yoffset,x+xoffset+hspeed,y+yoffset,obj_obstacle,true,true)
{
  
    if hspeed > 0 then hspeed = 0
  
}
//left
if collision_rectangle(x,y-yoffset,x-xoffset+hspeed,y+yoffset,obj_obstacle,true,true)
{
  
    if hspeed < 0 then hspeed = 0
  
}
//up
if collision_rectangle(x-xoffset,y-yoffset+vspeed,x+xoffset,y,obj_obstacle,true,true)
{

    if vspeed < 0 then vspeed = 0

}
//down
if collision_rectangle(x-xoffset,y+yoffset+vspeed,x+xoffset,y,obj_obstacle,true,true)
{

    if vspeed > 0 then vspeed = 0

}
I solved the issue by just having 4 different collision boxes, one per side. Until this starts screwing me up, I think i'm good.
sorry I kinda wasted your time, thanks anyway.
 
Top