Scrolling map and objects whose with width/height < tile width

Hi all.

I’m new to using a tiled map and having read through the forums I wanted to ask what would be best practice for adding objects who I’d like to detect collisions with or act as physics objects.

For example:

  • my tile map is a large scrolling map of terrain e,g grassland, roads, sand etc
  • I have a vehicle that I want to be able to drive across the map
  • I have walls, buildings etc that have a width that may have a width or height partial tile width.

If I want to detect collisions with these (e.g a bullet should stop and disappear when it hits wall) or have my vehicle ‘bounce back’ from them, am I best placing these as ‘normal’ objects through the standard corona API and just use to calculate tileToPixel positions?

Also would it be best to store these object and their positions in an object layer in the tiled program or just store these via a standard lua table with tile coordinates or positions?

Many thanks for any advice. I’m struggling to find an up to date tutorial that will walk though these kind o questions.

Ant

I’ll make an official tutorial on this sometime, but in the meantime, read through https://forums.coronalabs.com/topic/42355-dusk-engine/page-16 and possibly a little further. The best way to deal with custom objects is through that style of function. This may eventually become core; it seems to be commonly needed.

Also, for simple objects, don’t forget that Dusk can build object layers with physics. You’d need to deal with the graphical side of them, but the basic collisions should be completely doable from within Tiled.

  • Caleb

Many thanks - that thread was helpful. However one thing I’m not sure about is how I ensure that an object I remove from the display after a collision does not get added back by the tile culling functionality once I scroll so the position of the destroyed object is off screen and then I scroll back so that the position is now on screen.

At the moment when I scroll back, the previously destroyed object now reappears.

Thanks for your help.

  • Ant

I think that’s also handled somewhere later in the thread. Basically, for on-demand state storage, you’ll add the object to a state table when it’s created:

local states = {} objectType.build = function(event) local id = event.object.x .. ":" .. event.object.y -- Give the object a unique ID states[id] = states[id] or {} if states[id].isDestroyed then return nil -- Don't forget to check for this in your addObjectType function end local obj = (build object) obj.id = id return obj end

Then, when your object gets destroyed, set the flag in the appropriate ‘states’ table, and you should be good to go.

  • Caleb

Thanks for the reply. I did read on and try something like that

local objectType = {} objectType.objectType = "enemy" objectType.destroyed = {} -- A function which creates your custom object objectType.build = function(event) if objectType.destroyed[event.object.\_name] then -- display.remove(event.object) return nil else physics.addBody( event.object, "static", {radius=25}) end return event.object end -- A function which deletes your custom object objectType.remove = function(object) objectType.destroyed[object.\_name] = true end return objectType

As you can see I’m not having to do anything to add objects that are in the object layer to the display that just seems to happen. I am having to call this to add physics (although I could do this via a property). However the return nil doesn’t seem to work since the culling functionality seems to add it back before this function gets called. I have a temporary fix with the commented line which works but I would rather that I can disable the auto adding and then not have to call display.remove(event.object).

Where is the default build object code from the tiled object layer being called?

Thanks again.

  • Ant

You shouldn’t actually delete the host object. It’s a Dusk core object. You might get errors if you do that. Instead, you should just hide all the host objects and rely on your object type to build the child objects or not build them, as needed.

Just put this at the top of your main.lua or somewhere global:

dusk.setPreference("virtualObjectsVisible", false)
  • Caleb

I find that for Sprite objects this has no affect. Dusk’s built in display/culling functions still get called :frowning:

Any tips? Thanks

Dusk doesn’t currently support hiding of graphic objects on creation. You can build your own object type for them, however: it’s super easy and adds a lot of flexibility. For example, my image object type includes options for aspect ratio to fit the image into the object’s shape, scale, tiling, etc., so I have complete control over the object. Once you’ve written an object type, use rectangles for your images to build them when you want.

  • Caleb

Ok this makes sense but is it possible to have these image objects specified within the Tiled output without Dusk using its inbuilt adding/culling functionality to interpret the Tiled json and add the graphic objects itself.

At the moment if I encode these objects within Tiled they get displayed and the preference

dusk.setPreference("virtualObjectsVisible", false)

has no effect.

Sorry I’m a bit slow to get this.

  • Ant

