Contents

Map Structure

Introduction

I say a lot in this guide that's said elsewhere in the docs, so you may yell out "Nasty Mr. Repeat-yourself!" if you want. Still, it's good to have a basic structure guide somewhere to bring other information together, and to provide a simple overview you can read through.

Maps

Dusk's primary purpose is loading maps. It follows that the map object is Dusk's primary class. Map objects are the "root" from which everything else in Dusk comes: layers, camera tracking, culling, and anything else you can think of.

To build a map, use the aptly-named dusk.buildMap() function. This function can either take a file path pointing to the map file or a table of map data previously loaded with the once again aptly-named dusk.loadMap(). The former case will probably be what you use most. The only time you'll need dusk.loadMap() is if you need access to the map's data in your code.

local dusk = require("Dusk.Dusk")

local map = dusk.buildMap("map.json")

Layer Access

Possibly the most accessed field in a map is the layer table. It stores the map's layers by both index and name. Simply put, this means you can access a layer by either its number or the name you specified in Tiled. By number, the top layer in the map is layer #1, and the bottom layer is layer #(however many layers you have).

local topLayer = map.layer[1]
local bottomLayer = map.layer[#map.layer]

To access a layer by name, you... er... access it by name. Sorry, but there's not really another way to say it. The name corresponds to what you set in Tiled, either in the layer properties menu or the layer list.

local layer = map.layer["myTileLayer"]

Due to Lua's happy dot notation, you can omit the brackets and quotes if the layer name allows it.

local layer = map.layer.myTileLayer

Layer Iteration

The section above raises a question just begging to be answered. Viz., if each layer is stored twice in map.layer, how do you keep from "hitting" each one twice when you iterate through them?

for layerName, layer in pairs(map.layer) do
  print(layerName)
end

If you run the code above, you'll get each index from 1 to the number of layers, then each layer's name printed out to the terminal. That means we can't iterate with a simple pairs() iterator. Have no fear, however! Dusk comes with a set of iterators just for you.

for layer in map.layers() do
end

for layer in map.tileLayers() do
end

for layer in map.objectLayers() do
end

for layer in map.imageLayers() do
end

Each of these iterators does exactly what it seems. Using them, you can iterate through each layer or each layer of a certain type easily.

Even though you can technically iterate through each layer of a certain type by using a map.layers() loop and a simple layer type check, it's clearer (and a tad faster) to use the dedicated iterators.

Unit Conversion

If you're making any sort of normal game, chances are that you'll need to convert between tiles and pixels somewhere. Dusk has a number of ways, covering each use case, to accomplish that.

local x, y = map.tilesToPixels(16, 16)
local x, y = map.tilesToContentPixels(16, 16)

The above functions convert tile coordinates to pixel coordinates. Surprised? You shouldn't be; I would have thought the names to be pretty clear. The difference between the two functions is that the first function (and its alias, map.tilesToLocalPixels()) returns local pixels and the second returns content pixels. You'll use map.tilesToPixels() when, for example, you need to place an object at a tile location in the map - say, spawn and enemy or build a sign - and map.tilesToContentPixels() when you need the position of a tile globally, say to display an overlay on the map.

You may have noticed my mention that the first function has an alias of map.tilesToLocalPixels(). You can use either function, and map.tilesToPixels() is probably simpler, it's just that having map.tilesToLocalPixels() and map.tilesToContentPixels() keeps the API "symmetrical."

Besides the tile-to-pixel functions, Dusk also has pixel-to-tile functions to convert back from pixels.

local x, y = map.pixelsToTiles(512, 512)
local x, y = map.contentPixelsToTiles(512, 512)

Again, there are two different methods here. The first function uses local coordinates, and the second uses content coordinates. Use the first function when you need the tile location of a point local to the map - e.g. "what tile is the player on" - and the second when you need the tile location of a content point - e.g. "what tile is the touch event inside."

Just like the tile-to-pixel conversion functions, map.pixelsToTiles() has an alias of map.localPixelsToTiles().

Destroying the Map

So you've almost completed your game, and you're ready to add the "wrapper screens" for file selection, credits, achievements, et al. You're ready to change scenes. There's just one more thing to do before changing scenes: destroy the map. In true clear Dusk API style, telling the map to destroy itself is quite simple:

map.destroy()

This function is like Corona's display.remove() or object:removeSelf(). You need to call it when you're done with the map to let Dusk clean things up, delete the layers, clear out everything, and generally finish things up.

And speaking of finishing things up, you've reached the end of this guide.