GameMaker Rotating tiles

I have a tilemap loaded into a layer. My question is how do I rotate and flip those tiles. I am not talking about the tileset.

I mean the same as what happens when you go to the room editor grid and use the rotate and flip tool intheGMS editor to change the individual tiles.

tile_set_rotate() is not what I want I need.

The same way as I do tilemap_set("layer name", current_tile, j ,i); I want to tilemap_set_angle("layer_name", current_tile, j, i);

Help would be much appreciated.
 
You need to get the unique index value for the tile and then use the specific tile functions to flip/rotate it. The manual has examples on all the appropriate pages, for example: http://docs2.yoyogames.com/index.html?page=source/_build/3_scripting/4_gml_reference/rooms/tilemaps/tile_set_rotate.html

Have you read the section on tiles in the manual? http://docs2.yoyogames.com/index.html?page=source/_build/3_scripting/4_gml_reference/rooms/tilemaps/index.html
Thanks for your reply. I have seen the manual but am trying to make sense of it. for a start the link you sent me seems to have a boolean value for rotate. Rotation should be a value between 0 and 359. I'm not understanding this.

Sprites are easy, you can even set the scale and rotation etc. If I know the map i'm using and I know the coordinates ofthe tile should I not just be able to rotate it.

tile_set_rotate() points to the tilesheet data and not the map thats been created.

I'm sure nobody wants to spend time looking at my project but I have provided a link anyway.

https://drive.google.com/open?id=1Bgd6Se6PJ6K2B9dz3S3eBaqwP3LKeEAx

Thanks in advance.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Thanks for your reply. I have seen the manual but am trying to make sense of it. for a start the link you sent me seems to have a boolean value for rotate. Rotation should be a value between 0 and 359. I'm not understanding this.
Ok, so, no, that's not right at all. The value IS boolean, as you can only rotate 90º or not. You would then use this in combination con the mirror/flip functions to get the 4 different rotation angles. Remember, that GMS2 tiles are NOT like sprites...they are handled differently which is why you have a seperate tileset resource. So a tile on a tile layer can ONLY be rotated 90º, and/or flipped, and/or mirrored.

tile_set_rotate() points to the tilesheet data and not the map thats been created.
The tilemap is simply a collection of tiledata "blobs", where each data blob has information about what tile index to use (where on the tileset to get the tile) and whether it is rotated, flipped and/or mirrored. So what that function does is set the bit in the supplied data blob that refers to rotation to either 1 or 0 and then returns the new data blob. You then use this to set the tile at the given tilemap index. Basically, the tilemap is simply a 2D array of data blobs, which you can then get and set as required.
 
Thanks again for your help. I understand the concept now, seems very simple. However, I still seem to be having issues with this. It's clearly something I'm doing wrong but to clarify it in my mind and make it simple so I'm not confusing myself with my own code would you please post an example.

So I have one tile layer called lyr_tile. I have a tilemap named tl_tilemap and one sprite spr_tilemap.

What code will I need to flip one tile vertically at 0, 0.

I copied and pasted the example code. I don't think this is even working because if I do
var bool = !tile_get_flip(data); or var bool = tile_get_flip(data); (No !) It works but the rotation and flipping etc is unaffected.

Also, I am confused as to why you need to get the ID because with tilemap_set() you only need to put the layer name in brackets and it works just fine.

Thanks.
 
Last edited:

Nocturne

Friendly Tyrant
Forum Staff
Admin
Okay, if you know the layer name you don't need to get the ID value, as the name will be linked by the IDE to the correct layer (as long as it exists)... this isn't specified in the manual, so I'll get that updated to be a bit more explicit. Before I post any code, I'll quickly outline the workflow:

Get the ID of the tilemap element on the layer
Use the tilemap ID to get the tile data "blob" for a tile
Manipulate this data (rotate, set the index, etc...)
Return the tilde data blob to the tilemap element

So:

