I made a block that converts a TileMap to stringified JSON (For saving TileMaps to the device with the Settings extension), but now that I need to write a block that converts the stringified JSON back to a Tilemap I need to generate a new TileMap, the closest built-in function I found was the tiles.createTilemap
function which takes in the arguments data: Buffer, layer: Image, tiles: Image[], scale: TileScale
but I don’t know how to use data, layer, and scale. They’re used to generate a TileMap from assets but I’m generating one from JSON not from assets.
An example of the stringified JSON of a TileMap:
Converts to:
{"size":[3,3],"tiles":[[{"id":1,"wall":true},{"id":0,"wall":false},{"id":1,"wall":true}],[{"id":0,"wall":false},{"id":0,"wall":true},{"id":0,"wall":false}],[{"id":1,"wall":false},{"id":0,"wall":true},{"id":1,"wall":false}]]}
2 Likes
I’m trying to create a new empty TileMap with tiles.createTilemap(hex
, img, [], TileScale.Sixteen);
but I cant change the width and height because they’re constant values. So I can’t generate a TileMap like this:
const data = {
"size": [3, 3],
"tiles": []
}
const tilemap = tiles.createTilemap(hex``, img``, [], TileScale.Sixteen);
tilemap.width = data.size[0]; // Error, 'width' is a constant value.
tilemap.height = data.size[1]; // Error, 'height' is a constant value.
1 Like
Oops, markdown error! It’s suppose to be tiles.createTilemap(hex``, img``, [], TileScale.Sixteen);
and not tiles.createTilemap(hex
, img, [], TileScale.Sixteen);
. And as I expected, the code doesn’t work. Does anyone know how to generate an empty TileMap with a specific width and height? Thanks!
can you not change:
const data = {
"size": [3, 3],
"tiles": []
}
to:
data = { // Change from constant to normal
"size": [3, 3],
"tiles": []
}
// Set "size" to something higher in an 'on game update' or 'while True'
// or some other code
1 Like
It’s an example, and I can’t define variables without var/let/const (This is JavaScript). The low size is also for an example.
The variable doesn’t get changed, so it can be const instead of let. Const also uses less memory.
The buffer must have a size of the number of tiles in x * the number of y + 4 bytes. Since the first two bytes are used to specify the x size of the tilemap and the second two for the y size.
let buffer = Buffer.create((xSize * ySize) + 4);
buffer.setNumber(NumberFormat.UInt16LE, 0, xSize);
buffer.setNumber(NumberFormat.UInt16LE, 2, ySize);
and the image should be the same size as the tilemap
image.create(xSize, ySize)
it would fit you like this…
const xSize = 16; // tilemap width
const ySize = 16; // tilemap height
const buffer = Buffer.create((xSize * ySize) + 4);
buffer.setNumber(NumberFormat.UInt16LE, 0, xSize);
buffer.setNumber(NumberFormat.UInt16LE, 2, ySize);
const tilemapImg = image.create(xSize, ySize);
const tilemap = tiles.createTilemap(buffer, tilemapImg, [], TileScale.Sixteen);
1 Like
I was thinking more in this direction:
let SizeVar: number
SizeVar = 3 // size as a variable
let data = { // The list / Dictionary
'size' : [3, 3]
}
game.onUpdate(function () {
data.size[0] = SizeVar // Assign different positions to the 'size' variable
data.size[1] = SizeVar
})
game.onUpdateInterval(1000, function () {
SizeVar += 1 // Change SizeVar by 1 every second
})
The code assigns ‘size’ to to a variable in addition to appending it to our ‘data.size’ list
What? I’m not trying to increase the size of the tilemap, I’m trying to generate a new empty tilemap with a specified width and height. What would I need to use this code for?
Hmm, no errors but the tilemap is empty even after I call tilemap.setTile(x, y, id)
. The only parameter that you left empty was tiles: Image[]
, maybe I have to give it the image of every tile in the assets? Wouldn’t that use too much memory? I can access tiles: Image[]
with tilemap.getTileset()
and the output is Image[]
. But when I log the variable (Either converted to JSON or not), it just logs [object Object], [object Object], [object Object], ...
or {{}, {}, {}, ...}
. Maybe I have to pass through every image in getTileset()
into the converted JSON from a tilemap, like this (Look in the tileset key):
{
"size": {"width": 3, "height": 3},
"tiles": [
// Array of ID and walls
],
"tileset": [
[
id: 0,
image: img`22221919999995888888888888333329855555`
// Just an example, hex doesn't work like that in JSON
]
]
}
To get a clue of build a tilemap with code, see the “tilemap.g.ts” file in your projet, after created a tilemap.
To place tiles you must add the images to the empty array, and the id of setTile(x, y, id) would be the index of the image in the array.
const tilemap = tiles.createTilemap(buffer, tilemapImg, [/* Fill this with your images */], TileScale.Sixteen);
Also you must call tiles.setTilemap to set the tilemap on the scene, otherwise you won’t see the changes you make to the tilemap when you call setTile.
tiles.setTilemap(tilemap);
One minor point, you should use tiles.setCurrentTilemap(tilemap)
instead of tiles.setTilemap(tilemap)
as setTilemap is deprecated / doesn’t play nice with variables and decompiling to blocks (https://github.com/microsoft/pxt-common-packages/blob/stable10.3/libs/game/tilemap.ts#L600)
2 Likes