SOLVED Instance_place doesn't work for platforms (one way platform)

FullCup

Member
I'm trying to make a platform collision (only from top to down / falling). Well, this code works but when the player collide with other platform inside, he ignores the bottom collision and he goes through it. I Tried to use 'instance_place' but it doesn't work. What i want is to check the collision of 'obj_platform' with '(x, y + vspd)' and also check '(x, y)' for the same instance that is colliding and not any 'obj_platform' instance. (English is not my main language).

GML:
//Checking
if place_meeting(x,y + vspd, obj_platform) and vspd >= 0
{
      //Instance
      var inst =  instance_place(x,y + vspd, obj_platform);
   
      //Collision
      if !place_meeting(x,y, inst) and inst != noone
      {
            while !place_meeting(x ,y + 1, inst) y += 1;
            vspd = 0;
      }
}
game.png
 
Last edited:

DPMlofty

Member
you player first collision is with this obj_plataform or its other one?
and, u sure this works? (i speak portuguese if its helps u)
 

DPMlofty

Member
Try using this
GML:
if(place_meeting(x , y + vspd, obj_plataform)){
    while(!place_meeting(x , y + sign(vspd) , obj_plataform){
        y = y + sign(vspd);
    }
    vspd = 0;
}
y = y + vspd;
 

FullCup

Member
Try using this
GML:
if(place_meeting(x , y + vspd, obj_plataform)){
    while(!place_meeting(x , y + sign(vspd) , obj_plataform){
        y = y + sign(vspd);
    }
    vspd = 0;
}
y = y + vspd;
Ohhh, it's because I didn't know the name before, I'm trying to create one way block, so, i guess don't need to take the 'sign(vspd)' because it will be always greater and equal than 0. The platform only works when the player is not colliding other platform 'inside' him.
 

TheouAegis

Member
instance_place and place_meeting use the entire bounding box for checking. You do not want that. Use collision_line instead and check along a line along the bottom of the player.

another option, which I don't like because I think it's going to be slower but whatever, is to use instance_place_list to get a list of all of the platforms that you will be colliding with when you drop down, then loop through that list and find the platform whose y coordinate is greater than the player's. That is a platform whose ID you will want to collide with.
 

FullCup

Member
instance_place and place_meeting use the entire bounding box for checking. You do not want that. Use collision_line instead and check along a line along the bottom of the player.

another option, which I don't like because I think it's going to be slower but whatever, is to use instance_place_list to get a list of all of the platforms that you will be colliding with when you drop down, then loop through that list and find the platform whose y coordinate is greater than the player's. That is a platform whose ID you will want to collide with.
Wow! I think i get it.
So, in the case of collision_line:
GML:
collision_line(bbox_left, bbox_bottom + 1, bbox_right, bbox_bottom + 1, obj_platform, false, false)
Is this?
 

FullCup

Member
I don't believe it, based on 'collision line' i made the collision with the 'collision rectangle', and worked so well! thanks guys!

Now, I'm just looking for a bug on the platform to see if it's really ok.

The only "sacrifice" I needed to make was to put 1 pixel platformer mask.

Code:
//Checking
if collision_rectangle(bbox_left, bbox_bottom +1, bbox_right, bbox_bottom  + abs(1 + vspd), argument0, true, false) and vspd >= 0
{
      while !collision_rectangle(bbox_left, bbox_bottom +1, bbox_right, bbox_bottom  + 1, argument0, true, false) y = y + 1;
      vspd = 0;
}

platform.png
 

TheouAegis

Member
The alternative is to check if there's no collision at the current coordinates. So basically, is there a collision where you're going to move to but not a collision where you're currently at?

Edit: A 1 pixel mask would require a place_meeting(x,y+vsp,obj_platform) check followed by a while!collision_line(x,y+1,obj_platform,0) loop. A full mask with a pID=collision_line(x,y+vspd,obj_platform) to get the ID of the platform then a !place_meeting(x,y,pID) check to verify you aren't already inside that platform, then add to y pID.bbox_top-bbox_bottom.
 
Last edited:
Top