Typing a level into your code is fine when it's tiny, but once it grows you'll want it in its own file. A .csv file is plain text: a number for each tile, commas between them, one row per line. Spreadsheet programs and level editors like Tiled can both save them.
This is assets/levels/level1.csv. -1 is an empty tile, and the other numbers are tiles from tiles.png: 0 is grass, 1 is dirt, 2 is stone, and 3 is water.
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,2,2,-1,-1,-1
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-1,-1,-1,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-1,-1,-1,1,1,1,-1,-1,-1,-1,-1,-1,-1,0,0,0
0,0,0,1,1,1,0,0,3,3,3,0,0,1,1,1
1,1,1,1,1,1,1,1,3,3,3,1,1,1,1,1
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
The game loads the file with the Asset Manager, waits for it, then turns it into a TilemapInteractable from the UI Module. Hover over the level to see the tile numbers.
loadFile() starts loading the file in the background and saves it as "level1". Until doneLoading() is true, the game just shows "Loading...".
Once it's ready, get("level1") gives you the file's text, which is exactly what TilemapInteractable wants. The tiles are 16 pixels, and tiles.png is 4 tiles wide.
To make the player stand on the level, check the tile at a position. screenToTile() turns a position into a tile position, and get() gives you the tile number there:
// Grass, dirt, and stone are solid. Water and empty tiles aren't.
function isSolid(x, y) {
const tile = level.screenToTile(x, y);
const number = level.get(tile.x, tile.y);
return number === 0 || number === 1 || number === 2;
}
// Is there ground just under the player's feet?
const onGround = isSolid(player.x, player.y + 16) || isSolid(player.x + 15, player.y + 16);
Load every level at the start, each with its own name, and switch levels by making a new tilemap:
MDog.AssetManager.loadFile("levels/level1.csv", "level1");
MDog.AssetManager.loadFile("levels/level2.csv", "level2");
function startLevel(number) {
level = new MDog.UI.TilemapInteractable(0, 0, MDog.AssetManager.get("level" + number), 16, "tiles.png", 4);
}