Now I want to render level. This task consists of several subtasks:
- Output some random tiles from GD2;
- Read level from GD2, output it (just tiles, without objects, doors or enemies);
- Output objects, doors, hero and enemies (as they can move, they should be separate sprites, and not be displayed in the tilemap.);
- Add another camera (for level), move it along with hero.
Luxe already have built-in tilemap, so at first I decided to try it. I don’t found any documentation or examples how to use
Tilemap directly, instead of every example of tilemap use
TiledMap to load map from file.
Fortunately luxe is open sourced, so I can just look into
TiledMap source and figure out how to use
Tilemap. There are several classes for that:
Tilemap– base class, tilemap itself;
TileLayer– one layer of tilemap (map can contains several layers);
Tileset– set of textures (for each tile), tilemap can use several tilesets, has
first_idproperty, you need it if you have more than one tileset in the same tilemap;
Tile– one specific tile on layer, non-zero
idto determine what texture from tileset should be used;
IsometricVisual– renderer for map.
Tileset image must contain rectangular tile images, with optional spacing between tiles and margin. That’s fine for most of cases, but in GD2 we have floor and ceiling tiles (64×64), which are divided into 4 smaller tiles (32×32). Because of this
Tileset is not suitable for my tiles. Also built-in tilemap is little overcomplicated for my purposes 🙂
BTW I still tried it – works well and fast.
My own tilemap #1
OK, for the first time I tried to use
Sprite for each individual tile. It has
uv property, so I can point it to appropriate tile image inside tileset. It works, but very-very slow.
WTF? Tileset works fast, but bunch of sprites – slow. While I’m digging in built-in tilemaps, I didn’t find something special, that should speedup rendering. But it was.
Scene vs Batcher
I previously had a lot of experience in OpenFl. So, in OpenFl, if you want to display something, you should add it to display list (eg. on stage or as child of another display object). Initially, I thought that scene in luxe is something like stage in OpenFl. But it is not true. A closer analogue of OpenFl stage is batcher.
Scene is container for entities (ECS), it listen for game events (eg. mouseup, mousedown, etc.), and emit them to child entities.
Entity is one specific game object, it can handle game events, it can have components. But also it has
origin properties. This is confusing.
Visual is entity which have geometry, and which can be displayed on the screen. Also it set geometry transform parent to entity transform, so you can change entity properties (eg.
pos) to change actual geometry position.
Sprite extends Visual and adds support for
uv and flipping.
Geometry is something visible, for example
Visual by default create
QuadGeometry. There are much more geometry variations (eg.
Batcher contains display list of geometries (actually balanced binary search tree, sorted by depth and several other properties). Batcher is that guy, that renders everything.
My own tilemap #2
I don’t need
Entity capabilities for each individual tile, so instead of creating
Sprite and adding it to
Scene, I should create
Geometry (to be exact –
QuadGeometry) and add it to
It worked, and everything became fast again. For convenience I created following classes:
TileGeometry– basic geometry for GD2 tiles;
TileVisual– Visual with
TilemapVisual– Visual with 2d map of tile geometries.
Reading level and objects, doors, hero and enemies
That was quite easy part, because I already has code for reading level in Java (from GD2). I just rewrite it in Haxe. Rendering objects, doors hero and enemies is easy part too, because I already have
One unexpected problem was with hero graphics. Because Gloomy Dungeons and Gloomy Dungeons 2 is 3D shooters – you can’t see protagonist, so there is no graphics for him 🙂 I used my photoshop mad skills in Photoshop, and just change color of first enemy.
See you later!