Hi all, this is my first contribution to the Defold workspace and my first post to the forums.
One of the issues I ran into with Defold was the fact that it does not support runtime tile animations. Most of the games that I love to play now and loved to play growing up boasted beautiful tilemap scenes with moving parts all over the place.
Defold Tilemap Animator provides runtime tile animations in a Defold game engine project. This includes both looping and trigger animations.
Full version 1.0 has been released. It now supports four loop playbacks:
āloop_forwardā
āloop_backwardā
āloop_pingpongā
āloop_corollaā
And four on-demand playbacks:
āonce_forwardā
āonce_backwardā
āonce_pingpongā
āonce_corollaā
On-demand playbacks are the bread and butter of DTA: they allow you to programmatically run animations on any tile assigned with a āonce_ā playback. This can be used to display interactive visual effects on a tilemap, such as the player stepping through grass or chopping down a tree. Iām pleased to see these playbacks working properly!
Just a small note, that for me natural was that āonce_forwardā should end at āend_tileā
function dta.once_forward(data, instance_data)
instance_data["frame"] = instance_data["frame"] + 1
if instance_data["frame"] > data["end_tile"] then
instance_data["frame"] = data["end_tile"] -- not "start_tile"
instance_data["extra"] = 9999
end
end
Thanks! Glad you like it. I see what you mean about the start_tile preference, I will look into it. I actually plan to rewrite this module soon, since there are quite a few components I can make more flexible and efficient. Now that Iāve learned about semantic versioning and how to handle open source projects properly, hopefully there wonāt be too many setup changes after I get the new version out.
If you have any feature ideas, let me know! Iāve started using this in my own project and I realize there may be some additional functions I could add to make things super convenient.
One feature I was thinking on was using DTA to set tiles properly according to some event (e.g. when that grass is burnt), but I came out with a workaround of just modifying āanimation_groupā table to suite my needs
Looks great! Bringing tile map worlds to life is exactly what I was hoping to see more of.
As for the suggestion, thatās in part why I added once_animations and the dta.animate(x, y) function. If you keep track of where the fire is burning, you can pass the coordinates to that function to roll the new animation.
Oh wait. Actually, something just came to kind. You mean youāre trying to assign both a continuous grass animation and a burning animation when an event occurs? I didnāt think of that.
Yes, you could edit the tables, but Iād like to make a safer way of dealing with that. Thanks for the suggestion, Iāll make sure to work it in soon.
No, no. One solution will be to draw burnt version of tileset and use it with your DTA - I will just set_tile to another tile (letās say 100) and in āanimation_groupā there will be an entry starting at 100 and with end_tile = e.g. 110, so one normal animation, but Iām changing a tile
But thatās a lot of drawing and Iām thinking about some shader instead, but for now I have something pretty easy and pretty ugly:
(itās working just like 2D lights, but color is black and not drawn on background (but drawn on hero sprite - that you can see it in the end of this gif)
I donāt like it now, but perhaps Iām going into a proper direction with something like a ādecayā on the ground. For grass I will probably need to make something different.
I decided to rewrite this entire module from scratch. The resulting Lua module was cut ~in half, design complexity was drastically reduced, the code is much more readable, and performance has been slightly improved.
Additionally, due to my recent learning about semantic versioning and how to properly manage a GitHub release, all erroneous previous releases have been deleted and replaced with version 0.1.0. Sorry for any inconvenience, although I am relieved to know that this will no longer be an issue in the future. Please take a look through the new README.md for setup changes.
Finally, a few notes about improvements to the module:
All loop_ and once_ callback presets have been removed. Instead, you are able to define your own custom animation sequences without being forced to conform to a preset. Very handy!
Tilemap layers have better support, namely when activating a trigger animation from a script.
Message passing has been incorporated into the project. DTA will send animation progress updates to your on_message() function. This can be disabled by calling dta.toggle_message_passing().
I noticed that using tilemap.set_tile() does not play nice with DTA, since the only version of tilemap that the module knows about is the one that exists when dta.init() is called. It will continue animating the exact same tiles regardless of how the tilemap changes throughout its lifetime. If you are setting new tiles to your map, then you will likely run into this problem. I am looking into how to handle this.
Let me know if you run into any glitches or unexpected behaviors. I will be sure to fix them as soon as possible.
It has been a while, but I figured Iād mention: DTA v0.2.0 was just released. Your suggestion was added! We can now specify a new reset field in the animation_groups table passed into dta.init(). This argument indicates that this trigger animation should regain its start tile graphic on completion. Otherwise, this animation will quit rolling once the final sequence frame has been reached.
Hey, I have been trying to implement this feature into my game for ages now but canāt get it to work. Every time I set it up I get the error āāinsertā (table expected, got nil)ā. I have tried setting it up using your exact example code with same setup and everything but nothing works and every time I am greeted with the same error.
please help!
Looks like dtile.tilemap_grid was not initialized properly. Can you post your code for the dta.init() function? Iām thinking one of your arguments is invalid.
I copied this straight from your example, all I changed was the path āmain.script.animation_groupsā. I also tried with a local function instead too.
function init(self)
msg.post("#", h_str.acquire_input_focus)
dtile.init(require āmain.scripts.animation_groupsā, msg.url("#tilemap"), { h_str.terrain })
dtile.toggle_message_passing(true, msg.url())
end
Donāt worry fixed it now. I literally just deleted line 108 in your lua script LOL.
ātable.insert(dtile.tilemap_grid[dtile.tilemap_layers[i]][j], tile_id)ā
It has been a while since Iāve looked at the Lua code, but I believe that line is critical for proper functioning. If you run into another problem, perhaps upload a copy of your Defold project and I can take a look.