DevLog: Creating a Platformer Pt.3

DAY 7

It had been roughly a week since I’ve had any public updates on this project. I had a busy Halloween weekend and I was also wrapping up some contract work. On top of that, I have been poking at some pixel art. I’d really like to have the freedom to create my own games, both technically AND visually. If I decide to practice pixel art more regularly, I’ll start a log about that too.

ANYWAY, changes since the last post:

1) I decided that I would be needing jump through platforms. There are collision objects that are only collide-able when you fall on top of them from above. Basically, you can jump up through them, then fall back down to land on them.

This can be done by simply editing our OnGround() script. Prior to this entry, OnGround() looked like this:

/// OnGround();

return place_meeting(x, y + 1, oParSolid);

I added another parent object (oParJumpThru) and edited the script. It now looks like this:

/// OnGround();

return place_meeting(x, y + 1, oParSolid) || (place_meeting(x, y + 1, oParJumpThru ) && !place_meeting(x, y, oParJumpThru));

We are now checking if we are colliding with a solid block OR if we are NOT colliding with a platform, but there is one below us. I hope that makes sense!

2) I’d like to plan ahead for moving platforms, both horizontal, vertical, and possibly, both. For that process we need to go over a few GM features.

With()

The With() statement or ‘construction’ is used to execute code from an object other than the calling object. Without this command, we have to do a lot of things like this:

platform = instance_place(x, y + 1, oParSolid);

if (platform != noone)
    vx = platform.vx;

The code above checks if there is a platform below the calling object. If there is one, it sets the horizontal velocity of the object to that of the platform. This could be the basics to horizontal moving platforms.

With() makes a task like this a lot simpler.

with (instance_place(x, y + 1, oParSolid))
    other.vx = vx;

Other

You may have noticed another GM keyword in that last example. ‘Other’ is used to target the object that is using the with() construction. The code is almost backwards compared to the first block. Now you are calling the commands from the platform and accessing the original object.

With() and ‘other’ are often used together in the ‘collision event’. When executing code within the ‘collision event’, ‘other’ always refers to the object that the calling object is colliding with. For example, if you wanted a player to be destroyed when coming into contact with a spike hazard, you could execute the following.

// oParHazard 'collision (w/ oPlayer) event'

with (other)
    instance_destroy();

Moving Platforms

Now that we understand with() and other, we can start to piece together our moving platforms. If you can’t already tell, we’ll basically just be checking moving objects positions and moving other objects in relation to their speed(s).

For now, let’s create bumpers that cause the platforms to change direction. We will also start with solely vertically moving obstacles. We’re going to iterate through the moving platform’s velocity values like we did with the player movement.

// oMovingPlatform 'end step event'
repeat (abs(vy)) {
    if (!place_meeting(x, y + sign(vy), oBumper)) {
        with (oParEntity) {
            //////////////////////////////////////////////
            // MOVE ENTITIES IN RELATION TO PLATFORM(S) //
            //////////////////////////////////////////////
        }
        y += sign(vy);
    }
    else
        // Bounce off of bumper
        vy *= -1;
}

We will basically be moving the platform in the exact same fashion that we did the player. However, we will also be calling some code from each entity object. This code will push those objects around if they come into contact with the vertically moving platform. However, to do this we need to check whether the entity is colliding with objects other than the calling platform.

// PlaceMeetingException(x, y, objectType, objectToIgnore);
var exception = argument3;

with (argument2) {
    // Allow 'other' access
    var this = id;
    
    if (id == exception)
        continue;
    else
        with (other)
            if (place_meeting(argument0, argument1, this))
                return true;
}

// Collision with a different object
return false;

This has been a code-heavy entry, so I’ll cut it short. Using the code above and PlaceMeetingException(), you should be able to piece together how to keep an entity on top of a moving platform. You can also add sub-pixel movement to the moving platforms, as well.

I also apologize for the slow-moving “DevLog”. I will pick up the pace when the project is revealed. This IS a commercial project, and I will respect its privacy for now!

-Z

DevLog: Creating a Platformer Pt.3

2 thoughts on “DevLog: Creating a Platformer Pt.3

Leave a comment