Dusk Engine

For your first question, what do you mean? Are you adding physics to the “child” object and the host object is getting it as well?

objectType.build = function(event) local obj = display.newRect(0, 0, 100, 100) physics.addBody(obj, ...) -- The host object is getting this?!? return obj end

!isData! is a property you can add to objects in Tiled that makes them retain all their properties but not be an actual display object. Culling is not available for !isData! objects, but I’ll likely add it soon. You can’t add isData programmatically, because it has to be attached to an object when the map is created.

Second question: Yup, that’s correct.

Third question: I use objects in Tiled sort of like boundaries for my child/built objects. Culling will activate as soon as the entire host object goes off-screen, so you can make the object bigger to keep it from being destroyed too soon. For example, I use Tiled objects for my moving platforms by making them the entire width or height of the platform’s moving path; then, the platform is deleted after it and its moving path is completely off-screen.

  • Caleb

I’ve moved this to Caleb’s own forum “Gymbyl Coding”. Might I suggest starting new threads for specific questions regarding the Dusk engine instead of continuing this very long and multi topic forum thread.

Thanks

Rob

1st

My bad - I forgot object layer’s physics settings - sorry :wink:

3nd

Ok. This sounds pretty nice actually. This way I can visually draw set the distance of moving platforms or enemies - great!

Nice job on Dusk Caleb!

I started playing with Dusk this evening by converting one of my previous games from Lime to Dusk. In less than 30 minutes I had the map loading.  Still have some more to do, but it looks like you have built a solid tool.

I am starting the process of updating one of my textbooks and will be switching the tool use for the chapter on tile-based games to Dusk.

Can anyone give me info how to load a tile map,

I trying but, show nothing in simulator, also in terminal dosnt show any issue,

