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

GameMaker Jump-through platforms

P

Pikpik

Guest
Is there a simple way to code Jump-through platfroms?

I followed this video:

With no success.

My code is completely different to his, I got it from this video:

If someone could atleast point me in the right direction that would be great.
 

TheouAegis

Member
Jump-through platforms are simply:
  1. Is my vertical speed greater than 0? ("if vspeed {")
  2. Is there a platform where I will be moving to? ("var inst = instance_place(x,y+vspeed,obj_platform); if inst {")
  3. Is that platform NOT where I currently am? ("if !place_meeting(x,y,inst) {")
  4. If the above is true, set your y coordinate to the top of the platform and reduce speed. ("y += inst.bbox_top - bbox_bottom); vspeed=0;}}}")
 
P

Pikpik

Guest
Jump-through platforms are simply:
  1. Is my vertical speed greater than 0? ("if vspeed {")
  2. Is there a platform where I will be moving to? ("var inst = instance_place(x,y+vspeed,obj_platform); if inst {")
  3. Is that platform NOT where I currently am? ("if !place_meeting(x,y,inst) {")
  4. If the above is true, set your y coordinate to the top of the platform and reduce speed. ("y += inst.bbox_top - bbox_bottom); vspeed=0;}}}")
Do I put it in the player object or the just object itself?
 

FrostyCat

Redemption Seeker
Do I put it in the player object or the just object itself?
Ask yourself these questions:
  • Do TheouAegis' instructions sound like something the player object would say, or do they sound like something the platform object would say?
  • Do TheouAegis' instructions sound like something that should run every step, or do they sound like something that can run once and be done with?
 
P

Pikpik

Guest
I'm new to Gamemaker so I don't know all the terminology yet.
 

FrostyCat

Redemption Seeker
At the very least you should know what these events are:
  • Create
  • Step
  • Draw
  • Draw GUI
  • Destroy
  • Cleanup
Read up on them until you can name and describe all 6 from memory. The kind of code from TheouAegis' instructions are typical of Step events.
 
P

Pikpik

Guest
GML:
if (vspeed < 0) & var_inst = instance_place(x, y+vspeed, obj_platform); if inst = 0)
if    !place_meeting(x,y,inst) 0)
y += inst.bbox_top - bbox_bottom); vspeed=0;}}}
Is this how I should write it?
 

TheouAegis

Member
Code:
if vspeed > 0 {
    var inst = instance_place(x,y+vspeed,obj_platform);
    if inst && !place_meeting(x,y,inst) {
        y += inst.bbox_top - bbox_bottom;
        vspeed = 0;
    }
}
 

TheouAegis

Member
Ugh. This again. This comes up roughly half the time. Solution varies from project to project. Try this for the last line:
y += inst.bbox_top - bbox_bottom - 1;
vspeed = 0;

I'm guessing he will start rapidly hopping up and down, which is a good sign if that's what happens.
 
P

Pikpik

Guest
There might be something wrong with my code.
GML:
onGround = false
//Get player inputs
key_left = keyboard_check(vk_left);
key_right = keyboard_check(vk_right);
key_jump = keyboard_check_pressed(vk_space);

//Calculate movement
var _move = key_right - key_left;

hsp = _move * walksp;

vsp = vsp + grv;

if (place_meeting(x,y+1,obj_block)) && (key_jump)
{
    vsp = -jumpsp
}

//Horizontal collision
if (place_meeting(x+hsp,y,obj_block))
{
    while (!place_meeting(x+sign(hsp),y,obj_block))
    {
        x = x + sign(hsp);
    }
    hsp = 0;
}
x = x + hsp;

//Vertical collision
if (place_meeting(x,y+vsp,obj_block))
{
    while (!place_meeting(x,y+sign(vsp),obj_block))
    {
        y = y + sign(vsp);
    }
    vsp = 0;
}
y = y + vsp;

//Animation
if (!place_meeting(x,y+1,obj_block))
{
    sprite_index = spr_player_jump;
    image_speed = 0;
    if (vsp > 0) image_index = 1; else image_index = 0;  
}  
else
{
    image_speed = 1;
    if (hsp == 0)
    {
        sprite_index = spr_player_idle;
    }
    else
    {
        sprite_index = spr_player_walk;
    }
}

if (hsp != 0) image_xscale = sign(hsp);

