GML Ground detection diy raycast problem

A

AX53

Guest
I'm making a sidescroller platformer engine but I've run into a strange problem. This might be a somewhat advanced question.

The initial collision detection / motionstopper works brilliantly. When I reach the DIY raycast which is essentially a for loop acting as a pixel perfect raycast, it doesn't seem to function at all.

What happens?
The character falls until the motionstopper takes place. yspeed is reset and it falls 1 pixel everytime yspeed reach 1 until it stops at the ground.

So what should happen?
After the motion stopper has taken place and initially detected the ground and turned the velocity to 0, the raycast part should move the object into contact with the ground. It does this by checking pixel by pixel for collisions downwards until it finds the ground and moves the character down the same amount of loops it's taken so far. (yes the collision mask is a 1x1 pixel sprite). But it doesn't seem to at any time find a collision even though the exact same function works flawlessly earlier on in the code.

Keep in mind that i've set terminal velocity to 8, and each collision block is 16x16 so its impossible for the character to skip trough the ground.

Any idea what I'm missing?

Code:
//Gravity application
yspeed += 16/30;

if(yspeed>0)
{
    //initial collision detection motion stopper
    if(!place_free(x,y+round(yspeed)+8))
    {
        yspeed = 0;
        //Diy raycast with ground contact movement
        for(raylength = 0; raylength<round(yspeed)+8; raylength+=1)
        {
            if(!place_free(x,y+raylength))
            {
                y+=raylength-8;
                break;
            }
        }
    }
}

//Velocity application
y+=max(min(round(yspeed),8),-8);
 
Last edited by a moderator:

CoderJoe

Member
Hmm. Raycasting in gamemaker is always interesting (hint hint gamemaker... you guys should add some built in raycasting). So off the top of my head I would check collision masks and double check that the player cant fall through the ground due to his speed. My go-to resource for platforming style games is this tutorial:
https://zackbellgames.com/2014/10/28/devlog-creating-a-platformer/

I read through your explanation and I dont get why you set yspeed to 0 and then have another loop. Could you just loop through the amount of pixels below the player based on the speed and then move that many pixels (so if the player was falling at a rate of 5 pixels then check 1 pixel under, then 2 pixels under, etc...)? If it found a collision then it would stop, moving the player to the collision point (the ground) and setting the yspeed to 0 at that point.
 
A

AX53

Guest
Hmm. Raycasting in gamemaker is always interesting (hint hint gamemaker... you guys should add some built in raycasting). So off the top of my head I would check collision masks and double check that the player cant fall through the ground due to his speed. My go-to resource for platforming style games is this tutorial:
https://zackbellgames.com/2014/10/28/devlog-creating-a-platformer/

I read through your explanation and I dont get why you set yspeed to 0 and then have another loop. Could you just loop through the amount of pixels below the player based on the speed and then move that many pixels (so if the player was falling at a rate of 5 pixels then check 1 pixel under, then 2 pixels under, etc...)? If it found a collision then it would stop, moving the player to the collision point (the ground) and setting the yspeed to 0 at that point.

Hmm its not quite that simple. What you describe is what the first place_free in the script actually currently do. But if the player is falling with 8 pixels per frame and is 4 pixels above the block, then it will detect the 16px thick block but it wont actually be contacting the ground. That's the purpose of the second "raycasting" part to move the player the last distance to the ground. Collisions masks isn't the problem since the first place_free works fine and I've double checked it. Also like I said falling trough objects isn't a problem since the player cant fall faster than 8 pixels per frame and the collision blocks are 16 pixels thick. (8 pixels thick would in fact be sufficient).

Thanks for your answer
 
Last edited by a moderator:
A

AX53

Guest
Oh i think I found the problem. I can't be resetting yspeed BEFORE applying the diy raycast.



Edit: Yep! Now it works
 

CoderJoe

Member
Cool! Glad you figured it out. I did think that yspeed=0 looked wrong and pointed it out before. Anyways good luck with your project!
 
Top