colinvella

Implementing animated tiles from Tiled JSON Tilemap files

Recommended Posts

I have spent some time finding out how to animate tiles in a tile map loaded from a Tiled map exported to JSON. At first I built a utility class called TileMapAnimator (TMA) to animate some tiles using manual data and eventually I extended the class so that it could load animated tile data directly from the map files. With TMA you define your animations in Tiled and load them directly into your Phaser game!

I'm sharing this code in the hope that others may find it useful. If you have invested into loading Tiled maps using the built in functions, I believe you can include animations in your game with very little retrofitting.

TMA can animate hundreds of tiles without any notable performance degradation.

Some usage restrictions apply:

  • In TMA, each animation uses a fixed frame interval for all the tile frames. Tiled actually allows you to specify different durations per frame. Hence TMA picks the first duration as the frame interval. 
  • TMA requires tile animations to be defined on one of the tiles included in the animation. This is because TMA scans the map layer for these tiles and sets up the animated tiles at the designated locations
  • Only one animated tile layer is supported for now. Perhaps I will extend TMA to support animation in multiple layers.

How to use TMA

Import the TMA class:

 
    import TilemapAnimator from "../graphics/TilemapAnimator";
 

In preload(), load the tile map and associated tile sets using the built-in Phaser map loading functions:

 
    this.load.tilemap('TileMap', 'assets/maps/world1/TileMap.json', null, Phaser.Tilemap.TILED_JSON);
 
    this.load.image('Ground', 'assets/graphics/world1/Ground.png');
 

Load the tile map again, but this time as a raw JSON file:

 
    this.load.json("TileMapAnimations", 'assets/maps/world1/TileMap.json');
 

In create(), set up the map and layers as usual:

 
    const tilemap = this.add.tilemap('TileMap');
    const groundTileset = tilemap.addTilesetImage('Ground', 'Ground');
    const groundLayer = tilemap.createLayer('Ground');
 

Create an instance of TMA, passing the game.time object, the tilemap and the layer containing the animations:

 
    const tilemapAnimator = new TilemapAnimator(this.time, tilemap, groundLayer);
 

Load the animation into TMA, by specifying the cache key of the raw JSON object loaded in prefetch() using game.load.json(....) and start the tile animations:

 
    tilemapAnimator.addAnimationsFromTilemap("TileMapAnimations");
    tilemapAnimator.start();
 

That's all there is to it! :)

Note: I am no NPM expert, but if anyone is willing to turn this into an NPM package or some other practical library, please get in touch so we set it up! 

The TMA class file is attached below.

 

 

 

 

 

 

TilemapAnimator.js

Share this post


Link to post
Share on other sites
7 hours ago, Pryme8 said:

is this glsl handling it?  I am looking to extend my tilemap shader to include animated tiles and this may help if you have the shader written already.

The TMA class essentially runs a background thread and changes specific tiles at specific intervals on a standard tilemap object, so all the actual rendering is done by Phaser. It's not a rewrite of tilemap,  but simply an addon.

Note that it's also possible to add animations manually using something like:

 
    tilemapAnimator.addAnimation([20, 21, 22, 23], 100, this.tileset);
 

which adds an animation consisting of the 4 tile indices 20 - 23 from the specified tileset with a frame duration of 100ms. The animation is applied anywhere on the layer where there are tiles with indices 20 - 23.

 

 

Share this post


Link to post
Share on other sites

At least the above demo with the animated water would be enough demo for me in JS! <3

Simplified & not using "this" or "prototype", but instead: 

var myfunc = function ( . . . ) { . . . }

~M

 

Share this post


Link to post
Share on other sites
On 20/10/2017 at 9:48 AM, Mythros said:

At least the above demo with the animated water would be enough demo for me in JS! <3

Simplified & not using "this" or "prototype", but instead: 

var myfunc = function ( . . . ) { . . . }

~M

 

I've been busy working on this over the past weeks and now it has evolved into this: https://www.npmjs.com/package/phaser-tilemap-plus

You should be able to use it with legacy ES5 javascript. Tile Animation is just one of the feztures now.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.