getMap() changed?

Hey Dyson - quick question.

It’s my own fault for not sticking up to date with the latest updates, and then struggling when I decided to update (damn those sexy new features :0) )

You may or may not remember that I was needing to store properties on each individual tile/cell in my map; you suggested creating my own two dimensional array containing the data and then attaching this to the map table from getMap() - http://forums.coronalabs.com/topic/41163-add-ability-to-mark-tiles-or-layers-as-property-only/

I then json’ed this, saved it to file and loaded it as needed.

This worked flawlessly until I updated to v980, which is now complaining when I try to json.encode the table about function variables contained within the object.

Upon closer inspection it seems as though the table returned from getMap() now contains a 2D array named tileObjects, which seems to contain entries that have a field containing a function named makeSprite() and also seem to hold references to the display objects ?!?

Obviously I could strip these away, but that’s going to get messy. So I was just wandering whether you could suggest a better approach. 

My workings were before you implemented saveMap into MTE - so I was manually saving the data and loading. Presumably MTE’s inbuilt functions will save me this hassle but I need to consider the workflow.

Just to recap my map contains 5 layers - (from bottom to the top), the first three layers represent Water, Dirt and Grass. On top of this is the Sprites and Objects layer, followed by a layer that contains white tiles that I adjust the colour accordingly to represent a “heatmap” of the aforementioned tile/cell properties. The layers are really there for a visual effect, i.e you dig through one layer to reveal the one below. 

I truly believe I’m making things more complicated then they need to be - and the fact that my setup isn’t working on the updated MTE has encouraged me to refactor my solution. 

Presumably my old technique of attaching my cell properties to the table returned by getMap() is not going to work unless I parse the table and strip away the entries that hold functions, display objects, etc… - NOT A GOOD SOLUTION.

So my question, in a really long-winded way is can you suggest a better approach to having properties stored on each individual cell, and the way to go about saving this so the game state is re-loaded when the player picks up the game again?

Many thanks…

Versions of MTE leading up to and including 0v958 handled tiles differently than the current post-rewrite versions. They used yet another abstract coordinate system not exposed to users, necessitating the locToGrid, levelPosToGrid, and other similar convert functions. You’ll notice convert doesn’t include any reference to grid at all now, because the grid tables are gone. The idea behind the new system was to make accessing sprites easier; they’re stored at their map locations, no conversion between multiple abstract coordinate systems needed.

That said, I suppose they don’t have to be in the map array itself… I’ll look into it on my end. If time allows I’ll work in a solution for Friday. I don’t think moving tileObjects out of map will cause any problems.

Hey Dyson - thanks for the info. I have successfully overcome the issue by using the inbuilt saveMap() function, which seems to strip away the display objects ?!?

I am having a few problems however when saving my sprites to reposition on a new load. I’ve just been debugging my code and noticed that I place an image on the map, whose x/y co-ordinates are 144/146, I even double check this because the name property assigned by MTE is 144_146_4.

Yet when I’m saving all the sprites to file I’ve noticed that it’s logging:

mainImage.x: 368
mainImage.y: 272

Obviously when I re-load the game this is putting the sprite in a crazy position?!? I have no knowledge as to why these values have changed; fyi the sprites are static, like buildings in an rts, there is nothing changing their position after they’re added to the map.

Even during the process of adding it to the map I’m printing out values and they all appear as expected:

Seed ACTION
Plant Seed?

event.x: 160
event.y: 146

Plant TileX: 12
Plant TileY: 9

sprite.x: 144
sprite.y: 146

locPos.x: 12
locPos.y: 9

As soon as I use addSprite - the values seem to change?!?

Apologies for the hassle but can’t quite get my head around how things have changed with regards to placement, positioning, etc…

Are they outlined in docs anywhere?

Many thanks…

Edit

It seems to be something to do with content scaling - I’ve noticed that scale is a new parameter to setCamera() now; so I’m going to experiment with this and see what I come up with.

One of the more significant changes has been to how the engine scales maps. In the old system, setting blockScale = 64 would render each tile as 64 x 64. If you change the blockScale again, you end up throwing the entire coordinate system out of whack. Post-rewrite the engine scales the layer group object as a whole. If your map uses 32x32 tiles, those tiles will always be 32x32 whether they’re tiny on the screen or they fill 64x64 (or more) worth of screen space. The coordinate system internal to the group is stable. If you’ve put any work-arounds in place to accommodate the old system, those work-arounds will probably cause problems on the new system.

I’m guessing your map tiles are 32x32 pixels. Above you say you’re adding tiles at locX = 12, locY = 9. Well, 12 * 32 = 384 - 16 = 368 and 9 * 32 = 288 - 16 = 272. The name is generated in addSprite before MTE corrects for it’s intended position, which is why the name appears to conform to the original position of the sprite. 

Something I would check is your event for planting seeds. If your event is attached to Runtime it’s event.x and event.y will not conform to the position on the map. You can call screenToLevelPos(x, y, layer) to translate between the runtime event position and the actual map position.

Ahhh I think I may know the source of my problem.

I have a Game_Map class, which has a pointer to MTE - everything MTE is directed through to this class.

I have a method within Game_Map named Game_Map:addSprite() which takes the sprite passed through and ultimately passes this through to mte.addSprite - however before this I’m calling:

local locPos = mte.convert(“screenPosToLoc”, sprite.x, sprite.y, mte.getSpriteLayer(1))