if keyboard_check(vk_down)
{
    sprite_index = spr_player_crouch
    if keyboard_check(vk_right) & keyboard_check(vk_down) then sprite_index = spr_player_crouch_walk;
    if keyboard_check(vk_left) & keyboard_check(vk_down) then sprite_index = spr_player_crouch_walk;
    jumpsp = 8
    walksp = 3
}  
   
if keyboard_check_released(vk_down)
{
    jumpsp = 9
    walksp = 3.5
}

if vspeed > 0 {
    var inst = instance_place(x,y+vspeed,obj_platform);
    if inst && !place_meeting(x,y,inst) {
        y += inst.bbox_top - bbox_bottom - 1;
        vspeed = 0;
    }
}
 

TheouAegis

Member
Because he was copying my code. You didn't change the variable.

Change vspeed to vspd.

I also think your block checking if not an obj_block is under the player, change the sprite. you can keep that, but you're jump through platform collision code is going to need to change the character sprite back to normal walking Sprite. And I predict that's probably going to cause the Sprite to lock on frame zero because you would essentially be resetting the Sprite every single step.
 
Last edited:
P

Pikpik

Guest
Okay, now the character pauses and then falls through the platform when colliding with the it.
 

TheouAegis

Member
Move the x=x+hsp and y=y+vsp lines to the very end of the code.

You want to move the sprite after it has had a chance to detect all collisions. So when it finds a solid block, it collides with solid blocks and then sets vsp or hsp to 0. Then it checks if it collides with a jump-through platform, and if it does, it sets vsp to 0. So by the end of the Step event, vsp will be 0 and you won't move. If you have the y+=vsp line where it is now, the player will fall if no solid block is detected, then it will check for a platform and lock to the platform, then the next step it will fall again and now won't stop on the platform because now it's below it.
 
P

Pikpik

Guest
GML:
if vsp > 0 {
    var inst = instance_place(x,y+vsp,obj_platform);
    if inst && !place_meeting(x,y,inst) {
        y += inst.bbox_top - bbox_bottom;
        vsp = 0;
    }
}
x = x + hsp;
y = y + vsp;
Like this?
 

TheouAegis

Member
Yes, if that's at the very end of your Step Event.

Code:
onGround = false
//Get player inputs
key_left = keyboard_check(vk_left);
key_right = keyboard_check(vk_right);
key_jump = keyboard_check_pressed(vk_space);

//Calculate movement
var _move = key_right - key_left;

hsp = _move * walksp;

vsp = vsp + grv;

if (place_meeting(x,y+1,obj_block)) && (key_jump)
{
    vsp = -jumpsp
}

