bouncing off blocks

Avram

Member
Hi all,

I have a player object that walks on a solid platform (obj_platform) but will bounce up on a bouncy block (obj_bouncyblock). Vertical movement is determined by vsp. Bouncespeed is set to 8. Here's the slightly modified Shaun Spalding code:

GML:
    //bouncy blocks
    bouncing_block = instance_place(x,y+16,obj_bouncyblock); //touching bouncing platform?
    if bouncing_block != noone
    {
       if (bouncing_block.y > y+16)//is player 16px above bouncy block?
       {         
            if !instance_place(x,(y-32),obj_platform) //check if player is about to hit their head on a platform
            {
                vsp = -(3 * bouncespeed);
            }
       }
    }
    
    if (vsp < 15) vsp += grav; //fall, but don't go too fast
    
    if (place_meeting(x,y+1,obj_platform)) //are we on a platform?
    {
         vsp = 0; //don't fall   
    }

    y += vsp; //move vertically
My problem is that if the player hits their head on a platform they rise through it when I'd rather have platforms above act as a barrier. I've tried while loops, for-next loops, a whole bunch of if statements, but cannot figure it out. Anyone got any ideas?
 

Nidoking

Member
Where's the part where you check for overhead collisions when you're not hitting a bouncing block? You're only checking during the step you actually bounce.
 

Avram

Member
Thanks for the reply, Nidoking.

I only need to check for overhead collisions when on a bouncing block in this situation. Each block is 32px square. What I am trying to do is check to see if the first 12 blocks above the player are not obj_platform. If not, then do a full bounce. If there is, say, an obj_platform 7 blocks above the player then that should affect how much the player can jump.

So that's where I was stuck trying to figure out how to always check the 12 spaces just above the player every time a block was touched in one step.
 

TheouAegis

Member
So your obj_platform is a jump-through platform that the player normally collides with only when falling?

Your first issue, right off the bat, is bouncing_block gets set to noone within 4 steps, so the anti-collision code never gets to run by the time there's a platform overhead. would need to calculate the distance between the bouncing block and the nearest platform directly overhead. Or platforms if the player could bounce with only a toe on the platform and there might be platforms off to the side. And if the player can move left or right while bouncing, then all of this is moot because then all platforms in the room need to be taken into consideration.

You could keep the bouncing_block variable aspect. When vsp is greater than 0, set bouncing_block to noone. Set a temporary variable to the id of the bouncy block, then if it's not noone, set bouncing_block to that temporary variable.
Code:
var n = instance_place(x,y+1,obj_bouncyblock);
if n bouncing_block = n;
if bouncing_block && !place_meeting(x,y-3*bouncespeed, obj_platform)
    vsp = -bouncespeed*3;
if vsp
    bouncing_block = noone;
 

Avram

Member
Sorry for the delay in responding and thank you Nidoking and TheouAegis for responding. Here's what I've come up with so far.
This new code checks to see if we're on a bouncy_block - if so, then it performs a while loop to check ten 32-pixel blocks above and adjusts the height of the bounce accordingly. It also uses bounce_flag to indicate if there is a bouncy_block in the 10-block range above the player.

So this almost works but does a strange thing. The player bounces once, hits a platform, drops down, and then bounces up again through the platform. I'll see if I can attach a GIF.

GML:
//bouncy blocks
    bouncing_block = instance_place(x,y+16,obj_bouncyblock); //touching bouncing platform?
    if bouncing_block != noone
    {
       if (bouncing_block.y > y+16)//is player 16px above player?
       {         
            while(bounce_locate < 320)
            {
                bounce_locate += 32;
                if instance_place(x,y-bounce_locate, obj_platform) //hit a platform?
                {
                    vsp = -bounce_locate/10;
                    bounce_locate = 320;   
                    bounce_flag = 1;
                }
            }
            if bounce_flag = 0
            {
                vsp = -(3 * bouncespeed);
                bounce_locate = 0;
            }
            else
            {
                bounce_flag = 0;
                bounce_locate = 0;
            }
       }
    }
    
    if (vsp < 15) vsp += grav; //fall, but don't go too fast
    
    if (place_meeting(x,y+1,obj_platform)) //are we on a platform?
    {
         vsp = 0; //don't fall   
    }

    y += vsp; //move vertically
 

Nidoking

Member
Why do you not just do something remotely normal and check to see whether the player collides with a block while moving upward and then make them stop when they hit the block, like absolutely every other game that allows the player to move upward?
 

Avram

Member
Hmm. Perhaps if I do an instance_place when vsp is negative and, if so, switch it to a positive value.
 

Nidoking

Member
Surely, you do something similar with horizontal motion and stop the player if there's a block within hsp, regardless of whether hsp is positive or negative. Is it that big a mental leap to do the same for vspeed?
 

Avram

Member
Thanks for all the ideas, everyone, especially TheouAegis.

Here's the finally working code. I don't get much time to program and am still learning how to program so it's not the most elegant but, most importantly works! The key was checking that the playerbody and playerhead aren't in the middle of a block and, if they are, reverse so they're dropping and, to be sure, move both playerbody and playerhead down 32 pixels.

GML:
    //bouncy blocks
    bouncing_block = instance_place(x,y+16,obj_bouncyblock); //touching bouncing platform?
    if bouncing_block
    {
       if (obj_bouncyblock.y > y+16)//is player 16px above player?
       {
            if !instance_place(x,y-vsp,obj_platform)
            {
              vsp = -(3 * bouncespeed);//bounce up into the air!
            }
       }
    }
    //bouncing into a platform? Move down and drop playerbody and player head
    if instance_place(x,y-16,obj_platform)
    {
        vsp = 8;
        y +=32;
        obj_playerhead.y +=32;
    }

    if (vsp < 15) vsp += grav; //fall, but don't go too fast
    
    if (place_meeting(x,y+1,obj_platform)) //are we on a platform?
    {
         vsp = 0; //don't fall   
    }

    y += vsp; //move vertically
 
Top