Defold Tilemap Animator

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.

Happy Defolding!

14 Likes

Sounds like a good module, thanks! Yet the link in github to the html5 example is not working.
http://planksoftware.com/html/defold_tilemap_automator.html

2 Likes

Approved! It should show up in the Asset Portal in a couple of minutes.

1 Like

Yes, I will fix this issue once I draft a more interesting example project and implement a couple new features.

Thank you! I will submit cover art for the asset soon.

1 Like

Full version 1.0 has been released. It now supports four loop playbacks:

  1. ā€œloop_forwardā€
  2. ā€œloop_backwardā€
  3. ā€œloop_pingpongā€
  4. ā€œloop_corollaā€

And four on-demand playbacks:

  1. ā€œonce_forwardā€
  2. ā€œonce_backwardā€
  3. ā€œonce_pingpongā€
  4. ā€œ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!

4 Likes

This asset is amazing! :wink:

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
2 Likes

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. :slight_smile:

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.

2 Likes

Yoau can see DTA here in action on the grass: :smiley: :leaves:

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 :wink:

4 Likes

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. :persevere:

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.

1 Like

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 :wink:

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.

2 Likes

Hi all,

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:

  1. 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!
  2. Tilemap layers have better support, namely when activating a trigger animation from a script.
  3. 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.

5 Likes

Good work!

2 Likes

Thanks for making this extension! Iā€™m planning to add it to my current project.

3 Likes

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.

7 Likes

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.

Example: dtile.init(require "example.animation_groups", msg.url("#tilemap"), { h_str.terrain })

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.

well ideally I could have it working without having to delete anything.
Hereā€™s my project, see what you think.
Project.zip (2.7 MB)