tilemap alignment

Hello everyone,

Simple question here. I am thinking about purchasing MTE as I’ve heard it’s much, much better than Ceramic and Lime.

The main issue I have with Ceramic/Lime is that the map doesn’t appear aligned when loaded.

I create a simple map with four tiles forming a square at the bottom left of the map. I use the ultimate config.lua which uses letterBox.

My background covers the whole screen and the map is aligned with the lower left corner as expected on most devices but on some devices there is a small amount of space to the left and/or bottom of the map so it isn’t quite aligned perfectly.

Is this something MTE handles?

Using these variables I found elsewhere on the site, I was able to manually draw a rect on the screen aligned with the bottom left of the screen on every device.

local topY = display.screenOriginY

local rightX = display.contentWidth - display.screenOriginX

local bottomY = display.contentHeight - display.screenOriginY

local leftX = display.screenOriginX

(then create a rect with those variables)

Basically, I want to lock the content area to the bottom left of the physical screen and force it to continue all the way to the right side of the screen. If the top of the map is cropped, that’s fine because the background will take care of it. Isn’t there a way to do this?

It sounds to me like you want a relatively narrow map to completely and precisely fill the width of the screen, and to be alligned with the bottom of the screen. This is easy enough to implement. 

First you would create your map. In this example the map is 100 x 20 tiles in size. It can be almost any size, but in this case you do want it at least as tall as it is wide (otherwise it will be centered vertically on the screen).

5vdd.png

Next you’ll need some basic code to load the map and display it onscreen. MTE’s constrainCameraToScreen() function will prevent the camera from displaying black regions outside of the map, provided the map is rendered large enough to fill the screen. Take note of “blockScale = display.viewableContentWidth / 20” in the goto command. This calculates the correct scale of your tiles to always fill the width of the screen, regardless of screen size or shape. The destination of locX = 1, locY = 100 is the lower left corner of the map.

-- main.lua local mte = require("mte") mte.loadMap("map.tmx") mte.goto({locX = 1, locY = 100, blockScale = display.viewableContentWidth / 20}) mte.constrainCameraToScreen({})

Given the above map and code, MTE displays the map at exactly the width of the screen and against the bottom of the screen on every device in the SImulator’s View As menu. Here are two examples of the output;

8rs1.png

zx4v.png

Dyson,

Your suggestion works beautifully.

I’m at the next logical stage where I want to add a sprite on the screen. It seems I am having a problem I am sure is a noob mistake, but I’d appreciate if you’d enlighten me.

I base my sprite code off your castle demo. If I remove the constrainCameraToScreen call, the tilemap is no longer scaled as I desired but I can see my sprite.

If I leave the call in, I can see the tile map but not my sprite.

Any ideas?

display.setStatusBar( display.HiddenStatusBar ) local mte = require "MTE.mte" local bg = display.newRect(0, 0, 1050, 700) bg:setFillColor(135,206,250) mte.loadTileSet("tileset-platformer1", "tileset-platformer1.png") mte.loadTileSet("tileset-platformer2", "tileset-platformer2.png") mte.loadTileSet("tileset-platformer3", "tileset-platformer3.png") mte.loadTileSet("tileset-platformer4", "tileset-platformer4.png") mte.loadTileSet("items1", "items1.png") mte.loadTileSet("items2", "items2.png") mte.loadTileSet("clouds1", "clouds1.png") mte.loadMap("test.json") mte.goto({locX = 1, locY = 15, blockScale = display.viewableContentWidth / 15}) local spriteSheet = graphics.newImageSheet("p1walk.png", {width = 72, height = 97, numFrames = 11}) local sequenceData = { {name = "stand", sheet = spriteSheet, frames = {1}, time = 400, loopCount = 0}, {name = "walk", sheet = spriteSheet, frames = {2,3,4,5,6,7,8,9,10}, time = 400, loopCount = 0} } local player = display.newSprite(spriteSheet, sequenceData) local setup = { kind = "sprite", layer = mte.getSpriteLayer(1), locX = -3, locY = 14, offsetY = 25, levelWidth = 72, levelHeight = 97 } mte.addSprite(player, setup) mte.setCameraFocus(player) local function gameLoop(event) --player:setSequence( movement ) --player:play() --mte.moveSpriteTo( { sprite = player, locX = xTile, locY = yTile, time = moveTime, easing = "linear" } ) collectgarbage("step", 20) mte.debug() mte.update() mte.constrainCameraToScreen({}) end Runtime:addEventListener("enterFrame", gameLoop)

