# Examples of animated tileset and image layer in Phaser3

**URL:** <https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992>\
**Category:** Phaser 3\
**Created:** [February 14, 2024, 3:59pm UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992 "2024-02-14T15:59:44Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![QuantumTopology](https://avatars.discourse-cdn.com/v4/letter/q/94ad74/32.png) [@QuantumTopology](https://phaser.discourse.group/u/QuantumTopology)\
**Post date:** [February 14, 2024, 3:59pm UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/1 "2024-02-14T15:59:44Z")

</div>

Is there any examples about how to display animated tilesets and image layer in Phaser3 ? Here is a tilemap with many layers. The background are composed by two images layers. Back layer 1 contains some animated layers representing the water. There are also some objects layers for the restrictions on activity areas. How to load and use these entries in phaser 3?

 ![image](https://global.discourse-cdn.com/free1/uploads/phaser1/original/2X/a/ad3694d4f43f0e33e842d38a0f3f153ba6c4e6f8.png)

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [February 14, 2024, 4:12pm UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/2 "2024-02-14T16:12:03Z")

</div>

Phaser 3 creates and renders tile layers only, with no tile animations.

Any image layer data is in [Tilemap#images](https://newdocs.phaser.io/docs/3.70.0/focus/Phaser.Tilemaps.Tilemap-images). You could use that to add images the usual way, with `this.add.image(…)`.

For object layers, you can use [createFromObjects()](https://newdocs.phaser.io/docs/3.70.0/focus/Phaser.Tilemaps.Tilemap-createFromObjects) to convert them into sprites or other Tilemap methods to get and work on the object data yourself.

For animated tiles, you could either [convert them into sprites](https://newdocs.phaser.io/docs/3.70.0/focus/Phaser.Tilemaps.Tilemap-createFromTiles) and play [“real” animations](https://newdocs.phaser.io/docs/3.70.0/Phaser.Animations.Animation) or run a simple timer changing the tile ID.

---

<div class="post-metadata">

**Author:** ![QuantumTopology](https://avatars.discourse-cdn.com/v4/letter/q/94ad74/32.png) [@QuantumTopology](https://phaser.discourse.group/u/QuantumTopology)\
**Post date:** [February 14, 2024, 10:37pm UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/3 "2024-02-14T22:37:53Z")

</div>

Thanks ! I will try these.  
If I create sprites for each animated tiles, will this be vey time-consuming ?  
 ![image](https://global.discourse-cdn.com/free1/uploads/phaser1/original/2X/1/1cf64feca3c8daf45d1f59f156102bc25da55bf3.png)  
For example, if I have four animated tiles, I have to place the sprite on each of the solts. Can I combine these tiles to make a _ **larger** _ sprite ?

---

<div class="post-metadata">

**Author:** ![QuantumTopology](https://avatars.discourse-cdn.com/v4/letter/q/94ad74/32.png) [@QuantumTopology](https://phaser.discourse.group/u/QuantumTopology)\
**Post date:** [February 15, 2024, 12:27am UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/4 "2024-02-15T00:27:37Z")

</div>

Hello, I don’t understand why these two things are very different: [Phaser.GameObjects.Sprite](https://newdocs.phaser.io/docs/3.70.0/Phaser.GameObjects.Sprite) and [Phaser.Types.GameObjects.Sprite](https://newdocs.phaser.io/docs/3.70.0/Phaser.Types.GameObjects.Sprite) . According to the page of **SpriteConfig** , I can only set the key, frame and anims. However, in some examples, x, y and scale can also be set. (In the documentation of **Scene.make.sprite** and **createFromTiles** , the SpriteConfig argument is linked to the same page. )

```javascript
const config8 = {
            key: 'logo',
            x: 400,
            y: 300,
            scale: { x: { randFloat: [0.2, 2] }, y: { randFloat: [1.5, 3] } }
        };

        this.make.sprite(config8);

```

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [February 15, 2024, 12:51am UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/5 "2024-02-15T00:51:17Z")

</div>

`make.sprite(…)` takes [GameObjectConfig](https://newdocs.phaser.io/docs/3.70.0/Phaser.Types.GameObjects.GameObjectConfig) and [SpriteConfig](https://newdocs.phaser.io/docs/3.70.0/focus/Phaser.Types.GameObjects.Sprite.SpriteConfig).

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [February 15, 2024, 12:53am UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/6 "2024-02-15T00:53:17Z")

</div>

You could use a TileSprite, but that doesn’t have an animation component like Sprite does.

---

<div class="post-metadata">

**Author:** ![QuantumTopology](https://avatars.discourse-cdn.com/v4/letter/q/94ad74/32.png) [@QuantumTopology](https://phaser.discourse.group/u/QuantumTopology)\
**Post date:** [February 15, 2024, 1:14am UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/7 "2024-02-15T01:14:38Z")

</div>

Thanks, but I still have no idea how to create an aimated tile sprite 🥲  
See the codes and comments below.

```javascript
//I create some layers
map.createLayer("Back Layer 1", tileset, 0, 0);
map.createLayer("Back Layer 2", tileset, 0, tanslateY);
map.createLayer("Front Layer", tileset, 0, tanslateY);
//In back layer1, There are some tiles which I want them to be animated.
//Here is the json related to animated tiles
let animated_tiles_json = {
 "195": //tile 195 and 196 are combined to be an animated tile.
{"animation":[{"duration":100,"tileid":195}, 
{"duration":100,"tileid":196}]},
"216":
{"animation":[{"duration":200,"tileid":216}, 
{"duration":200,"tileid":217}]}
}
//For the animated tile "195", there are two frames
let sprites = map.createFromTiles(
   [195, 196], //the two frames
   null, 
   {key: "ani", x: 400, y: 300}, //the position and the name of this sprite
   this, //the Phaser.scene
   undefined, //camera ? in fact, I don't know how to handle this argument
   "Back Layer 1" //the animated tiles are shown in back layer1
);
//However, sprites is an empty array
console.log(sprites); // []
this.add.sprite("ani"); //I get a black square, there is nothing in it.

```

Say I have a 54\*30 tilemap layer which is bulit from the tileset containing 200 square tiles. Then the first argument of **map.createFromTiles** should be the indexes in the range[0, 1620] or in the range[0, 199] ?

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [February 15, 2024, 2:39pm UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/8 "2024-02-15T14:39:14Z")

</div>

Since there are two animations, I think you’ll probably call `createFromTiles(195, …)` and `createFromTiles(216, …)`.

https://codepen.io/samme/embed/preview/ExPMrNP?default-tabs=js%2Cresult&height=300&host=https%3A%2F%2Fcodepen.io&slug-hash=ExPMrNP

---

<div class="post-metadata">

**Author:** ![QuantumTopology](https://avatars.discourse-cdn.com/v4/letter/q/94ad74/32.png) [@QuantumTopology](https://phaser.discourse.group/u/QuantumTopology)\
**Post date:** [February 16, 2024, 12:31pm UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/9 "2024-02-16T12:31:20Z")

</div>

After “try and error”, I finally find the solution. Thank the help from @samme .I post the codes here for anyone who needs this,  
For the image layer, just treat it as a normal image. Usually we need to tile the image on a rectangle area, so we need the tileSprite function, for example

```javascript
this.add.tileSprite(0, 550 2048, 512, "Background").setOrigin(0, 0); 
this.add.tileSprite(0, 380, 2048, 512, "Clouds").setOrigin(0, 0);

```

where “Background” and “Clouds” are the keys of the textures which we load in preload() function.

For the animated tiles, we can create an animation or change the ids of tiles in a timer.  
The first way, create an animation:

```javascript
//Suppose I have loaded a map with the key "map1"
let map = this.make.tilemap({key: 'map1'});
//It has a tileset, named "tileset", here I create the tileset.
let tileset = map.addTilesetImage("tileset", "tileset_image");
//Here is the json related to the animated tiles, these can be generated by Tiled
//However, phaser.js won't read these informations
let animated_tiles_json = {
            "195":{"animation":[{"duration":100,"tileid":195}, {"duration":100,"tileid":196}]},
            "216":{"animation":[{"duration":200,"tileid":216}, {"duration":200,"tileid":217}]}
        };

```

Here comes the important part. If we want to create an animation, we need a texture with multiple frames. The image we load (“tileset\_image” in this case) is already a texture, with a single default fram \_\_BASE. We just need to add frames to this textures. And the frames we should add are just the tiles we want to animate.

```javascript
let tileid, x, y, tileWidth, tileHeight;
tileWidth = tileset.tileWidth;
tileHeight = tileset.tileHeight;

for (let key in animated_tiles_json) {
     if (animated_tiles_json.hasOwnProperty(key))
            {
                for(let i = 0; i < animated_tiles_json[key]["animation"].length; ++i)
                {
                    tileid = 1 + animated_tiles_json[key]["animation"][i]["tileid"];
                    x = map.tiles[tileid][0];
                    y = map.tiles[tileid][1];
                    this.textures.list["tileset_image"].add(
                        "tile_frame_"+tileid, //the name of frame
                        0, //source index
                        x, //x coordinate of frame
                        y, //y coordinate of frame
                        tileWidth, 
                        tileHeight); 
                }
            }
        }

```

Now we can create the animation:

```javascript
this.anims.create({
            key: "flame_ani",
            frames: [
                {key: "tileset_image", frame: "tile_frame_196", duration:200},
                {key: "tileset_image", frame: "tile_frame_197", duration:200}
            ],
            repeat: -1
        });
       
        this.anims.create({
            key: "water_ani",
            frames: [
                {key: "tileset_image", frame: "tile_frame_217", duration:200},
                {key: "tileset_image", frame: "tile_frame_218", duration:200}
            ],
            repeat: -1
        });

```

The last step, we should create sprites on the position where the tiles should be animated.

```javascript
//Create the "Back Layer 1"
//On this layer, there are some tiles representing water, which should be animated.
//The indexes of them are 217.
map.createLayer("Back Layer 1", tileset, 0, 0);
//Now we select all the tiles with id 217, and replace them by the empty tile, 0.
//And create sprites on the locations of these tiles. All these works are done by createFromTiles.
let sprites = map.createFromTiles(217, 0, {anims: "water_ani"});
for (let i = 0; i < sprites.length; ++i)
{
      sprites[i].setOrigin(0, 0);
 }

```

For the second way, we firstly define a class:

```javascript
class changeTile {
    constructor()
    {
        this.I = 0; 
        this.layer = null; 
        this.tile_index = []; 
        this.tile_id_array = []; 
    }

    next ()
    {
        if (this.I == this.tile_id_array.length) this.I = 0;
        for(let i = 0; i < this.tile_index.length; ++i)
            this.layer.data[this.tile_index[i][0]][this.tile_index[i][1]].index = this.tile_id_array[this.I];
        this.I += 1;
    }
}

```

next, fill the class and create a timer

```javascript
let ct1 = new changeTile();
        let back_layer_1 = map.getLayer("Back Layer 1");
        //The layer object which we want to change its tile id
        ct1.layer = back_layer_1;
        //Tiles 217 and 218 forms the animation
        ct1.tile_id_array.push(217, 218);
        for(let i = 0; i < back_layer_1.height; ++i)
            for(let j = 0; j < back_layer_1.width; ++j)
                //Here, we find the tiles which we should change the ids.
                if (back_layer_1.data[i][j].index == 217) ct1.tile_index.push([i, j]);
        //At last, we create the timer.
        this.event1 = this.time.addEvent(
            {
                delay: 200,
                loop:true,
                callback: () => {ct1.next(); }
            }
        );

```

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [February 16, 2024, 4:26pm UTC](https://phaser.discourse.group/t/examples-of-animated-tileset-and-image-layer-in-phaser3/13992/10 "2024-02-16T16:26:29Z")

</div>

> [@QuantumTopology](#):
>
> `let sprites = map.createFromTiles(217, 0, {anims: "water_ani"});`

You can use `{ anims: "water_ani", origin: 0 }` here.
