[Mostly SOLVED] Weird behavior with jump through platform

P

Palocles

Guest
I've just implemented Shun Spaldings code for jump through platforms in my game and my player can jump up through them fine but will not jump back down through them from their own surface.

If I jump a press down while in the air above the platform I will fall through it but if I just press down while on the platform the player object doesn't move.

I expect this is some weird interaction with my movement states which I should be able to allow for but have been unable to so far.

As per the video (
) the platform has a create event to remove the sprite, and a draw event to replace it and the following step event, incorporating some fixes from the video comments.

GML:
 if(instance_exists(objPlayer))
{
      if((objPlayer.bbox_bottom) > y) || ((objPlayer.key_down))// && (objPlayer.key_jump))
      {
          mask_index = -1;
      }
      else
      {
          mask_index = sprMovingPlatform;
      }
}
My intention is for the player to be crouching and press jump to fall through, on a normal block a crouching player will jump if jump_key is pressed.
here is the relevant script for crouch:
Code:
function scrPlayerCrouch(){

    show_debug_message("entered Crouch State");

    sprite_index = sprPlayerCrouch;
    //image_xscale = currentFacing;
    //running = 0;
    //onGround = 1;
   
    if(image_index >= (image_number -1))
    {
        image_speed = 0;
    }
   
    //should allow player to drop through the block
    if (place_meeting(x, y+1, objJumpThruPlatform) && (key_jump))
    {
        show_debug_message("fall through platform");
        scrPlayerGravity();
        currentState = playerState.jump;
        image_speed = 1;
    }
    else if(place_meeting (x, y+1, objBlock)&&(key_jump))
    {
        {
            show_debug_message("crouch to jump")
            vSpeed = jumpSpd - 0.5;
            currentJump ++;
            currentState = playerState.jump;
            image_speed = 1;
        }
    }

    if (!key_down)
    {
        currentState = playerState.idle;
        image_speed = 1;
    }
   
}
The debug messages don't seem to be running either.

Any other code helpful?

Thanks for the help.
 
Last edited by a moderator:

TheouAegis

Member
I always just added 1 or 2 to y when jumping down,since that automatically invalidates most jump-througj collisions. It's not always ideal, but there are ways to work around its shortcomings.
 
P

Palocles

Guest
I see.

Well, I had read the problems others had had and wasn’t too worried about it because they aren’t likely to apply in my case. Single player and no enemy mobs on the platforms.

I did see another example tutorial for one way platforms but it didn’t allow jumping down through them. I’ll try it tomorrow and see though.

Thanks.
 

TheouAegis

Member
Does your platform have a sprite assigned to it? I'm guessing no, if your code works for normal jumps, but just reminding peeps that mask_index=-1 means the sprite_index will be used for collision checks, of a sprite was assigned.
 
P

Palocles

Guest
Platform has a create event to remove the sprite then a draw event to put it back.

I'm not getting the debug message from the attempt to jump through though, that might be more significant.
 

Nidoking

Member
You're setting the mask_index to -1 when obj_player.key_down, which is apparently true whenever you enter the script you posted for the crouch state. If the mask is -1, then how do you expect place_meeting to find the platform? It has no collision mask.
 
P

Palocles

Guest
Good catch, I'll see if changing it works.

edit: Still not working. I'll have a look at what Slyddar posted and see if I can change the code with that in mind.
 
Last edited by a moderator:

Amon

Member
Isn't this the worst way to do one way platforms? The whole -1 mask_index causes too many headaches. I remember a post that covered this which used an alternative method for one way platforms. I'll try and hunt it down.
 
P

Palocles

Guest
Apparently it is. Hence my trouble now and Slyddars comment in his linked post.

It's now causing issues with my moving platforms, even though I finally have them carrying my Player object the way i want them to.
 

poliver

Member
Stop this craziness. All you need to do is check for collision on the way down only. That's it!
When you're jumping down just move your character 1 or 2 pixels below it so he's no standing on it.
 
P

Palocles

Guest
So i will have to selectively turn off collision detection in my gravity script.

Got any suggestions for that?
 

poliver

Member
no need to turn it off, just add an extra check.

if(colliding-normally){
normal-collision-check
}
else {
if(colliding-only-on-the-way-down-only-with-one-way-platform) {
one way platform collision check
}
}
 
Last edited:
P

Palocles