To get the LocPos to pass to addSprite().

This was all working prior to upgrading, but I’m guessing that the changes to MTE have broken this - I know you’ve mentioned that convert is being deprecated. 

Would you advise changing this line to screenToLevelPos as you’ve mentioned up above?

In fact looking over my code I use .convert() quite extensively, would you advise changing all of this?

Thanks for all of your help Dyson, was truly pulling my hair out over this…

Right now convert just calls the new functions internally.

The 368, 272 position is the correct level position… the question becomes, do you then pass 368, 272 through the convert function again when you reload the map? Each time you do so the sprite will be more offset from where it should be because 368, 272 is the level position. If you pass the level position into a function meant to convert from a screen position, you’re going to run into pretty severe problems!

EDIT: Also, today’s update moves the tileObjects table out of the map table. You can switch back to your original method for saving the map if you like. The saveMap() function will also run more quickly now that it doesn’t have to strip out the tile objects during execution.

Versions of MTE leading up to and including 0v958 handled tiles differently than the current post-rewrite versions. They used yet another abstract coordinate system not exposed to users, necessitating the locToGrid, levelPosToGrid, and other similar convert functions. You’ll notice convert doesn’t include any reference to grid at all now, because the grid tables are gone. The idea behind the new system was to make accessing sprites easier; they’re stored at their map locations, no conversion between multiple abstract coordinate systems needed.

That said, I suppose they don’t have to be in the map array itself… I’ll look into it on my end. If time allows I’ll work in a solution for Friday. I don’t think moving tileObjects out of map will cause any problems.

Hey Dyson - thanks for the info. I have successfully overcome the issue by using the inbuilt saveMap() function, which seems to strip away the display objects ?!?

I am having a few problems however when saving my sprites to reposition on a new load. I’ve just been debugging my code and noticed that I place an image on the map, whose x/y co-ordinates are 144/146, I even double check this because the name property assigned by MTE is 144_146_4.

Yet when I’m saving all the sprites to file I’ve noticed that it’s logging:

mainImage.x: 368
mainImage.y: 272

Obviously when I re-load the game this is putting the sprite in a crazy position?!? I have no knowledge as to why these values have changed; fyi the sprites are static, like buildings in an rts, there is nothing changing their position after they’re added to the map.

Even during the process of adding it to the map I’m printing out values and they all appear as expected:

Seed ACTION
Plant Seed?

event.x: 160
event.y: 146

Plant TileX: 12
Plant TileY: 9

sprite.x: 144
sprite.y: 146

locPos.x: 12
locPos.y: 9

As soon as I use addSprite - the values seem to change?!?

Apologies for the hassle but can’t quite get my head around how things have changed with regards to placement, positioning, etc…

Are they outlined in docs anywhere?

Many thanks…

Edit

It seems to be something to do with content scaling - I’ve noticed that scale is a new parameter to setCamera() now; so I’m going to experiment with this and see what I come up with.

One of the more significant changes has been to how the engine scales maps. In the old system, setting blockScale = 64 would render each tile as 64 x 64. If you change the blockScale again, you end up throwing the entire coordinate system out of whack. Post-rewrite the engine scales the layer group object as a whole. If your map uses 32x32 tiles, those tiles will always be 32x32 whether they’re tiny on the screen or they fill 64x64 (or more) worth of screen space. The coordinate system internal to the group is stable. If you’ve put any work-arounds in place to accommodate the old system, those work-arounds will probably cause problems on the new system.

I’m guessing your map tiles are 32x32 pixels. Above you say you’re adding tiles at locX = 12, locY = 9. Well, 12 * 32 = 384 - 16 = 368 and 9 * 32 = 288 - 16 = 272. The name is generated in addSprite before MTE corrects for it’s intended position, which is why the name appears to conform to the original position of the sprite. 

Something I would check is your event for planting seeds. If your event is attached to Runtime it’s event.x and event.y will not conform to the position on the map. You can call screenToLevelPos(x, y, layer) to translate between the runtime event position and the actual map position.

Ahhh I think I may know the source of my problem.

I have a Game_Map class, which has a pointer to MTE - everything MTE is directed through to this class.

I have a method within Game_Map named Game_Map:addSprite() which takes the sprite passed through and ultimately passes this through to mte.addSprite - however before this I’m calling:

local locPos = mte.convert(“screenPosToLoc”, sprite.x, sprite.y, mte.getSpriteLayer(1))

To get the LocPos to pass to addSprite().

This was all working prior to upgrading, but I’m guessing that the changes to MTE have broken this - I know you’ve mentioned that convert is being deprecated. 

Would you advise changing this line to screenToLevelPos as you’ve mentioned up above?

In fact looking over my code I use .convert() quite extensively, would you advise changing all of this?

Thanks for all of your help Dyson, was truly pulling my hair out over this…

Right now convert just calls the new functions internally.

The 368, 272 position is the correct level position… the question becomes, do you then pass 368, 272 through the convert function again when you reload the map? Each time you do so the sprite will be more offset from where it should be because 368, 272 is the level position. If you pass the level position into a function meant to convert from a screen position, you’re going to run into pretty severe problems!

EDIT: Also, today’s update moves the tileObjects table out of the map table. You can switch back to your original method for saving the map if you like. The saveMap() function will also run more quickly now that it doesn’t have to strip out the tile objects during execution.