//Horizontal collision
if (place_meeting(x+hsp,y,obj_block))
{
    while (!place_meeting(x+sign(hsp),y,obj_block))
    {
        x = x + sign(hsp);
    }
    hsp = 0;
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>REMOVE THIS    x = x + hsp;

//Vertical collision
if (place_meeting(x,y+vsp,obj_block))
{
    while (!place_meeting(x,y+sign(vsp),obj_block))
    {
        y = y + sign(vsp);
    }
    vsp = 0;
}
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>REMOVE THIS    y = y + vsp;

//Animation
if (!place_meeting(x,y+1,obj_block))
{
    sprite_index = spr_player_jump;
    image_speed = 0;
    if (vsp > 0) image_index = 1; else image_index = 0;
}
else
{
    image_speed = 1;
    if (hsp == 0)
    {
        sprite_index = spr_player_idle;
    }
    else
    {
        sprite_index = spr_player_walk;
    }
}

if (hsp != 0) image_xscale = sign(hsp);

if keyboard_check(vk_down)
{
    sprite_index = spr_player_crouch
    if keyboard_check(vk_right) & keyboard_check(vk_down) then sprite_index = spr_player_crouch_walk;
    if keyboard_check(vk_left) & keyboard_check(vk_down) then sprite_index = spr_player_crouch_walk;
    jumpsp = 8
    walksp = 3
}
 
if keyboard_check_released(vk_down)
{
    jumpsp = 9
    walksp = 3.5
}

if vsp > 0 {
    var inst = instance_place(x,y+vsp,obj_platform);
    if inst && !place_meeting(x,y,inst) {
        y += inst.bbox_top - bbox_bottom - 1;
        vsp = 0;
    }
}

x = x + hsp;
y = y + vsp;
 
Last edited:
P

Pikpik

Guest
Yeah, that's what I did. I copied and pasted the two lines, and removed the old ones.
 

TheouAegis

Member
//Animation
if (!place_meeting(x,y+1,obj_block))
{
sprite_index = spr_player_jump;
image_speed = 0;
if (vsp > 0) image_index = 1; else image_index = 0;
}
else
{
image_speed = 1;
if (hsp == 0)
{
sprite_index = spr_player_idle;
}
else
{
sprite_index = spr_player_walk;
}
}
What if you moved this block of code to the bottom of the Step Event? Also change "if !place_meeting(x,Y=1,obj_block)" there to just "if vspd!=0". Does that affect anything? I can't find anything in your code that would move the player other than changing the sprite at the wrong time.
 
P

Pikpik

Guest
Nope, still not working.
Changing it to if vsp=0! just crashed the game.
 
P

Pikpik

Guest
Tried it, but the character still pauses for a sec and then falls through the platform. I also can't crouch anymore.
 

TheouAegis

Member
Move the crouching code to the end too, then.

Did you put the platform mask back to Automatic?

I was just expecting at this point to just hear that the player was bouncing up and down....

What is your gravity set to? How much is vsp increasing by?
 
K

Kauan Henrique

Guest
GML:
event CREATE:
grv = 0.4; //gravity
vspd = 0; //vertical speed

--------------------------------------------------------------------------

script (get_input)
key_up = keyboard_check_pressed(ord("W"))

--------------------------------------------------------------------------
script (player state alive)

if place_meeting(x,y+1,obj_parede) and key_up{
vspd -= 8;
}

--------------------------------------------------------------------------

step event:

if place_meeting(x,y+vspd,obj_parede)
{
while(!place_meeting(x,y+sign(vspd),obj_parede))
{
y = y + sign(vspd);
}
vspd = 0;
}
y = y + vspd;

//gravity
vspd = vspd + grv;
 
K

Kauan Henrique

Guest
something like that, so you need to adapt it to your project, but the logic is this
 
P

Pikpik

Guest
The sprite mask was always automatic, the gravity is 0.4, and I'm not entirely sure where that last thing is.
 

MaxLos

Member
Hey, I watched that tutorial from Art Games and Tech too quite awhile back and it worked perfectly for me! The code used in the 2nd tutorial you posted has near identical collision handling code to the one used in the jump through platform tutorial and they are very compatible with each other. It would have been nice if you had posted your code from the platform tutorial cus maybe you made some typos or something and that's why it wasn't working for you, but its fine

Try this:
Code:
///Create Event
hsp = 0; //Horizontal Speed
vsp = 0; //Vertical Speed
grv = 0.3; //Gravity
walksp = 3;
jumpsp = 6; 
grounded = false; //Whether or not we're on the ground
Code:
///Step Event
//Inputs
key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_down = keyboard_check(vk_down);
key_jump = keyboard_check_pressed(vk_space);

//Grounded Checks
grounded = false;
if place_meeting(x,y+1,obj_block) grounded = true; //If the player is on top of a block, set grounded to true
with (obj_platform)
{
    //If the player is on top of the platform and not inside it, set grounded to true
    if place_meeting(x,y-1,other) and !place_meeting(x,y,other) other.grounded = true;
}
    
//Player Movement
move = key_right - key_left; 
if !(move = 0) 
{
    hsp = walksp * move; 
}
else hsp = 0;

//Gravity
if !(grounded) vsp +=grv; //If the player isn't on the ground, add gravity to their vertical speed

//Jump
if (key_jump) and (grounded) //If we're on the ground and the jump key was pressed
{
    vsp -= jumpsp; //Move us up by our jumpspeed
}

//Jump Through Platform Collision
with (obj_platform) //Run the following code from inside all the jump through platforms:
{
   if (other.vsp > 0) //If the player is falling down
   {  
      //If the player would collide with this specific platform at their current speed and is not already colliding with this platform
      if place_meeting(x, y-ceil(other.vsp),other) and !place_meeting(x,y,other)
      {
         while !place_meeting(x,y-1,other) //While the player isn't on top of this platform
         {
            other.y +=1; //Move them down
         }
         other.vsp = 0; //Then set their vertical speed to 0
      }
      
   }
}

//Horizontal Collision
if (place_meeting(x+hsp,y,obj_block)) 
{
    while (!place_meeting(x+sign(hsp),y,obj_block)) 
    {
        x = x + sign(hsp);
    }
    hsp = 0; 
}
x = x + hsp; 

//Vertical Collision
if (place_meeting(x,y+vsp,obj_block)) 
{
    while (!place_meeting(x,y+sign(vsp),obj_block)) 
    {
        y = y + sign(vsp);
    }
    vsp = 0; 
}
y = y + vsp;
 
P

Pikpik

Guest
Hold on, the character gets stuck in a block if they hit it with their head.
 

MaxLos

Member
Hold on, the character gets stuck in a block if they hit it with their head.
That's weird, I'm able to hit solid blocks from below just fine.. did you add on any additional code to what I gave you? If so, post your step event code
 
P

Pikpik

Guest
GML:
//Inputs
key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_down = keyboard_check(vk_down);
key_jump = keyboard_check_pressed(vk_space);

//Grounded Checks
grounded = false;
if place_meeting(x,y+1,obj_block) grounded = true; //If the player is on top of a block, set grounded to true
with (obj_platform)
{
    //If the player is on top of the platform and not inside it, set grounded to true
    if place_meeting(x,y-1,other) and !place_meeting(x,y,other) other.grounded = true;
}

//Player Movement
move = key_right - key_left;
if !(move = 0)
{
    hsp = walksp * move;
}
else hsp = 0;

//Gravity
if !(grounded) vsp +=grv; //If the player isn't on the ground, add gravity to their vertical speed

//Jump
if (key_jump) and (grounded) //If we're on the ground and the jump key was pressed
{
    vsp -= jumpsp; //Move us up by our jumpspeed
}

//Jump Through Platform Collision
with (obj_platform) //Run the following code from inside all the jump through platforms:
{
   if (other.vsp > 0) //If the player is falling down
   { 
      //If the player would collide with this specific platform at their current speed and is not already colliding with this platform
      if place_meeting(x, y-ceil(other.vsp),other) and !place_meeting(x,y,other)
      {
         while !place_meeting(x,y-0.9,other) //While the player isn't on top of this platform
         {
            other.y +=1; //Move them down
         }
         other.vsp = 0; //Then set their vertical speed to 0
      }
      
   }
}

//Horizontal Collision
if (place_meeting(x+hsp,y,obj_block))
{
    while (!place_meeting(x+sign(hsp),y,obj_block))
    {
        x = x + sign(hsp);
    }
    hsp = 0;
}
x = x + hsp;

//Vertical Collision
if (place_meeting(x,y+vsp,obj_block))
{
    while (!place_meeting(x,y+sign(vsp),obj_block))
    {
        y = y + sign(vsp);
    }
    vsp = 0;
}
y = y + vsp;

//Animation
if vsp != 0
{
    sprite_index = spr_player_jump;
    image_speed = 0;
    if (vsp > 0) image_index = 1; else image_index = 0;   
}   
else
{
    image_speed = 1;
    if (hsp == 0)
    {
        sprite_index = spr_player_idle;
    }
    else
    {
        sprite_index = spr_player_walk;
    }
}

if (hsp != 0) image_xscale = sign(hsp);

if keyboard_check(vk_down)
{
    sprite_index = spr_player_crouch
    if keyboard_check(vk_right) & keyboard_check(vk_down) then sprite_index = spr_player_crouch_walk;
    if keyboard_check(vk_left) & keyboard_check(vk_down) then sprite_index = spr_player_crouch_walk;
    jumpsp = 8
    walksp = 3
}   
    
if keyboard_check_released(vk_down)
{
    jumpsp = 9
    walksp = 3.5
}
 

MaxLos

Member
Hmm.. did you say earlier that your sprite mask was set to automatic? That might be causing the problem; when your character hits their head on a block, im thinking that collision mask for your player's falling sprite might be taller than the mask for their jumping one, and it might be clipping into the blocks when he hit them from below because of that.
In general, for platformers you usually want the player's mask to be a static, rectangular shape or you might run into problems like this one. The 2nd part to the tutorial you posted actually talks about this too and Shaun explains it better than I can:
(Watch from the time I left it at up to 9:07)

If that doesn't fix it then I'm honestly stumped
 
Last edited:
P

Pikpik

Guest
Nah, that was the platform object I was talking about earlier. The jumping sprite does have a manual collision mask, I also didn't have problems with it before I changed the code yesterday.
 

TheouAegis

Member
Make sure the size of the bounding box for both your jumping sprite and walking sprite are the exact same size, and make sure the distance from the origin to each edge is the same for both sprites.

For example, if the walking sprite is 4, 0, 15, 31 and origin is (12,31), then the jumping sprite doesn't need those exact same numbers but it needs the same dimensions, such as 0,8,11,39 with origin at (8,39).
 
Top