maybe i missed something, please help !!! :( 

@carlos.rafael:

All Dusk does to load properties is process the value, which converts it to a number, Boolean, table, etc., and add it to the object with the exact same key as was specified in Tiled. So if you add a property called “name” to a tile in Tiled, each tile will have that property. If you’re not picking up the property in your collision listener, all I can say is that your collision listener is acting up. Here’s a working collision function (global because it seems that’s what you’re using):

local function onCollision(event) local tile, object = event.object1, event.object2 if not tile.tileX and not tile.tileY then tile, object = object, tile -- We mixed the tile and the object up; switch them end -- Use tostring() in case the name of either object is nil print("The tile's name is " .. tostring(tile.name) .. ", and the object's name is " .. tostring(object.name)) end Runtime:addEventListener("collision", onCollision)

@touchdowngames:

Yay, a use case for plugins! I’ve been on the fence with them for a while. I just pushed a commit to the dev branch which actually calls plugin callbacks (previously, you could add plugins all you wanted, but they did absolutely nothing :D). What you’ll do now is this:

local tilesetChanger = {} -- Create the plugin table tilesetChanger.onLoadMap = function(data, stats) -- In here, 'data' will look approximately the same as Tiled exported map data. The only difference is that Dusk adds some extra properties in. -- Look at your map file to see the structure. data.tilesets[1].image = "../blahblahblah.png" -- Notice that the path is relative to the map file, not the root. end -- Later somewhere, BEFORE you load your map dusk.registerPlugin(tilesetChanger)

Notice that this will only work with the dev branch (I really need to get a stable release out!).

@geiganax:

I know you said it’s not, but this seriously sounds like a prime case of object-not-in-map-layer. Are you sure you’re not inserting the object into something else after you insert it into the layer? Corona only allows objects to be in a single display group, so any insertions remove it from the previous group and insert it into the new one. I ask because I know someone who had this same problem - all the symptoms of notinmapitis, but they were inserting the object into the map correctly. It turned out that later they inserted it into another display group, so it was getting removed from the map after all.

@Dr Brian Burton:

Wow, great! Let me know if you need any help at any time.

  • Caleb

Heelo @Caleb. It just worked really well. 

I just would like to understand how the var dusk know that tile.name will get exactly the name of the Tile on my map, I don’t know if it is a clear question. How tile.name is not set to null but for the tile’s property on my map.

Also, can I keep improving this function to deal with other types of tiles?

Thank you in advance 

@carlos.rafael:

Dusk reads the map data from the file exported from Tiled, and builds the map accordingly. Tiled includes the tile properties you set in the data. Thus, when Dusk reads the data, it knows that tile #xxx in the tileset gets the property “name” set to “blahblahblah” or whatever. Each tile in a layer is a separate display object, so when Dusk builds the tile, it adds that property.

For an alternative way of looking at it, imagine that you’re creating ten rectangles in your app, each of which has a different ‘name’ property. When a rectangle collides, you want to print out its name. That’s all Dusk is really doing - creating a bunch of little objects, each of which has different properties according to what you set in Tiled.

You should be able to just check for other names to deal with other types:

if tile.name == "flamingSpikesOfDeath" then -- Player dies elseif tile.name == "friendlyCloudWithTeeth" then -- Player looks quizzically at it elseif tile.name == "portraitOfNapoleon" then -- Player reflects on French history end
  • Caleb

I am trying to use your addObjectType(params) function, but it just don’t replace the objects in Tiled with the same objectType.

this is how my build function looks like:

[lua]

        objectType.build = function(event)

          local object = display.newSprite( sheetPic, sheetSequenceData)

          object.myName = “Enemy”

          physics.addBody( object, “static”, {radius = 25} )

          object:setSequence( “spinRight” )

          object:play()

          object.x, object.y = event.object.x, event.object.y

          event.object.parent:insert(object)

          return object

        end

[/lua]

EDIT:

Got it working, I thought you needed to give custom property for object in Tiled like objectType = Enemy, but I just noticed the Type field under the Object properties.

But now I noticed the object in Tiled is still visible when I for example shoot the enemy. I am guessing the !isData! is the right way to do in Tiled object, but how do I set object !isData! ? Is the removeSelf() function right way to remove the shooted enemies?

@Painconfess:

To hide the object, just set the Dusk preference ‘virtualObjectsVisible’ to false before loading your map.

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

@Caleb P,
can you check the Bang notation to add collision filters. This is the property I added in the Tiled app but it doesn’t seem to work.

physics:filter = !!! categoryBits: 4 maskBits: 1

This is a screenshot of the property I added in Tiled so you can see if I did it right:
https://www.dropbox.com/s/0fv0za2jhdaflm4/Screenshot%202015-10-05%2016.53.27.png?dl=0

I know I got the CategoryBits and the Bitmask right because I tried the collision filter between the player, bullets, and a static crate image and it works.

About (smoothly) scrolling background :wink:

I’ve set the camera focus to the player and tracking level is about 0.1. I try to add a scrolling background image that should move with the player, but not as fast. The player moves like 3 pixels and the background 1 pixels in a frame. But because the camera movement is smooth, it looks pretty weird when the player goes right and stops, the scrolling background also stops, but the camera still moves a bit (because of the necessary smoothess). Pretty hard to explain :wink:

The point is - How could I also move the background image smoothly (and not like background.x=background.x-1)? For example, could I access the movement of the camera of the Dusk?

This is not a pure Dusk question, but I think that all of us who are working with tiles, need this :slight_smile:

Should be fixed. Try the new master branch or just add “filter = true” to the physicsKeys tables on lines 44 and 41 of objectlayer.lua and tilelayer.lua, respectively.

  • Caleb

Edited, realized mistaken assumption:

That was it, I was trying to insert the sprite into the composer scene group even though I’d already inserted it into the map. Thanks!

Thanks Caleb! It works perfect now :slight_smile:

Hi Caleb!

Question 1:

I got the same problem as Painconfess. If I’ve created enemy with the build code above. How do I remove the object, if it is destroyed? And when the host object is created again after beeing culled, how do I prevent that the object is not created again?

Question 2:

How can I call the function: objectType.remove = function(object)

Question 3:

If I create a new object like mySpecialObjectType2. How do I do that? You said:“The easiest way to make object types is with separate modules. It even gives you a sort of object-oriented feel. This code only needs to be called once. It’s like a “hey, Dusk, do this and this when you draw and erase an object” function.

Do you mean something like this: https://coronalabs.com/blog/2012/08/28/how-external-modules-work-in-corona/

You said "_This code only needs to be called once" _ - do you mean once per object type? 'Cause the way I understood the code, is that the code is diffenent if the object is different. For example “local object = display.newRect(0, 0, event.object.width, event.object.height)”   could be “local object = display.newImageRect(“image.png”, 40, 40)” and other properies are also different (for example hit point).

Is it possible to have a example code where you have two object types in modules and maybe with this remove thing (question 1) :slight_smile:

Aatos Media,

I haven’t tried this but have you tried to set the host’s Type to different value after the child is built to prevent it’s rebuild? This might again be a bad way to do this if this works but I had to share my idea :smiley: If you want to host appear after culling if it’s not destroyed by player then I don’t know what to do. Some how you need to iterate through child to host to set the Type…

And I think the removeSelf() or display.remove(object) is right way to do because in objectType.remove function uses the same method.

I have at the moment 2 different enemies in my map and both have own objectTypes in my gamedata.lua and have the addObjectType function in game.lua.

gamedata.lua:

[lua]

local F = {}

function F.EnemyList()

        local objectType = {}

        objectType.objectType = “Enemy”

        – A function which creates your custom object

        objectType.build = function(event)

          local object = display.newSprite( sheetPic, sheetSequenceData)

          physics.addBody( object, “static”, {radius = 25} )

          object.x, object.y = event.object.x, event.object.y

          event.object.parent:insert(object)        

          return object

        end

        – A function which deletes your custom object

        objectType.remove = function(object)

          display.remove(object)

        end

 return objectType

end

function F.BossList()

        local objectType = {}

        objectType.objectType = “Boss”

        – A function which creates your custom object

        objectType.build = function(event)

          local object = display.newSprite( sheetPic, sheetSequenceData)

          physics.addBody( object, “static”, {radius = 83})

          object:setSequence( “spin” )

          object:play()

          object.x, object.y = event.object.x, event.object.y

          event.object.parent:insert(object)

              end

          end

          return object

        end

        – A function which deletes your custom object

        objectType.remove = function(object)

          display.remove(object)

        end

 return objectType

end

return F

[/lua]

game.lua:

[lua]

local gamedata = require( “gamedata” )

local BL = gamedata.BossList()

local EL = gamedata.EnemyList()

  addObjectType(EL)

  addObjectType(BL)

[/lua]

I stripped some unnecessary lines like variables for sprites etc.

I hope this helps!

@Aatos Media:

You can insert the scrolling background into an empty layer of the map, then set the layer’s xParallax/yParallax as needed. That way, it’ll move exactly in the same way as the rest of the map.

Q1: Just make sure your remove() function doesn’t fail if the object is already removed, then call it to remove the object when you want to. Then, when the host object is culled, the remove function will be called but nothing will happen. The addObjectType code adds a listener for the type, so you could technically set the type of the object to something else (I think?), but a much easier and safer way is to just set a flag for something specific about the host object, like position or name. Here’s an example for position, built on the idea that no two host objects in a layer will have the same position and object type.

local dontComeBackOrIllShoot = {} -- Table to hold references to destroyed objects -- Yackety yack -- Inside an object's destroy function (when your bullet hits it or whatever) local specialKey = object.x .. "|" .. object.y -- Make a magical key to identify the host object; it's important to note that 'object' here refers to the host object, not the child object dontComeBackOrIllShoot[specialKey] = true -- Set the flag in the destroyed objects table -- Yackety yack -- Inside the objects build function local specialKey = event.object.x .. "|" .. event.object.y if dontComeBackOrIllShoot[specialKey] then return -- Never mind, this one's already been destroyed end

Q2: I don’t really understand this question :(. Can you explain some more please?

Q3: The way Painconfess did it works. You can put the object types into separate modules, then require() them and add the object types to the map. Alternatively, you can do it how I do it and make a separate module for each object type:

-- types/movingPlatform.lua local objectType = {} objectType.build = ... objectType.remove = ... return objectType

-- types/floorSwitch local objectType = {} objectType.build = ... objectType.remove = ... return objectType

Then, in your game file:

addObjectType(require("types.movingPlatform")) addObjectType(require("types.floorSwitch"))

And yes, I did use “called once” to mean “called once per object type”.

  • Caleb

It seems like when you use map.destroy() it doesn’t call the objectType.remove to the added & displayed objects. I have moving enemies and shooting enemies now and 1st I had errors when culling removed the objects, but got that fixed by adding the lines transition.cancel(object) and timer.cancel(object.shooting) in objectType.remove function.

But now if enemy is displayed and scene is changed (to gameover for example) I get the same error (nil value from object.x or something). So I managed with the moving enemies to set in scene:destroy the line: transition.cancel(), but the timer.cancel(object.shooting) is a bit trickier. I tried using for loop where iterate all whose typeIs(“shootingEnemy”) and timer.cancel() each, but noticed it only iterates host objects.

So in short I am asking how do I iterate child objects? :smiley: Or how could I make the displaying enemies do their own remove function before I change the scene…?

Question 2 in long version. If I have added object culling like in Painconfess’s example (one gamedata.lua file) and I have collision handler function in main.lua. Now - how can I code that I want to call remove function from the module gamedata.lua and from the Enemylist function? Sorry - this is complicated, but I think the structure is a bit complicated too :wink: Or If you prefer your example (one module per type), how could I call remove function from the main.lua when the remove function is in types/movingPlatform.lua

I thought it would be something like (painconffess case):

module (gamedata) --> function (EnemyList) – > function (objectType.remove) --> pass removable object (event.object2)

If this is possible, I think I’m heading to a new problem. If the collision happens, how I know if the object is Enemy of Boss (I think this could be managed, but the logic is becoming too complicated). Or should I put the collision detection into to build-function of the objectType.build = function(event)?

Sorry about the confusing message - but I’m pretty confused :slight_smile: