Understanding Collision Basics Pt.1

I have been asked time and time again to start doing video tutorials for Game Maker Studio and programming concepts in general. I’m going to start by taking requests for blog posts, and if interest continues, I’ll invest some time into a video series!

Send Me Ideas!

Email me -> zbell91@comcast.net
Ask publicly -> http://ask.fm/ZackBellGames

Collision Basics

I get this question almost every day, so it’s about time that I talk about it. How do I implement slopes of different angles and other more advanced collision features?

Well honestly, I’d consider that to be simple collision detection. However, I understand that it isn’t exactly intuitive to a lot of people. Luckily, once you get it, you get it. From there the concepts involved can be expanded rather easily into jump through platforms, moving terrain, etc.

1) The first step is collision against solid, flat block objects. Basically, the player should stop when making contact with the floor, ceiling, and walls.

For these examples I will be using Game Maker syntax and function calls (I am comfortable in this environment and most of my followers expect this). I will also use vx and vy to describe the horizontal and vertical velocities of the player object.

// Vertical
repeat(abs(vy)) {
    if (!place_meeting(x, y + sign(vy), oParSolid))
        y += sign(vy); 
    else {
        vy = 0;
        break;
    }
}

// Horizontal
repeat(abs(vx)) {
    if (!place_meeting(x + sign(vx), y, oParSolid))
        x += sign(vx); 
    else {
        vx = 0;
        break;
    }
}

I’ll quickly walk you through the loop in normal speak. Basically what we’re doing is asking the following:

1) Is there a collision one pixel in the direction that I am moving (up/down)?
2a) If no, move one pixel in that direction (up/down).
2b) If yes, rest your speed (up/down) and exit the loop.
3) Repeat step 1.

You repeat this cycle until a collision causes you to break out of the loop OR you have iterated “vy” times through the loop. The horizontal movement loop looks identical at this point.

2) The next step is allowing the player to move up and down slopes. More specifically, slopes that increase the player’s y-coordinate by one pixel per step.

Additional code has been added in bold.

// Vertical
repeat(abs(vy)) {
    if (!place_meeting(x, y + sign(vy), oParSolid))
        y += sign(vy); 
    else {
        vy = 0;
        break;
    }
}

// Horizontal
repeat(abs(vx)) {

    // Move up slope
    if (place_meeting(x + sign(vx), y, oParSolid) && !place_meeting(x + sign(vx), y - 1, oParSolid))
        --y;
    
    // Move down slope
    if (!place_meeting(x + sign(vx), y, oParSolid) && !place_meeting(x + sign(vx), y + 1, oParSolid) && place_meeting(x + sign(vx), y + 2, oParSolid))
        ++y; 

    if (!place_meeting(x + sign(vx), y, oParSolid))
        x += sign(vx); 
    else {
        vx = 0;
        break;
    }
}

You will notice that nothing changes in terms of the vertical collision loop. The initial loop that we had set up will handle not falling through slopes. However, there are TWO changes to the horizontal loops. These are for moving up and down slopes.

// Move up slope
1) Is there is a collision in the direction you are moving (left/right) and no collision in that direction if the player is moved up by one pixel?
2) If yes, you are next to a slope and push the player up by one pixel. The rest of the loop will handle moving the player towards the slope, horizontally.

// Move down slope
1) Is there no collision in the direction you are moving, and no collision if the player were moved down one pixel and a collision if the player was moved down by two pixels?
2) If yes to all of the above, you can move down a slope.

That third check (for moving down) is to check that you’re not just on a cliff/ledge. Without this, all corners are treated as slopes.

3) Lastly, you may want to handle steeper slopes. I will show an example of slopes that adjust the player’s y-coordinate by two pixels per step.

Again, additional code is displayed in bold.

// Vertical
repeat(abs(vy)) {
    if (!place_meeting(x, y + sign(vy), oParSolid))
        y += sign(vy); 
    else {
        vy = 0;
        break;
    }
}

// Horizontal
repeat(abs(vx)) {
    // Move up slope
    if (place_meeting(x + sign(vx), y, oParSolid) && place_meeting(x + sign(vx), y - 1, oParSolid) && !place_meeting(x + sign(vx), y - 2, oParSolid))
        y -= 2;
    else if (place_meeting(x + sign(vx), y, oParSolid) && !place_meeting(x + sign(vx), y - 1, oParSolid))
        --y;
    
    // Move down slope
    if (!place_meeting(x + sign(vx), y, oParSolid) && !place_meeting(x + sign(vx), y + 1, oParSolid) && !place_meeting(x + sign(vx), y + 2, oParSolid) && place_meeting(x + sign(vx), y + 3, oParSolid))
        y += 2;
    else if (!place_meeting(x + sign(vx), y, oParSolid) && !place_meeting(x + sign(vx), y + 1, oParSolid) && place_meeting(x + sign(vx), y + 2, oParSolid))
        ++y; 

    if (!place_meeting(x + sign(vx), y, oParSolid))
        x += sign(vx); 
    else {
        vx = 0;
        break;
    }
}

Above you see the code added for moving up steeper slopes isn’t much more complicated! The key to simple collision is iterating through an object’s movement path. Is there a collision ahead? If not, move. Otherwise, stop.

I challenge you to expand the code above! You may notice a pattern in the way I check for 2-pixel slopes and 1-pixel slopes. You should be able to set that up within an inner loop that allows you to set a variable (something like ‘slopeMax’) and iterate through slopes of any steepness.

Also, you can adjust the player’s speed when you are moving UP slopes that are steep. Plenty could be added to the code above!

Be sure to follow me on Twitter for news about the next segment. I’ll be discussing both horizontal and vertically moving platforms.

Thanks,

-Z

Understanding Collision Basics Pt.1

6 thoughts on “Understanding Collision Basics Pt.1

  1. SLOPES! Thank you! I was wondering how to get that working. I was putting it on the backburner till now! Please keep these coming man! I hope you cover surfaces in the future. I would love to wrap my head around that lol. P.s. Can’t wait for the moving platforms so far I have had epic fails with those. My character moves up with the vertical platform then falls through when it moves down lol.

    Like

Leave a comment