• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Question - IDE What is the performance difference between collision objects vs tilemaps?

spacerobot

Member
Bare with me, I'm no gamemaker pro or anything, just a casual hobbyist messing around.

So my GMS 1.4 project has collisions based on solid objects. After messing around with GMS2 tilemap collisions I like the use of a collision tile layer in the room editor, but it seems that setting up the collisions with a tilemap are a pain for me. It would be a lot easier to check for place_meeting against an object than all the tilemap_get_at_pixel stuff.

So I am wondering if I stick with objects in GMS 2 instead of tilemap collisions what is the performance difference? Anything to worry about with a 2d platformer?

My perfect world would be to use a tilemap collision layer, assign that to a variable then use place_meeting or something similar to check against that like any other object.
 
Last edited:

FiveSprites

Member
The new tilemap collision stuff is lightning quick - and is really easy to work with. It's far better than using collision objects, and using solid objects is a bad idea.

Grab a handle to your tilemap in a Create event somewhere:

global.tileMap = layer_tilemap_get_id("MyTileMapLayerName");

Then to do a collision it's simply a case of checking the tile(s) nearest to your object:

tile = tilemap_get_at_pixel(global.tileMap, x, y) & tile_index_mask;

that returns the data for the tile you're currently on. It's good practice to and the returned tile data with the tile_index_mask.

The result from this will tell you which tile in your tileset is currently at the x/y of the object. For example, 0 is no tile, 1 is your ground, 2 is hot lava etc. Since hot lava is a little bit deadly, you know that your object is insta-dead!

To know if you will collide with a tile before entering, then get the next tile and determine if it's safe in the same way. If it's a wall then determine distance from the x/y of that tile and your current tile - the difference is the amount of pixels you can move.
 

Gradius

Member
Traditional collision checking loops through *every* single object (actually a bit of a lie now that GM has some kind of octree optimisation going on) that has collision, and compares its bounding box + collision shape to that of the object checking the coliision. With precise masks on, it also has to compare individual pixels.

Tilemap colliision simply rounds the checked position by the size of the tiles, and uses that to look up what value is in the tilemap array at that point.

So, thousands of checks vs one variable lookup (more or less). So while the former isn't guarenteed to slow the game down by a noticable amount, it's objectively way way slower.
 
R

Reaxgrim

Guest
yeah trying to still get my own head around tilemap collisions.

I went over the tut by gmwolf but didn't understand too much of it heh.
Seems the collisions only work if you are using the entire tilemap space (ie: all of the 32x32 etc) but if the drawn space is less than that it just looks like the player is floating.
 

spacerobot

Member
The new tilemap collision stuff is lightning quick - and is really easy to work with. It's far better than using collision objects, and using solid objects is a bad idea.

Grab a handle to your tilemap in a Create event somewhere:

global.tileMap = layer_tilemap_get_id("MyTileMapLayerName");

Then to do a collision it's simply a case of checking the tile(s) nearest to your object:

tile = tilemap_get_at_pixel(global.tileMap, x, y) & tile_index_mask;

that returns the data for the tile you're currently on. It's good practice to and the returned tile data with the tile_index_mask.

The result from this will tell you which tile in your tileset is currently at the x/y of the object. For example, 0 is no tile, 1 is your ground, 2 is hot lava etc. Since hot lava is a little bit deadly, you know that your object is insta-dead!

To know if you will collide with a tile before entering, then get the next tile and determine if it's safe in the same way. If it's a wall then determine distance from the x/y of that tile and your current tile - the difference is the amount of pixels you can move.
Ahh gotcha. I didn't understand the 0, 1, 2 returns. So do they correspond to the tiles in my tileset? Like if the next tile was poison liquid i would check for a value of 3?
 

spacerobot

Member
yeah trying to still get my own head around tilemap collisions.

I went over the tut by gmwolf but didn't understand too much of it heh.
Seems the collisions only work if you are using the entire tilemap space (ie: all of the 32x32 etc) but if the drawn space is less than that it just looks like the player is floating.
That is the tutorial I followed as well. I got it all working with my test game that has 16 x 16 tiles. I was struggling to see how I would expand this out to my other types of collision objects. The info above helps though. And yeah slopes do not seem to work with this method as is.
 

Ariak

Member
@spacerobot

Of course slopes work! Shameless link to my tutorial below. It works with grids - tilemaps are exactly the same. I've since expanded massively upon it in terms of performance, allowing for any sized rectangular objects, 360° controller support etc, but the base logic is the same for collision checking and slope movement.

https://forum.yoyogames.com/index.php?threads/on-slopes-and-grids-subpixel-perfect-topdown-movement-and-collision-line-without-objects.4073/

As for the tile index:


When hitting the sloped grid-wall I merely shifted the controller stick UP, yet the character will smoothly slide along the wall. I included the second character to make it more obvious this is not input based.

Edit: Back to the original question: grids are ~5% faster than tilemaps. Using AND to remove tilemap info like rotation will only make this "worse". Both are lightning fast in comparison to solid objects. See my tutorial - run the -gmz file, hit space and watch the fps skyrocket.
 
Last edited:

spacerobot

Member
@spacerobot

Of course slopes work! Shameless link to my tutorial below. It works with grids - tilemaps are exactly the same. I've since expanded massively upon it in terms of performance, allowing for any sized rectangular objects, 360° controller support etc, but the base logic is the same for collision checking and slope movement is the same.

https://forum.yoyogames.com/index.php?threads/on-slopes-and-grids-subpixel-perfect-topdown-movement-and-collision-line-without-objects.4073/

As for the tile index:


When hitting the sloped grid-wall I merely shifted the controller stick UP, yet the character will smoothly slide along the wall. I included the second character to make it more obvious this is not input based.

Edit: Back to the original question: grids are ~5% faster than tilemaps. Using AND to remove tilemap info like rotation will only make this "worse". Both are lightning fast in comparison to solid objects. See my tutorial - run the -gmz file, hit space and watch the fps skyrocket.
Thanks for the info! I knew that slopes worked, but I just meant that the particular youtube tutorial we followed didn't built it out fully to do slopes. I'll have to read through your article later today.
 
R

Reaxgrim

Guest
yeah that helps :)
i couldn't see how i could expand on it too but as you said "I didn't understand the 0, 1, 2 returns. " this was the same for me. now i understand it better. will mess around with it tonight
and thanks @Ariak for the info will give it a read.
 

spacerobot

Member
@Ariak

I was checking out your engine linked in the tutorial. It works very well. Interesting that I get better performance with it in GMS 1.4 over 2. In 1.4 before pressing space I am above 200 FPS and then over 1K after pushing space. In GMS 2 I do not break 200 initially and after pressing space I get max 700 or so.
 
Top