Code:
var map_id = layer_tilemap_get_id("Layer_Name"); // Get the ID of the tile layer
var data = tilemap_get(map_id, 0, 0); // Get the data blob from the tile at layer cell (0,0)
var rotate = tile_get_rotate(data); // Get the rotation bit from the tile data
data = tile_set_rotate(data, !rotate); // Set rotate bit to (not) rotate (ie from 0 to 1 to 0) and return the new tile data blob
tilemap_set(map_id, data, 0, 0); // Set the tilemap position to use the new data
Keep in mind, that layers in CODE have an extra "layer" (pardon the pun) of complexity. In the room editor, you have distinct layers for different asset types (backgrounds, sprites, tiles), BUT that's just a convenience for editing in the rooms. In reality a layer can hold ANY asset type permitted, so you can have a layer with tiles and with sprites and with a background - in GM we call these asset specific layers "elements". This is because you actually have GenericLayer > ElementLayer(s) > ElementLayerContents. So, you need to get the tilemap ID for the (element) tilemap that has been assigned to the (generic) layer before you can set the (element layer contents) tiles on that tilemap.

Hope that makes sense! Tilemaps (and layers in general) can be a bit tricky when you first start working with them, but this extra complexity is a requirement for the speed at which things are now rendered compared to GMS1.4...
 
Last edited:
Ok, so, I think we are on the same page. I understand most of that. However when the code you provided as is, runs, but does not display anything. If I change the last line
tilemap_set(map_id, data, 0, 0); // Set the tilemap position to use the new data

to tilemap_set(map_id, 1, 0, 0); // Set the tilemap position to use the new data, it works (not rotated).

It's annoying because I completely understand the logic but It's just not working for me.

I assume If I use the code you posted, it should work as is without my need to understand.

Edit: I pulled the data variable into a message box and it comes up with a large string which clearly isn't the tile ID it's asking for because if I put in 1 it displays.

Thanks again.

PS. Thanks for pointing out that the layers are all the same. I did not know that. I thought they were useful but from what I understand they are for "warm fuzzys" only.

I'm still very confused about the
tilemap_set(map_id, data, mx, my);
line because data comes out as a long string and if I tell GM to tilemap_set(map_id, data, mx, my); it's telling it to use tile number 1023545468 whatever etc. Obviously, that tile does not exist.
 
Last edited by a moderator:

GMWolf

aka fel666
I'm still very confused about the
tilemap_set(map_id, data, mx, my);
line because data comes out as a long string and if I tell GM to tilemap_set(map_id, data, mx, my); it's telling it to use tile number 1023545468 whatever etc. Obviously, that tile does not exist.
Tile data and tile index is not the same thing.

Tile data actually holds all the info to draw the tile: the index of the tile, if it is rotated, if it is flipped or mirrored, etc.

Therefore, the numbers will look nonsensical at first.
 
Ok, This does make sense. I do believe I now understand the concepts as stated above and do understand what is going on now in principle.

However, I have been copying examples all day but am still left with a blank page.

The only way I can get anything to display is by putting a number between 0 and the number of tiles available.

If someone could post a project with a solution I would much appreciate it. All I want to see is a tilemap layer with one flipped tile and ill be happy.

Ok, This does make sense. I do believe I now understand the concepts as stated above and do understand what is going on now in principle.

However, I have been copying examples all day but am still left with a blank page.

The only way I can get anything to display is by putting a number between 0 and the number of tiles available.

If someone could post a project with a solution I would much appreciate it. All I want to see is a tilemap layer with one flipped tile and ill be happy.
I have tried everything. The best I can achieve is a tile as is on the screen. I could actually cry at this point.
 
Last edited by a moderator:

GMWolf

aka fel666
Dont put raw numbers. Use the tile_set_* functions to manipulate it.

For instance:
Code:
//flip tile at [0,0]
var tile = tilemap_get(tilemap, 0, 0);
var new_tile = tile_set_flip(tile, true);
tilemap_set(tilemap, new_tile, 0,0);
 
I was only using the numbers to check that it was working at all. I copied the code from above being.

