So far everything is working fine but I have another question:
How can I change a tile into another tile from an tileset image? Something like: The tile from tileset1 with ID 5 is grass and it should become rock from tileset2 with ID75 when the character is doing some action or moving over this tile.
Jack, can you please post a more detailed sample on how you did include animated tiles, starting from adding the properties and samples of the code and functions?
I was just wondering exactly how fast Dusk really is. As you most likely know, speed hasn’t ever really been a main focus of Dusk; Dusk is more of a awesome-features-and-really-easy-to-use engine, with speed as a plus.
Hint: I had to encode the map as Lua because JSON took too long to parse.
(ok, so that was more of an interesting fact than a hint. But it is true.)
Hint #2: The map file is ~75 Mb
By the way, here’s the source code for the program in the video, with the irrelevant code cut out (display.setStatusBar, etc., as well as the drag+drop code in main.lua)
[lua]
local dusk = require(“Dusk.Dusk”)
print(“Loading Lua data…”)
local mapData = dusk.loadMap(“impossibly_huge.lua”)
print(“Finished loading Lua data.”)
print(“Building map…”)
local map = dusk.buildMap(“tests/benchmarks/impossibly_huge.lua”)
print(“Done!”)
Sure! First, here’s the snippets from tilelayer.lua that are relevant:
Here’s how every tile is instantiated, as of when I got it:
local tile = display\_newSprite(imageSheets[sheetIndex], imageSheetConfig[sheetIndex]) tile:setFrame(tileGID)
What this does is make a sprite object using the tilesheet and specific GID using setFrame(). This means that we can change the frame to any other tile in the tilesheet! What I decided to do was add some custom properties that would let me know what other GIDs to use. For my purposes (specifically, opening a door by swtiching between “closed” and “open” states), I just want to specify one “alternateGID”. I tracked down the spot where properties are added in functions.lua, and added this code:
elseif key:match("^props:") then insertionTable = p.props k = key:sub(6) --insert check for animation here elseif key:match("^animation:") then insertionTable = p.props; k = key:sub(0); else
What this does is look for any property that starts with “animation:” (for my purposes, animation:alternateGID) and throws that into the tile’s .props table.
After the space marked – Add Properties and Add Tile to Layer, I added the following code:
-- Add animation -- Custom edit if(tile.props.animation) then if(tile.props.animation.alternateGID) then tile.props.animation.alternateGID = tonumber(tile.props.animation.alternateGID) + 1; --for some reason, the values of GIDs are off by 1 in Dusk tile.setAlternateGID = function(self) local currentGID = self.GID; self:setFrame( self.props.animation.alternateGID ); self.props.animation.alternateGID = currentGID; end end end
This adds a function, tile:setAlternateGID(), that lets me alternate between GIDs at will by accessing the property I added and calling :setFrame(). Other options might be to store a sequence of frames as a table and use that animation. (It could start when prompted by some trigger or just as soon as it the tile is created.)
I have a persistent problem that I’ve noticed others mention here, but haven’t been able to find a solution for: whenever I make an object in Tiled using an image, it is never created in the right spot along the y-axis. I think I’ve narrowed it down to this line inside objectlayer.lua:
This looks like it directly controls the position of objects. If the aspect ratio of the screen is different than what my build settings are specified for (entirely likely, since I’m working on a video game right now), image objects tend to be several tile-heights above where I’ve drawn them in Tiled. It only works perfectly if I run it simulating an OUYA, whose screen dimensions I’m using. I’m exporting using .json, and the x- and y- values in the file match what Tiled says they are.
Does anyone have any advice? (I’m new to Git and have made a few custom edits to Dusk, so I’ve never updated Dusk since I started using it; if it’s already been fixed, I never got an update.) I can upload screenshots if it’d help.
The early-early-early-early version of animated tiles is now complete! I just pushed a new version to GitHub. Dusk now allows animated tiles, and synchronizes them with culling, so they don’t get messed up from being removed and then created.
You can now specify anim:enabled = true in your properties. Then make your animation options with anim:options, and pass a table (Bang or JSON) for the animation options (the second table in Corona’s display.newSprite()). Check out maps/square_anim.json in the Git repository to see what I mean. Again, it’s in a very, very early stage, so I’ve only tested it with start, count, and time parameters in the animation options table. Custom frames (frames = {1, 5, 6, 6, 2} or similar) aren’t supported right now.
But it’s pretty cool! And AWESOME! Like when Luke flies through that canal thingy in the Death Star in Star Wars! Come to think of it, not quite like that…
Thank you for the animation stuff! I can’t wait to try it
One other thing: Is there an easy way to change tiles into other tiles, like for example I want to change a grass tile into some rock or dirt. Is this possible?
It would also be great to use this for some kind of “Fog of War”, when a character is moving around. Tacking it’s position and changing the “Fog Of War” layer tiles.
Currently, no. Tiles are created with display.newImageRect, so they can’t change their frame. I’ve been thinking of a special property (!isSprite! or similar) to allow the user to specify which tiles should be created as sprites; you could then say !isSprite! on your grass tile and then Dusk would build them as sprites and you could cycle through them and set the frame. Would that work for you?
I know it’s much to ask but can you please give a small example where to use the property settings (in which file exactly) and how to cycle through sprites?
And one more question:
Can this be used to access individual grass tiles by it’s coordinates for example, so only one grass tile can be changed to stone, dirt etc. (sprite frame)? This way I guess it will make possible all the features to change tiles on a map and using the changes with actions, like for example a character can open a door if he has the key, a bridge can be destroyed if he walks over it and so on.
Thank you for all your great help and feedback! I really appreciate it!
When I refer to a “property”, that means the property in Tiled. So to use the !isSprite! property, you add !isSprite! = true to the tile properties.
When a tile is created when !isSprite! = true, you can then access the tile and just call :setFrame() on it, just like any other Corona sprite.
[lua]
map.layer[“tiles”].tile(1, 1):setFrame(5)
[/lua]
Oh, and there’s a simple sprite example in maps/square_animated.json. Look at the tile properties for the first tile.
AWESOME! Both the info and the cool fix for the flickering lines. I fixed my tileset to avoid the problem, but now it even works with the ‘old’ tiles which is awesome!
What is the best way to implement parallax scrolling with the Dusk Engine?
I’ve spent the last week running test maps through Dusk in an attempt to get a fluid parallax effect. It’s working, but is far from fluid. I’m posting from mobile so I don’t have my code handy, will post that later. Here’s how it works, or doesn’t work ;).
1.) Build the map.
2.) Define individual layers.
3.) Create sprite with simple animation. Define linear velocity.
4.) Insert sprite into a platform layer (physic set up…works fine).
5.) Lock camera to sprite(centerX)
6.) Create functions to update x position of each layer(islandlayer.x = islandlayer.x - 5). Each function ends with map.updateView ().
7.) Run each function with timer delay:
timer.performWithDelay (1, updateIslandLayer, -1)
Like I said, this system does work, the layers scroll at different speeds. There are serious performance issues though. Within a few seconds, my sprite slows to a crawl. I’ve narrowed the problem down to the culling system. If I turn culling off (not really an option…map is 64000 pixels wide), there is no noticeable slowdown over time. There is still a performance issue because I’m loading a very large map into memory all at once.
My questions
Is there a better way to implement parallax?
Is there a way to have partial culling? Load entire map…remove tiles as they pass off the screen?
So sorry you spent so long on this; I really need to write docs :(.
Parallax scrolling is already implemented. Just set a layer’s xParallax and yParallax properties (from layer properties or programmatically), and the camera system will move each layer accordingly and cull correctly. Parallax is 1 -> normal, 0.5 -> half movement, 2 -> twice as much movement, etc.
I can’t figure out how to work with actual screen coordinates using dusk. Can someone please give some hints to the right direction!?
When touching the screen (map) I need the touch coordinates in pixels (not tiles). I’m using the camera following a character on screen and I can use the finger to move the map around. What I want to achieve here is: I want to touch the screen and then draw a line from the current character position (in pixels, not tiles) to the touch event. Somehow I can’t figure out to do this because the coordinates seem to be off. I know about the contentToLocal and localToContent, but I don’t know how to use it here to make the line drawing work. What exactly is the group here? The map itself is not working as group used with the localToContent.
Any ideas?
Thank you!
UPDATE:
I just saw I didn’t have access to the map in my part of the code. With older versions I got some errors (using Glider), but somehow with the new versions of Corona I don’t get this kind of error messages anymore.
I just noticed there still are some vertical 1px lines between tiles on a Retina iPad4
Maybe this is an easy fix because you already fixed the horizontal gaps?
I can work around the problem by putting an extra pixel around each tile (copying the outer border of the tile) and only using the inner area, as you mentioned before some posts ago… but it would be nice to have Dusk working without a graphical workaround