The “virtualObjectsVisible” preference only applies to so-called “virtual objects” - rectangles, polygons, and ellipses. Most people won’t be actually displaying these in their game. Image objects are different: users’ll probably want to display them instead of hide them and use them for data.

There is a “trump all” property which builds objects as data tables instead of display objects: !isData!. Set an object’s !isData! property to ‘true’ in Tiled and it won’t get built but callbacks will still be called on it. Keep in mind that this property means that the object won’t get built at all, so you’ll have to build it yourself every time.

  • Caleb

I’ll make an official tutorial on this sometime, but in the meantime, read through https://forums.coronalabs.com/topic/42355-dusk-engine/page-16 and possibly a little further. The best way to deal with custom objects is through that style of function. This may eventually become core; it seems to be commonly needed.

Also, for simple objects, don’t forget that Dusk can build object layers with physics. You’d need to deal with the graphical side of them, but the basic collisions should be completely doable from within Tiled.

  • Caleb

Many thanks - that thread was helpful. However one thing I’m not sure about is how I ensure that an object I remove from the display after a collision does not get added back by the tile culling functionality once I scroll so the position of the destroyed object is off screen and then I scroll back so that the position is now on screen.

At the moment when I scroll back, the previously destroyed object now reappears.

Thanks for your help.

  • Ant

I think that’s also handled somewhere later in the thread. Basically, for on-demand state storage, you’ll add the object to a state table when it’s created:

local states = {} objectType.build = function(event) local id = event.object.x .. ":" .. event.object.y -- Give the object a unique ID states[id] = states[id] or {} if states[id].isDestroyed then return nil -- Don't forget to check for this in your addObjectType function end local obj = (build object) obj.id = id return obj end

Then, when your object gets destroyed, set the flag in the appropriate ‘states’ table, and you should be good to go.

  • Caleb

Thanks for the reply. I did read on and try something like that

local objectType = {} objectType.objectType = "enemy" objectType.destroyed = {} -- A function which creates your custom object objectType.build = function(event) if objectType.destroyed[event.object.\_name] then -- display.remove(event.object) return nil else physics.addBody( event.object, "static", {radius=25}) end return event.object end -- A function which deletes your custom object objectType.remove = function(object) objectType.destroyed[object.\_name] = true end return objectType

As you can see I’m not having to do anything to add objects that are in the object layer to the display that just seems to happen. I am having to call this to add physics (although I could do this via a property). However the return nil doesn’t seem to work since the culling functionality seems to add it back before this function gets called. I have a temporary fix with the commented line which works but I would rather that I can disable the auto adding and then not have to call display.remove(event.object).

Where is the default build object code from the tiled object layer being called?

Thanks again.

  • Ant

You shouldn’t actually delete the host object. It’s a Dusk core object. You might get errors if you do that. Instead, you should just hide all the host objects and rely on your object type to build the child objects or not build them, as needed.

Just put this at the top of your main.lua or somewhere global:

dusk.setPreference("virtualObjectsVisible", false)
  • Caleb

I find that for Sprite objects this has no affect. Dusk’s built in display/culling functions still get called :frowning:

Any tips? Thanks

Dusk doesn’t currently support hiding of graphic objects on creation. You can build your own object type for them, however: it’s super easy and adds a lot of flexibility. For example, my image object type includes options for aspect ratio to fit the image into the object’s shape, scale, tiling, etc., so I have complete control over the object. Once you’ve written an object type, use rectangles for your images to build them when you want.

  • Caleb

Ok this makes sense but is it possible to have these image objects specified within the Tiled output without Dusk using its inbuilt adding/culling functionality to interpret the Tiled json and add the graphic objects itself.

At the moment if I encode these objects within Tiled they get displayed and the preference

dusk.setPreference("virtualObjectsVisible", false)

has no effect.

Sorry I’m a bit slow to get this.

  • Ant

The “virtualObjectsVisible” preference only applies to so-called “virtual objects” - rectangles, polygons, and ellipses. Most people won’t be actually displaying these in their game. Image objects are different: users’ll probably want to display them instead of hide them and use them for data.

There is a “trump all” property which builds objects as data tables instead of display objects: !isData!. Set an object’s !isData! property to ‘true’ in Tiled and it won’t get built but callbacks will still be called on it. Keep in mind that this property means that the object won’t get built at all, so you’ll have to build it yourself every time.

  • Caleb