var map_id = layer_tilemap_get_id("Layer_Name"); // Get the ID of the tile layer
var data = tilemap_get(map_id, 0, 0); // Get the data blob from the tile at layer cell (0,0)
var rotate = tile_get_rotate(data); // Get the rotation bit from the tile data
data = tile_set_rotate(data, !rotate); // Set rotate bit to (not) rotate (ie from 0 to 1 to 0) and return the new tile data blob
tilemap_set(map_id, data, 0, 0); // Set the tilemap position to use the new data

This gives me a blank screen with no errors. :(

I have been using GMS2 for a while now. I have to say it is wonderful, it is. But it kind of feels like a cult. If you're not in the know it's hard to get your head around the lingo until it clicks.

Then you get promoted to a higher state of consciousness with the caveat that you kind of know you're in a cult and this is not really the way it works but it's ok because that's just the way it works.

But still, I don't want to be shunned. I really do want this to work. the statement above still applies.



MOD EDIT: Multiple posts merged throughout the topic. Please do not double post constantly to reply. Simply edit your previous post if nobody else has replied in the meantime.
 
Last edited by a moderator:
And if you don't add the last tilemap_set, do you still get a blank screen?
Yes. The original code from the admin works in the sense that I get no errors. Replace the data with 1 or any other number up to the number of tiles. It works but no rotation.

Your code works how I think it should work. But it doesn't. Neither does the admins code for that matter.

I have attached a link to my project above but I know everybody's time is like gold dust but I would appreciate any help I can get on this one.
 
I'm still banging my head against a brick wall here. All I have is the following code. From my understanding, this should provide me with one mirrored tile at 0, 0.

I get a blank screen.

var lay_id = layer_get_id("lyr_tile");
var map_id = layer_tilemap_get_id(lay_id);
var data = tilemap_get(map_id, 0, 0);
data = tile_set_mirror(data, true);

tilemap_set(map_id, data, 0, 0);

Please help :(.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
That all looks correct... weird that it doesn't work. Let me set up a little test app and if it works for me I'll post it here for you to download and look at (and if it doesn't then I'll file a bug report!).
 

Electros

Member
I'm still banging my head against a brick wall here. All I have is the following code. From my understanding, this should provide me with one mirrored tile at 0, 0.

I get a blank screen.

var lay_id = layer_get_id("lyr_tile");
var map_id = layer_tilemap_get_id(lay_id);
var data = tilemap_get(map_id, 0, 0);
data = tile_set_mirror(data, true);

tilemap_set(map_id, data, 0, 0);

Please help :(.
The functions seem ok - I dropped them into a new blank project and the rotate / mirror worked without issue. This was using the example code from (https://docs2.yoyogames.com/source/...reference/rooms/tilemaps/tile_set_rotate.html), dropped into the Global Left Pressed event of a single control object. (I did rename bool to boolean, guess that one is reserved :))

Are you trying this with a new blank project, or incorporating into your current one? Sometimes other code will impact in various ways - took me a while to get my head around tile targeting last week in my vshmup, as all the tile_layers are continuously scrolling, so had to take that into account!
 
The functions seem ok - I dropped them into a new blank project and the rotate / mirror worked without issue. This was using the example code from (https://docs2.yoyogames.com/source/...reference/rooms/tilemaps/tile_set_rotate.html), dropped into the Global Left Pressed event of a single control object. (I did rename bool to boolean, guess that one is reserved :))

Are you trying this with a new blank project, or incorporating into your current one? Sometimes other code will impact in various ways - took me a while to get my head around tile targeting last week in my vshmup, as all the tile_layers are continuously scrolling, so had to take that into account!
I have resolved these issues now, thanks for all you help guys.
 

Telvarost

Member
I know I'm a bit late to the party, but I was searching the forums at one point for this and thought maybe someone else would find it useful:

var tiledata = tilemap_get( tilemap_element_id, cell_x, cell_y );
tiledata = tiledata | tile_flip | tile_rotate;
tilemap_set( tilemap_element_id, tiledata, xcell, ycell);

You can set the flip and rotate bits of a tile that you grab from your tile resource map to put onto a tile layer, instead of having to grab the tile from the layer and rotate it.
 
Top