1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice
  2. NOTICE: We will be applying a Xenforo update on Tuesday 25th of February. This means that from approximately 10:00 to 14:00 BST the forums will be offline (or possibly longer). Sorry for the inconvenience! Official Announcement here.

GMS 2 [SOLVED] Find the edge of the platform in 2d platformer

Discussion in 'Programming' started by player_2, Jan 17, 2020.

  1. player_2

    player_2 Member

    Joined:
    Jan 17, 2020
    Posts:
    5
    Hi guys! I am newbie and I need your help. Recently I started making a game in GMS2 and ran into a couple of questions that I couldn’t find answers to:

    1.There is an object that moves along the platform, reaches the edge and turns around in the opposite direction. it works like this:
    Code:
    var hspd = movespeed*dir;
    if(!place_meeting(x+ sign(hspd)*sprite_width+ hspd, y+1, oSolid))
    {
        while(place_meeting(x + sign(hspd)*sprite_width + sign(hspd), y+1,oSolid))
        {
            x+= sign(hspd);   
        }
    hspd = 0;
    dir *= -1;
    }
    x+= hspd;
    [​IMG]
    Such a code has many disadvantages - if the hole is less than the width of the sprite of the object, then it will not notice it and will move on. Also, if i change the direction of the sprite depending on the direction of movement (image_xscale), the code starts to work incorrectly:
    [​IMG]
    How to check the lack of a platform ahead? It seems that for 2d platformers this is a fairly common situation and the solution should be simple.

    2. Same case, but I still need to find out the ID block on the edge of the platform . if I do it this way ( the color of the block changes for clarity)
    Code:
    var hspd = movespeed*dir;
    if(!place_meeting(x+ sign(hspd)*sprite_width + hspd, y + 1, oSolid))
    {
        while(place_meeting(x + sign(hspd)*sprite_width + sign(hspd), y+1, oSolid))
        {
        x+= sign(hspd);
        }
    hspd = 0;
    dir *= -1;
    var inst = instance_place(x,y+1, all); // this string
    inst.image_blend = c_red;
    }
    x+= hspd;
    the code does not work correctly - on one side of the platform, the color changes at the desired block, on the other side - at the penultimate block:
    [​IMG]
    How to do it right? (sprite origin for all objects is in the center)
     
  2. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,449
    You should be using sprite_width /2.
     
  3. player_2

    player_2 Member

    Joined:
    Jan 17, 2020
    Posts:
    5
    Yes, but this only solves the problem of getting the id of the last block.
    The object does not stop at the very edge of the platform. Plus, changing the direction of the sprite (depending on the direction of movement) still breaks everything.
     
  4. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,449
    Oh, you need to use position_meeting() or instance_position().

    if !position_meeting(x + sign(hspd) * sprite_width/2 + hspd, y+1, oSolid)

    You don't need to check the whole mask for a collision, just the bottom corner points.

    And unless your hspd is super high, you should be able to just use instance_position(x,y+1,oSolid) to get the id of the oSolid directly below the NPC, then get its bbox_left if the NPC's hspd is negative or get its bbox_right if the NPC's hspd is positive. Then add the difference between the specified variable of both instances.

    if !position_meeting(x+sign(hspd)*sprite_width/2+hspd,y+1,oSolid) {
    var inst = instance_position(x,y+1,oSolid)
    if hspd<0 x+=(inst.bbox_left-bbox_left);
    else if hspd>0 x+=(inst.bbox_right-bbox_right);
    hspd = 0;
    dir *= -1;
    }

    If changing image_xscale breaks anything, either you have unnecessary code somewhere or your sprite's origin-to-bounds ratios are to blame. If your sprite has a centered origin but the collision mask isn't centered, then you should mirror the sprite before moving it to the edge of the ledge.
     
    Last edited: Jan 17, 2020
    player_2 likes this.
  5. player_2

    player_2 Member

    Joined:
    Jan 17, 2020
    Posts:
    5
    Many thanks! This seems to be what I was looking for.
     
  6. player_2

    player_2 Member

    Joined:
    Jan 17, 2020
    Posts:
    5
    and one more small question - I discovered if I change image_xscale to a negative value, the sign of sprite_width also changes. is this normal behavior?
     
  7. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,449
    Oh. Yeah. Yeah I see what you were saying about it messing things up. I haven't done collision checks the way you were doing them for a while, so I forgot about that. That was one reason why I stopped doing that way. You can use the function sprite_get_width(sprite_index) instead.
     
    player_2 likes this.
  8. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,449
    To expand on it real quick: sprite_width, sprite_height, sprite_xoffset and sprite_yoffset are negated when xscale or yscale are also negated, since they are both calculated using simple formulas that don't take negation into account. If you are going to use actual scaling on top of flipping and mirroring, then just remember to get the absolute value of those variables before you use them.
     
  9. player_2

    player_2 Member

    Joined:
    Jan 17, 2020
    Posts:
    5
    Thanks again!
     

Share This Page