1. Hey! Guest! The 34th GMC Jam will take place between August 22nd, 12:00 UTC (Thursday noon) and August 26th, 12:00 UTC (Monday noon). Why not join in! Click here to find out more!
    Dismiss Notice

GM:S 1.4 Pixel-Perfect Collision

Discussion in 'Programming' started by HalfSquat, Jul 21, 2019.

  1. HalfSquat

    HalfSquat Member

    Joined:
    May 5, 2019
    Posts:
    6
    For some reason whenever my character lands on the platforms, he lands at different positions, sometimes overlapping and sometimes landing outside the platform. When he's outside the platform, he can move left and right, but when he overlaps the platform, he's stuck until I jump. Is there a way to get pixel-perfect collision on the platforms? I tried using hps and vsp and using sign, but that doesn't seem to fix the issue. Capture2.PNG Capture.PNG Capture1.PNG
     
  2. TheSly

    TheSly Member

    Joined:
    Jan 16, 2017
    Posts:
    949
    Probably best to just check out a GML series that shows you a good way to set it up. Shaun's platform tutorial is worth following.



    And if you want to start with DnD, I have a series on platforming which does it too. Link is below.
     
  3. RefresherTowel

    RefresherTowel Member

    Joined:
    Jul 13, 2016
    Posts:
    1,188
    On top of @TheSly's post. Properly format your code, screenshots is fine on in-game action, but you should not be using screenshots of your code. Post the code inbetween [ code][/code] tags so we can copy and paste parts if necessary. Also, use brackets, lol. I'm not going to go through and fix the code because it's a screenshot and I would have to literally type the whole thing but:
    Code:
    if place_meeting && hp || place_meeting && hp {
    Is very probably not doing what you want.
    Code:
    if ((place_meeting && hp) || (place_meeting && hp)) {
    That lets the computer know what statements should be checked together and what are part of the or. As your code stands, it could be asking this:

    Chunk 1: if place_meeting
    Chunk 2: and hp or placemeeting
    Chunk 3 and hp

    Or it could be asking this:
    Chunk 1: if place_meeting and hp
    Chunk 2: or place_meeting and hp

    The computer is choosing one of those and it might not be the one you want.
     
    Last edited: Jul 22, 2019
  4. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,661
    Why the y+20? That's a really odd, seemingly arbitrary number.

    If you look for a collision at the current time, you need to move outside of the collision. Or if you check for a collision at the next future step, you need to move into the collision. Shaun's tutorials do the latter.
     
  5. HalfSquat

    HalfSquat Member

    Joined:
    May 5, 2019
    Posts:
    6
    Oops, yeah I know to use the code tags, I just forgot this time. I added in the parentheses, which doesn't seem to change anything.

    I tried using sign and hps and vsp like Shaun does, but that results in my character floating in the air. I'm also hesitant to do my platforming controls exactly like he does, since I have my own code for keypresses that affect hspeed, which works just fine.

    The reason I have y+20 is to try to keep the character out of the platform so that he doesn't overlap. Sometimes he floats above the platform, allowing him to move left and right, and sometimes he still gets stuck inside the platform and has to jump to get out.

    Code:
    if ((place_meeting(x,y,obj_ground) && hp > 0) || (place_meeting(x,y + 20,obj_platform) && hp > 0))
            {
                vspeed = 0      //standing still on collision
                sprite_index = spr_idle
              
                if keyboard_check_pressed(vk_space)     //jumping
                {
                    vspeed = -jspeed;
                    sprite_index = spr_jump
                }
                }else{
                if ((vspeed < grav) && !place_meeting(x,y, obj_ground)) || ((vspeed < grav) && !place_meeting(x,y + 20, obj_platform))  //falling code
                {
                vspeed += grav
                sprite_index = spr_jump
                }
    
     
  6. Old School Ben

    Old School Ben Member

    Joined:
    Feb 28, 2018
    Posts:
    16
    I ran into similar collision problems in my game. Upon inspection, my code looked good but since I was not using a sprite sheet and instead using individual GIFs for my sprites the collision masks would be different sizes between sprite animations. I also ran into problems with the origin position of the sprite being off by a few pixels.

    How I solved this was going in and adjusting the collision mask to be the same across each individual sprite. I also went in and adjusted the origin position of my sprites so I didn't have my sprites jumping around between animation transitions.

    You may also want to double check the collision mask/ code on the platforms that may be causing problems.

    Not really sure if this is the problem you are running into but it may be worth looking into if your code doesn't dictate what you are seeing when you run your game.
     
  7. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,661
    You can still use the built-in variables, is simply only adjust the x & y position when there is actually a collision detected, you do not adjust the position manually any other time.

    Don't forget to set the speed to 0.

    And definitely verify that your sprites are properly aligned correctly. That is of the utmost importance.
     
    Last edited: Jul 24, 2019
  8. HalfSquat

    HalfSquat Member

    Joined:
    May 5, 2019
    Posts:
    6
    So my character has several sprite animations, each with wildly different mask sizes and origin points. Would you know any way to make the masks and origin points uniform across multiple sprites (or a tutorial showing how to do so? I tried searching for one, but no dice)? I tried going into the individual animation sprites and changing the masks, but that made things more confusing for me.

    The collision masks on the platforms are the exact shape and size as the sprites, so they're probably not the problem.
     
  9. TheSly

    TheSly Member

    Joined:
    Jan 16, 2017
    Posts:
    949
    In the properties of the object, you can set the object to always use a single mask. It's in a section called "Collision Mask", just under where you select the sprite for the object.
     
  10. Old School Ben

    Old School Ben Member

    Joined:
    Feb 28, 2018
    Posts:
    16
    As far as I know, they all have to be edited individually, which is honestly a bit of a pain.

    Your collision mask may be the same size across all your sprites, but are they all in the same position in the sprite (x and y position)? Just because you can't see your collision masks moving when you change the sprite_index doesn't mean that they aren't jumping around.

    This sort of thing would cause my object to get stuck in walls when changing animations. I really do wish there was a simpler way to "sync" these values across multiple sprites. I'm not using a sprite sheet after all :/
     
  11. TheSly

    TheSly Member

    Joined:
    Jan 16, 2017
    Posts:
    949
    You can also add this to a draw event of your object to see the mask it is using.
    Code:
    draw_self();
    draw_set_alpha(0.3);
    draw_rectangle_colour(bbox_left,bbox_top,bbox_right,bbox_bottom,c_red,c_red,c_red,c_red,false);
    draw_set_alpha(1);
    
     
    Old School Ben likes this.
  12. Hyomoto

    Hyomoto Member

    Joined:
    Jul 7, 2016
    Posts:
    1,060
    I would propose an alternative take here, and one that is seemingly overlooked. The question is, "Do you actually need pixel perfect collision?" Or, to put it in a different way, do you need the computer to do pixel-perfect collisions for you? When it comes down to it, very few games have pixel perfect collision. It is entirely common to use circles, cylinders and rectangles to approximate collisions, and then work the art assets in around them. For example, perhaps you wish to have your character bump into a wall, and when they do so, they put their hands up on the wall. Having the computer figure out a bunch of calculations to make the sprite align with the wall might be fine during development, but to save performance (and arguably your own sanity), it would be far easier, and more reliable, to edit your sprites so that they animate naturally into the position you want them to be in. A pixel perfect collision with the wall, while still relying on the convenience of a rectangle to define the boundaries of the character, is much easier when you conform your art assets to your code, rather than vice versa.

    In your case, you have admitted that your sprites constantly change size and origin points. Well, you have some options. You can store those differences in code, which you can then look up to make the corrections you need, or you can adjust your art assets to be more universal. you can have differently sized bounding boxes, and even offsets, if you need, but generally speaking it's best to have those be somewhat consistent. Even if your goal is, "Oh, but while I'm ducking I want my bounding box to get smaller so I can duck bullets with perfect accuracy!" Well, without changing the bounding box at all, you could easily just store the player height during the ducking animation and compare that during a collision to see if the bullet should hit or not. You start from a place of consistency and then add the exception, rather than starting from the exception and working towards consistency.

    Other people might be able to offer a bit less abstract advice on this problem, but it's worthwhile to examine how much of the problem you are trying to solve is caused by other things you could be solving instead.
     
    Last edited: Aug 7, 2019
    Nocturne and HalfSquat like this.
  13. HalfSquat

    HalfSquat Member

    Joined:
    May 5, 2019
    Posts:
    6
    So I went and adjusted the bounding boxes for each of my player sprites to be an ellipse that is 80 pixels wide and 100 pixels tall. However, this doesn't seem to make any difference. I'm still having the issue of the player landing at different vertical positions when he jumps on the platforms. The player object itself has no sprite, it calls the different sprite animations through the code.
    Capture.PNG Capture2.PNG
     
  14. TheSly

    TheSly Member

    Joined:
    Jan 16, 2017
    Posts:
    949
    Did you do this?
     
  15. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    6,661
    Your player object obviously has a Sprite, otherwise he will not be able to use place_meeting(). You set the sprite_index, which is the same as giving the player a Sprite.

    Your two sprites have different bounding box positions. but this also means is if both sprites have the same origin, you are going to have collision issues because one Sprite is going to collide where another Sprite doesn't. it won't matter if you have Pixel perfect collision detection, because your sprites are not aligned with each other.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice