OFFICIAL Tech Blog: Precise Tile Collisions

Nocturne

Friendly Tyrant
Forum Staff
Admin
001_blog_post.jpg

This weeks tech blog from guest writer PixelatedPope shows a really ingenious method for getting precise collisions using a combination of tiles and instances. Really good stuff, and very well explained!

 
F

FranFox

Guest
Hi there!

I'm following the tutorial and I'm having a strange behaviour. I'm stuck on the Replace "Place Meeting()" point.

- I have my new collision tile
- I've created my tile layer and setup the tile
- I've created the tile_meeting script

So, I've replaced all my place_meeting() instances by the new tile_meeting() ...

Example:
on_ground = tile_meeting(x, y + 1, "TileCollision") ? true : false;

... and it seems the game go into an infinite loop, inside this for in tile_meeting script...

Code:
for(var _x = _x1; _x <= _x2; _x++){
for(var _y = _y1; _y <= _y2; _y++){
    if(tile_get_index(tilemap_get(_tm, _x, _y))){
    return true;
    }
}
}
Any suggestion? Thanks!
 
Last edited by a moderator:
F

FranFox

Guest
Thanks @gnysek I had some problem with my player movement code that was causing an infinite loop. It's normal that now I can't go outside the room? Seems that player collide with the room boundaries.
 
Last edited by a moderator:
A

atmobeat

Guest
So, I'm sorry for a post on this 2 months later but I have a question about this method. Since you use place_meeting in tile_meeting_precise, don't both the checker object and the calling instance have to have precise collision enabled? If precise collision is enabled on the calling instance, won't it produce the wrong results using the sprite instead of the bounding box? Won't you have heads running into the wall and stopping the character rather than the feet (where the bounding box will be located for top-down games)?

I feel like you really need two different checker objects. One for the tiles and one to act like the calling object's collision mask. Am I missing something here.
 

Yal

šŸ§ *penguin noises*
GMC Elder
f precise collision is enabled on the calling instance, won't it produce the wrong results using the sprite instead of the bounding box?
The bounding box is basically exactly the collision mask of a sprite, but always rectangular. (You can check rectangle collisions with just 4 less than / greater than maths checks, so it's a lot faster than checking every pixel in a precise mask for overlaps). So the difference is that the bounding box covers the same area as the sprite's collision mask, but it's less precise. Having precise collision checking turned on will never make your collisions less accurate, only less efficient CPU-wise.


Also, feedback on the blog itself:
You will need to repeat this process every time you add or remove tiles from your tileset! Though if youā€™ve used tiles before, you know that altering your tileset is going to do a lot more damage than make you do this againā€¦ especially if youā€™ve already designed multiple rooms with said tileset.
Changing the height of a tileset won't scramble the tiles (they're numbered from left to right, up to down, and all pre-existing tiles maintain their index after changes to a tileset).

In my approaches to tile collisions so far, I've combined these two things into one: tile collisions are based on the left and top coordinates of the tile, so e.g. tiles whose left coordinate is 64 always are slopes and upwards/downwards slopes are in pairs on alternating rows. This approach also makes it possible to reuse tile data with a different tileset easily (since you're forced to make the tiles line up for every tileset) and can speed up your workflow since you always know where each type of tile is located in the tileset, but the main benefit is having less cases to handle in the code.
 
Last edited:
A

atmobeat

Guest
The bounding box is basically exactly the collision mask of a sprite, but always rectangular. (You can check rectangle collisions with just 4 less than / greater than maths checks, so it's a lot faster than checking every pixel in a precise mask for overlaps). So the difference is that the bounding box covers the same area as the sprite's collision mask, but it's less precise. Having precise collision checking turned on will never make your collisions less accurate, only less efficient CPU-wise.
Thanks Yal for responding and for all you do on the boards. I've often found your comments helpful, but I'm still unclear on something because my confusion doesn't come from the accuracy of the check but what the collision-check is using to check for overlap.

If both the calling instance and the other object have to use precise collisions, then the objects' sprites themselves become the collision mask and bounding boxes aren't used anymore to check for overlap. I'm just getting this from the manual's entry for place_meeting (http://127.0.0.1:51291/index.htm#t=...rhsearch=place_meeting&rhhlterm=place_meeting). I'm especially referring to what's happening in the picture showing the difference between using place_meeting with just bounding boxes and using it with precise collision checked and the sprite becoming the collision mask.

In a zelda-like the bounding box is usually placed down around the feet or legs to help with the illusion of a somewhat 3d environment (e.g. when you collide with a wall above you, the character's head will be drawn over the wall). But if you are using PixelatedPope's method, and your player sprite is shaped like a person, then the head is now part of the collision mask because that's what precise collision being checked does.

Check out the pic in the manual's entry above (I mean, I'm sure you know how it works and all). Am I right here or am I missing something still?

I do think PixelatedPope's method can still work out really well but it seems not quite where it should be yet.
 
A

atmobeat

Guest
Ok, so I've heard from PixelatedPope over on his itch.io page and the crucial thing that's missing to understand how this system works is that any instance calling tile_meeting_precise does need "Precise per frame" collision type selected and you must assign a separate sprite to the collision mask (unless the sprite happens to work for some reason).

I feel kinda dumb, as usual when using something new in GMS, but I've just never needed to assign a different sprite for a collision mask. A rectangular one usually works fine for my purposes. This may have been obvious to others but I think it would be worth adding into the blog post to help out noobs like me, especially as it really is a cool method.
 

badwrong

Member
Cool way of doing things with the invisible object.

Personally I just use a few lines of math based on the index of the collision tile.
 
Top