• 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!

One-Way Platform Collision Bug [SOLVED]

A

Adventurous_Elf

Guest
Hello there!

I am currently developing a two-dimensional, sidescrolling platformer game, however I have hit a snag when it comes to implementing platforms that you can jump through from below.

Being not entirely sure how to do this myself, I searched around the internet, and came up with a solution partially based on this video:


Essentially what I've done is I've created a new object for the walkthrough platform that is parented to my holding object for solid collision surfaces, aptly called 'par_solid'. If it weren't for the following code, the game would treat it as a normal solid platform.

Code:
///Toggle mask
mask_tick --; //Tick mask toggle

//based on entity position and mask tick
if (y > (par_entity.y + (par_entity.sprite_height / 2)) &&
    par_entity.vsp >= 0 &&
    !place_meeting(x, y, par_entity) &&
    mask_tick <= 0)
    {   
    mask_index = -1; //this tells the platform to use its sprite as a collision mask when the player is above it, thus preventing the player from falling through
    } //End if - mask toggle
else
    {
    mask_index = spr_nomask; //else, if the player is below the platform, use the no collision mask, allowing the player to jump through it
    } //End else - mask toggle
This is where I toggle the object's collision mask based on the position of a given entity object, which encompasses the player. You may notice some references to a variable called 'mask_tick', which allows me to remotely disable the collision mask from other objects in the most inneficient way possible.
Don't worry about it.

Jump-Through Platformer Test.gif

The above would be a perfectly fine solution for me and my project, if it weren't for one thing... this bit of code right here:

Code:
/*stopping in mid-air*/
if (vsp < 0 && !key_jump_held) vsp = max(vsp, -jsp / 3);
Which allows the player to have more control over their jump height a la Super Mario Brothers by stopping in mid-air.

This also works fine, however the two areas of the program come into contact when the player tries to stop themslelves when colliding with the platform object in mid-air.

This can create a rare edge case where the player hasn't quite reached the platform yet. This causes them to jitter between falling and hitting the ground, slowly sinking beneath the platform. I've tried messing around with the values I currently have, but nothing seems to work.

Jump glitch.gif

Can someone please advise me on fixing this problem?

Any help would be much appreciated.
 
B

Becon

Guest
I don't remember the code but I saw on the Legacy forum that you can have your player.x compare to see if it is greater then the platform.obj.x you are about to jump through. If it's greater or BELOW the platform.obj, then the platform.obj reacts as if it wasn't solid. If player.x is less then platform.obj.x, then it knows you are above and "solidifies". Ya might want to give it a small buffer so you don't get stuck though so something like:

If objPlayer.x < then objPlatform.x+3 then objPlatform solid

I hope this helps.
 

TheouAegis

Member
I foresee that code causing you many headaches down the road... You may want to consider any codes that do not require changing variables inside the platform, such as the mask index or solid.
 
A

Adventurous_Elf

Guest
Thank you for all your suggestions. After a bit more fiddling, I found a solution on my own based on changing the sprite y origin used in the collision box to '0', and altering the code used for collision. What I found is that it was simply a problem with my mathematical calculations.

Wheras previously I would toggle the collision mask based on the player being above the platforms y co-ordinate, I now realise that most of the problem stemmed from that sprite origin not being flush with the top of the platform.
I reached the following code eventually and I think it works well enough:

Code:
///Toggle mask
mask_tick --; //Tick mask toggle

//based on entity position and mask tick
if (y > ((par_entity.y  + (par_entity.sprite_height / 2)) - 1) &&
    par_entity.vsp >= 0 &&
    mask_tick <= 0)
    {   
    mask_index = -1; //this tells the platform to use its sprite as a collision mask when the player is above it, thus preventing the player from falling through
    } //End if - mask toggle
else
    {
    mask_index = spr_nomask; //else, if the player is below the platform, use the no collision mask, allowing the player to jump through it
    } //End else - mask toggle
you may notice that the if statement at the top has changed, and that change seems to have solved the issue.
 
Top