Guest
I fixed this issue with this gravity script:
GML:
function scrPlayerGravity()
{
    
    if (place_meeting(x, y, objBlock))
    {
        vSpeed += global.grav;
    }
    else if(vSpeed < 0)
    {
        
        if(place_meeting(x, y + vSpeed, objJumpThruPlatform))
        {
            vSpeed += global.grav;
        }
        else if(place_meeting(x, y + vSpeed, objBlock))
        {
            while(!place_meeting(x, y-1, objBlock))
            {
                y -= 1;
            }
            vSpeed = 0;
        }
        else
        {
            vSpeed += global.grav;
        }
    }
    else
    {
        if(!place_meeting(x, y + vSpeed, objBlock))
        {
            vSpeed += global.grav;
        }
        else if(place_meeting(x, y +vSpeed, objJumpThruPlatform)&&(key_down))
        {
            vSpeed += global.grav;
        }
        else if (place_meeting(x, y + vSpeed, objBlock))
        {
            while(!place_meeting(x, y+1, objBlock))
            {
                y += 1;
            }
            vSpeed = 0;
            currentJump = 0;
            onGround = true;
            currentState = playerState.idle;
        }
    }
    
    y += vSpeed;
}
No collision masks are turned off, no code is required within any of the objects (ie, platforms). The script for crouching moves the player object down a pixel and gives them a slight vSpeed push. Running off the edge of a block works correctly, ie, transitions to jump animation and down movement.

However there are still two issues. First if the player object head clips a platform it might cause it to fall through the platform it's supposed to land on. Second, the player object occasionally falls through the floor. Not sure how to fix the floor issue though.
 

TheouAegis

Member
Is the head inside a jumpthrough platform while standing on a floor that he starts sinking through? You are using place_meeting(), which doesn't care where the platform is in relation to the player.
 

poliver

Member
I fixed this issue with this gravity script:
GML:
function scrPlayerGravity()
{
   
    if (place_meeting(x, y, objBlock))
    {
        vSpeed += global.grav;
    }
    else if(vSpeed < 0)
    {
       
        if(place_meeting(x, y + vSpeed, objJumpThruPlatform))
        {
            vSpeed += global.grav;
        }
        else if(place_meeting(x, y + vSpeed, objBlock))
        {
            while(!place_meeting(x, y-1, objBlock))
            {
                y -= 1;
            }
            vSpeed = 0;
        }
        else
        {
            vSpeed += global.grav;
        }
    }
    else
    {
        if(!place_meeting(x, y + vSpeed, objBlock))
        {
            vSpeed += global.grav;
        }
        else if(place_meeting(x, y +vSpeed, objJumpThruPlatform)&&(key_down))
        {
            vSpeed += global.grav;
        }
        else if (place_meeting(x, y + vSpeed, objBlock))
        {
            while(!place_meeting(x, y+1, objBlock))
            {
                y += 1;
            }
            vSpeed = 0;
            currentJump = 0;
            onGround = true;
            currentState = playerState.idle;
        }
    }
   
    y += vSpeed;
}
No collision masks are turned off, no code is required within any of the objects (ie, platforms). The script for crouching moves the player object down a pixel and gives them a slight vSpeed push. Running off the edge of a block works correctly, ie, transitions to jump animation and down movement.

However there are still two issues. First if the player object head clips a platform it might cause it to fall through the platform it's supposed to land on. Second, the player object occasionally falls through the floor. Not sure how to fix the floor issue though.
1. don't check the ground collision against the whole collision mask of the player. use bbox_bottom or smtn similar
2. is the 'ground' by any chance thinner than your possible max vspeed at any point?
 
P

Palocles

Guest
Theou, I realise that if the player object overlaps a platform at the top then it won’t land on one that is close below it. In this case the collision mask of the player should be small enough to fit between and I fixed the problem by moving the platforms 10 pixels further apart but I’d like a better fix that allows for close platforms.

Roman, if I used bbox_bottom how do I keep the player moving once the bbox bottom is clear of the block underneath? Or do I keep using place meeting for that and use bbox bottom to check for a landing?

The blocks that make the floor (and everything else) are 20 x 20. Gravity is 0.3 and steps/sec is 60 so after a bit more than a second of falling the vSpeed would be over 20 pixels and that could happen. I have checked falling from high places and it doesn’t seem to be the cause.

However the falling thru floor bug resolved itself last night when I did cosmetic work on the room. I realised I hadn’t autotiled over the blocks. To do that I had to reduce the grid size to 10 move all the blocks so the auto tile brush would line up. After that, and moving the platforms to realign, the bug stopped happening.

If it doesn’t reappear I can move on but I would like a better collision detection for landing on the jump thru blocks still.

Happy New Year too!
 
Top