Google Summer of Code 2022 - The ENIGMA Team

Week 6: Hexagonal map support and some bug fixes

Contributor: Kartik Shrivastava
Project: Add Tiled compatibility to/from Enigma
Guided by: bjorn, fundies and Josh

Highlights:
  1. Added support to load uncompressed layer data tiles #3d5899f
  2. Added impl to apply background color to Room according to Tiled map #7273269
  3. Added support to hexagonal maps #c8415a8



Details

Hexagonal map support

There are few things which are very important while dealing with hex or hexagonal maps. Let's take a look into each one of them one by one.

hexSideLength: It tells us how much pixels each side of the hexagonal tile takes.
staggerAxis: It tells us in which direction does two parallel but opposite sides of the hexagon tile lie. It can take value of "x" or "y".
staggerIndex: Two consecutive staggerAxis rows/columns are arranged with an offset between one-another to make up a hex map. So staggerIndex tells us which index will remain in place and which has to be offsetted. It takes value of "odd" or "even".

I've created a small struct to store these three properties of hex map together.

Width and height of hex maps depends on hexSideLength and staggerAxis. Let's take an example with "x" as staggerAxis.

The effective width of each hex tile in "x" staggered hex map is (hexSideLength + 1/2*hexSideLength) or (3/2*hexSideLength). So total width becomes (numHorizontalTiles * (3/2 * hexSideLength)) + (1/2 * hexSideLength). We add (1/2 * hexSideLength) to the result to fully show the last hex tile in x direction.

The height of hex map in "x" staggered hex map is almost same as of orthogonal map, just with extra pixels (hexSideLength) given for last hex tile in y direction. So height becomes (numVerticalTiles * tileHeight + hexSideLength).

Below is the snippet for room width/height calculation in case of hex map, for both "x" and "y" staggerAxis.

Another notable changes has to be made in the arrangement of tiles in room, to make it look like a Tiled hexagonal map.

Let's take example of "x" staggered hex map again. The x position of top most corner of the given tile is almost similar to that of orthogonal map, with an exception. As mentioned earlier the effective width of hex tile is different than actual tile(a little smaller in stagger direction), so to compensate that we subtract (1/2*hexSideLength) from the actual (tileWidth) to get final top-left corner x value as (currentColumn * (tileWidth - (1/2*hexSideLength))). I imagine it as pulling all tiles lying in staggerAxis direction by some offset.

Now to decide top-left corner y position of hex tile in "x" staggered hex map, we will make use of staggerIndex. Also let's take a case when staggerIndex is "odd".
Whenever we will encounter (currentRow) index multiple of 2 we will set y position as (currentRow*tileHeight)(which is equal to that of orthogonal tile), otherwise we will set y position as (currentRow*tileHeight + hexSideLength).

Below is the snippet for tile x/y top-left corner position calculation in case of hex map, for both "x" and "y" staggerAxis as well as both "even" and "odd" staggerIndex.

That's a glimpse of how a hexagonal map can be parsed. Coming week I'll be working on isometric map support, thanks for following along!