If your sprite is sharing the same map layer as your tiles it will eventually end up behind them. I did a quick test on my end and found that a sprite on the same layer as the tiles in the above examples “disappears” when mte.constrainCameraToScreen({}) executes because it is merely hidden behind a tile. 

Ideally you want your sprites on a seperate map layer all there own. You do not have to call mte.constrainCameraToScreen({}) every frame either; the constraints will stay in effect after the first call until you explicitly remove them. A good place to call it is after setCameraFocus().

hi dyson122

how easy is it within your system to address individual tiles - and to change them for other tiles in the sprite sheet, or from other sheets or separate png images/

i am working on educational translation apps (the logic is already in the bag) and want to display words and translated words, but Corona does not seem to cater too well for apps that are essentially text based.

MTE is probably overkill, but if the alternatives are lime and Ceramic, and I want to build a sustainable project, I have to ask.

Many thanks.

Darkry999,

It may have been better to create your own thread in this forum to avoid confusing future readers of this thread.

MTE does have an updateTile function that serves that purpose. I will include the documentation below.

However, MTE is best (and perhaps only) used with tile maps created with Tiled. If you are making it into a graphical game and want to change one graphic tile for another in the tile map, MTE can do that easily.

However, I will caution that text should not be tile based. You can either use ‘display.newText’ or a bitmap font. Neither of which require MTE, Ceramic, or anything else.

updateTile(input) Changes the tile index at a location on the map and updates the tile display object grid to reflect the change. parameters: (table) Data describing the location to make the change, and the new tile index. Format for parameters locX: The X location of the tile. locY: The Y location of the tile. tile: The new tile index. Use 0 to remove the tile from the map and display. posX: The X position of the tile if known. posY: The Y position of the tile if known. gridX: The tile display object X index on MTE grid, if known. gridY: The tile display object Y index on MTE grid, if known. layer: (number) A layer in the tile map. Example: mte.updateTile({locX = 21, locY = 19, tile = 7, layer = 1})

thanks jdsmith1012

really appreciate the help.   think i might get the mte.

It sounds to me like you want a relatively narrow map to completely and precisely fill the width of the screen, and to be alligned with the bottom of the screen. This is easy enough to implement. 

First you would create your map. In this example the map is 100 x 20 tiles in size. It can be almost any size, but in this case you do want it at least as tall as it is wide (otherwise it will be centered vertically on the screen).

5vdd.png

Next you’ll need some basic code to load the map and display it onscreen. MTE’s constrainCameraToScreen() function will prevent the camera from displaying black regions outside of the map, provided the map is rendered large enough to fill the screen. Take note of “blockScale = display.viewableContentWidth / 20” in the goto command. This calculates the correct scale of your tiles to always fill the width of the screen, regardless of screen size or shape. The destination of locX = 1, locY = 100 is the lower left corner of the map.

-- main.lua local mte = require("mte") mte.loadMap("map.tmx") mte.goto({locX = 1, locY = 100, blockScale = display.viewableContentWidth / 20}) mte.constrainCameraToScreen({})

Given the above map and code, MTE displays the map at exactly the width of the screen and against the bottom of the screen on every device in the SImulator’s View As menu. Here are two examples of the output;

8rs1.png

zx4v.png

Dyson,

Your suggestion works beautifully.

I’m at the next logical stage where I want to add a sprite on the screen. It seems I am having a problem I am sure is a noob mistake, but I’d appreciate if you’d enlighten me.

