Proposal: Tilemap changes

Hi!

tileset.getRect should be implemented, tile.tileset is an optional property (if you use a unique tileset for one specific tile). The other method of getting a Tileset reference might be using tilemap.tileset, but it’s all in how you set up your code

We’ll consider center points, the issue is that we don’t want to burden the renderer with too much matrix manipulation, but I understand how this would make things more convenient. Happy if someone is interested in helping

You need this instead :
var rect = tilemap.tileset.getRect(tile.id);

I suppose you have set the default Tileset in Tilemap but you have not set any Tileset for the Tile. This is a correct implementation when you use only one Tileset. With this implementation, the renderer will use the default Tileset from Tilemap. If you want to use more than one Tileset, you will have to set a Tileset for each Tiles (or at least for each Tiles that don’t use the default Tileset in Tilemap). So the error you get is normal because Tile.tileset is null (openfl does not copy/paste the default Tileset here, it’s up to you to set it). Hope it’s clear enough.

So is there a guide to using the tilemap yet? I know theres a bunnymark, however it doesnt really specify how to use it for tiling as it only uses a single bunny image. Also does anybody know if it is bound to change again?

I don’t think it will change anymore.

And here is my library to import texture atlas format (Sparrow, Spriter, etc.) : https://github.com/loudoweb/openfl-atlas

Here is the how to:

//create a Tileset and add rectangles for all your tiles inside your atlas
var tileset:Tileset = new Tileset(Assets.getBitmapdata('atlas.png'));
var tileId:Int = tileset.addRect(new Rectangle(0,0,100,100));
//or you could import one using my openfl-atlas library
var tilesetEx:TilesetEx = new SparrowTileset(Assets.getBitmapdata('atlas.png'), Assets.getText('atlas.xml'));
//then create a Tilemap (this the displayObject)
var tilemap = new Tilemap(width, height, tileset, smoothing);
addChild(tilemap);
//add a tile using the tileId given by the addRect method
var tile:Tile = new Tile(tileId, x, y, scaleX, scaleY, rotation)
//or retrieve the tileID by name using my openfl-atlas library
var tile:Tile = new Tile(tilesetEx.getImageID(name), x, y, scaleX, scaleY, rotation);
//add the Tile into Tilemap
tilemap.addTile(tile);
//if you want to specify a different tileset for a Tile you can do that:
tile.tileset = tileset2;

Thanks for the help, I’ve got tiles going again now. What is the best way to do a scrolling map from this, it seems to take a lot of resources to continuously empty the array reload them every frame, though I still have to load new tiles in as the player moves. Do you guys use some form of binary search tree or something?

It seems rather difficult.

First: have you tried just rendering the entire map, including everything offscreen? If you can do that without much lag, maybe that’s good enough.

Otherwise…

Let’s say the screen is 15 tiles wide and 15 tiles tall. This means you can see a maximum of 256 (16*16) tiles at a time. My advice is to allocate an array of exactly 256 tiles, and use those.

Each frame, you’d check where the top-left corner of the camera is. Then you’d take the first tile, and set its id to whatever should show up in the top-left corner. Also, set its x and y coordinates to place it in the right spot. Repeat for the other tiles.

In case you’re confused, here’s a demo that I spent way too long on. Each of the 256 tiles are numbered so that you can see how they move around. You can also check out the source code if you’re curious.

This is great, thanks very much for the help.

Hi everyone,

I give suggestion if you have very large bitmap and loads very slow or game launcher will freeze.

Why not we use OpenGlView because bitmapdata draws very slow. From SimpleOpenGLView you can try OpenGLTile, OpenGLTileMap, …

Okay I will write own TileMap under OpenGL. After my work I will try. If it works faster than normal bitmapdata TileMap.

I give suggestion:

  • Animator
  • Effectiver
  • Ammo
  • Enemy
  • Movable
    And more functions

Easy to develop if they don’t know how do they develop TileMap games.
Thanks for taking care with my suggestions!

2 Likes

Sorry for stupid question, but how can I rotate tile about arbitrary pivot point?

Also what about color transform support?

rotate around point -> http://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/2drota.htm (the picture at bottom;)

may this formular helps:

positionVector = (positionVector - pivotVector) * matrix2D(
                                                            cos(alpha),  -sin(alpha) ,
                                                            sin(alpha),   cos(alpha)
                                                           )
                                 + pivotVector
1 Like

You need to compute the final position by yourself like @maitag suggested.

But be careful I think there is some bug when you use rotation after scaling or vice versa with specific values. Anybody has the same bug?

Currently tile.matrix is what the renderer uses, the get/set x, y, rotation (etc) are really convenience methods over the matrix, but as you know, the order of scale vs rotation affects this.

We don’t support a center or offset on tilesets, but perhaps for ergonomics, we need to. I wanted to avoid doing matrix math like this in the tile render, but perhaps this is important to usability

What do you mean? That my issue is not a bug? So how can I use negative scale for example? Should I only use matrix instead of get x,y,rotation and scale?

That’s what I do:

// rotation : Float
// scale : Float
// positionX : Float
// positionY : Float
// pivotX : Float
// pivotY : Float

var mat = tile.matrix;

mat.a = Math.cos(rotation) * scale;
mat.c = Math.sin(rotation) * scale;
mat.b = - mat.c;
mat.d = mat.a;

// set matrix **before** setting x and y, because they are setters, and they set
// internal flag __transformDirty
tile.x = positionX - pivotX * mat.a - pivotY * mat.c;
tile.y = positionY - pivotX * mat.b - pivotY * mat.d;

It seems that Matrix has method setRotation(theta : Float, scale : Float), but unfortunately it is private :frowning:

1 Like

@singmajesty It seems that tile.visible doesn’t work for neko, cpp and webgl.

Example (webgl) - http://pub.zame-dev.org/tmp/bunnymark-tilemap-visibility/
(click left mouse button to toggle first bunny visibility).

Source - https://gist.github.com/restorer/c160c1b844f4642c1bbd9e8c7aa2c89b
(basically same as BunnyMark, but instead of adding bunnies it toggle visibility)

When tile is not visible, tile position is not updated, but tile still visible.

Thank you!

It should be fixed in the latest commit now on GIT

1 Like

Using the latest GIT commit for the visibility fix of tiles, it seems that it doesn’t fix for Android output. The tiles I turn visibility off for don’t come back after I make them visible again.

Would the possibility of isometric support be a silly idea?

What do you mean? Isometric is just a matter of position and z-order…it’s up to you!

Indeed, it is! That’s why I thought of the possibility of adding a flag to Tilemap for handling such things out of the box.