I base my sprite code off your castle demo. If I remove the constrainCameraToScreen call, the tilemap is no longer scaled as I desired but I can see my sprite.

If I leave the call in, I can see the tile map but not my sprite.

Any ideas?

display.setStatusBar( display.HiddenStatusBar ) local mte = require "MTE.mte" local bg = display.newRect(0, 0, 1050, 700) bg:setFillColor(135,206,250) mte.loadTileSet("tileset-platformer1", "tileset-platformer1.png") mte.loadTileSet("tileset-platformer2", "tileset-platformer2.png") mte.loadTileSet("tileset-platformer3", "tileset-platformer3.png") mte.loadTileSet("tileset-platformer4", "tileset-platformer4.png") mte.loadTileSet("items1", "items1.png") mte.loadTileSet("items2", "items2.png") mte.loadTileSet("clouds1", "clouds1.png") mte.loadMap("test.json") mte.goto({locX = 1, locY = 15, blockScale = display.viewableContentWidth / 15}) local spriteSheet = graphics.newImageSheet("p1walk.png", {width = 72, height = 97, numFrames = 11}) local sequenceData = { {name = "stand", sheet = spriteSheet, frames = {1}, time = 400, loopCount = 0}, {name = "walk", sheet = spriteSheet, frames = {2,3,4,5,6,7,8,9,10}, time = 400, loopCount = 0} } local player = display.newSprite(spriteSheet, sequenceData) local setup = { kind = "sprite", layer = mte.getSpriteLayer(1), locX = -3, locY = 14, offsetY = 25, levelWidth = 72, levelHeight = 97 } mte.addSprite(player, setup) mte.setCameraFocus(player) local function gameLoop(event) --player:setSequence( movement ) --player:play() --mte.moveSpriteTo( { sprite = player, locX = xTile, locY = yTile, time = moveTime, easing = "linear" } ) collectgarbage("step", 20) mte.debug() mte.update() mte.constrainCameraToScreen({}) end Runtime:addEventListener("enterFrame", gameLoop)

If your sprite is sharing the same map layer as your tiles it will eventually end up behind them. I did a quick test on my end and found that a sprite on the same layer as the tiles in the above examples “disappears” when mte.constrainCameraToScreen({}) executes because it is merely hidden behind a tile. 

Ideally you want your sprites on a seperate map layer all there own. You do not have to call mte.constrainCameraToScreen({}) every frame either; the constraints will stay in effect after the first call until you explicitly remove them. A good place to call it is after setCameraFocus().

hi dyson122

how easy is it within your system to address individual tiles - and to change them for other tiles in the sprite sheet, or from other sheets or separate png images/

i am working on educational translation apps (the logic is already in the bag) and want to display words and translated words, but Corona does not seem to cater too well for apps that are essentially text based.

MTE is probably overkill, but if the alternatives are lime and Ceramic, and I want to build a sustainable project, I have to ask.

Many thanks.

Darkry999,

It may have been better to create your own thread in this forum to avoid confusing future readers of this thread.

MTE does have an updateTile function that serves that purpose. I will include the documentation below.

However, MTE is best (and perhaps only) used with tile maps created with Tiled. If you are making it into a graphical game and want to change one graphic tile for another in the tile map, MTE can do that easily.

However, I will caution that text should not be tile based. You can either use ‘display.newText’ or a bitmap font. Neither of which require MTE, Ceramic, or anything else.

updateTile(input) Changes the tile index at a location on the map and updates the tile display object grid to reflect the change. parameters: (table) Data describing the location to make the change, and the new tile index. Format for parameters locX: The X location of the tile. locY: The Y location of the tile. tile: The new tile index. Use 0 to remove the tile from the map and display. posX: The X position of the tile if known. posY: The Y position of the tile if known. gridX: The tile display object X index on MTE grid, if known. gridY: The tile display object Y index on MTE grid, if known. layer: (number) A layer in the tile map. Example: mte.updateTile({locX = 21, locY = 19, tile = 7, layer = 1})

thanks jdsmith1012

really appreciate the help.   think i might get the mte.