Showing posts with label Game. Show all posts
Showing posts with label Game. Show all posts

Tuesday, December 5, 2017

Shards at Yahoo! Japan

 



 On 28th November our game Shards was published at Yahoo! Japan. Game was published by Worker Bee Inc. and you can play it on their site here.


Saturday, September 30, 2017

Unity tutorial: Optimize removes from List

 





 If you maintain long List of items in your code and you often need to remove some at arbitrary position within it, then you pay performance penalty as all items with higher index have to be copied one position left.

 This is how code for method List.RemoveAt() looks:

        public void RemoveAt(int index) {
            if ((uint)index >= (uint)_size) {
                ThrowHelper.ThrowArgumentOutOfRangeException();
            }
            Contract.EndContractBlock();
            _size--;
            if (index < _size) {
                Array.Copy(_items, index + 1, _items, index, _size - index);
            }
            _items[_size] = default(T);
            _version++;
        }

 If item you want to remove is not the last one, then Array.Copy() is called. If your list is long and you are removing items at beginning, then performance costs may be high. But, if you do not care about order of items, you can write simple extension method, that will swap item you want to remove with last item in list and then call RemoveAt() on it. As item to remove is now last one, no copying of array is needed. Here is code for FastRemoveAt method:

using System.Collections.Generic;
using UnityEngine;

public static class ListExtensions {

    public static void FastRemoveAt<T>(this IList<T> list, int index) {
        // fast remove swaps item to remove with last item and then removes it
        // it should avoid internal Array.Copy, but changes order of items in List

        int lastIndex = list.Count - 1;

        T tmp = list[index];
        list[index] = list[lastIndex];
        list[lastIndex] = tmp;

        list.RemoveAt(lastIndex);
    }
}

 For test I created list with 100k items. Then, in loop, I remove first item in it and also add new item to the end, so it keeps its length. This is test code:

        // test
        Debug.Log("=========================================");
        var startTime = Time.realtimeSinceStartup;

        var list = new List<int>();
        var val = 0;

        for (; val < 100000; val++) {
            list.Add(val);
        }

        for (int i = 0; i < 1000000; i++) {
            //list.RemoveAt(0);
            list.FastRemoveAt(0);
            list.Add(val++);
        }

        Debug.Log("Time taken = " + (Time.realtimeSinceStartup - startTime));
        Debug.Log("=========================================");

 With both methods RemoveAt() and FastRemoveAt() I got these results for various number of updates:


 As you can see, FastRemoveAt() is much faster then RemoveAt().





Sunday, September 17, 2017

Pirates! - the match 3 made it into Apple AppStore

 



 Our game Pirates! - the match 3 is finally finished and its iOS version just made it into Apple AppStore. You can get it here:


 Pirates! is classic match 3 game with many different tasks for players - dig treasures, open chests, fight enemies or fulfil other tasks you are given in each level. It also features lot of gems combinations to produce various gameplay effects. Graphics for game was made by Tomáš Kopecký and music was composed by Juraj Růžička from SoundRoseStudio.






Flat Jewels Match 3 at Yahoo! Japan

 


 On 11th September our game Flat Jewels Match 3 was published at Yahoo! Japan. Game was published by Worker Bee Inc. and you can play it on their site here.

 



Wednesday, July 12, 2017

Fruit Dating at Yahoo! Japan

 


 Our logical puzzle game Fruit Dating was published at Yahoo! Japan today. It was published by Worker Bee Inc. and you can play it here.


Friday, June 30, 2017

Shards available in Windows Store

 



 Shards - the brickbreaker is now available in Microsoft's Windows Store as UWP aplication for Windows 10 phones.

Get it on Windows 10

Thursday, June 29, 2017

Shards and Fruit Dating is available on Tizen Store

 


 In June I rewrote our older games Shards and Fruit Dating into Unity engine. Both are now published at Tizen Store and anyone with Tizen device can download and play them!


Shards


Shards at Tizen Store




Fruit Dating


Fruit Dating at Tizen Store




Wednesday, April 19, 2017

New games released: Elsa Jewels, JumpTuber and Brick Stacker

 





 It has been long since I last posted info about games I finished. So, here is list of games finished or released in first quarter of 2017.


Elsa Jewels


 Elsa Jewels was exclusively made for Famobi. It features popular Disney's characters - Anna and Elsa from Frozen. And yes, Olaf is there too!
 You can play the game here.




JumpTuber


 JumpTuber is game to promote local youtuber Jirka Kral. Jirka is running from left to right in his youtuber den, picking likes and hamburgers. He has to avoid ducks and other items thrown at him by other youtubers. Game was made for Gamee platform and you can play it here.




Brick Stacker


 Last game in this list is Brick Stacker. It is another game made for Gamee. You have to build as high tower of blocks as possible. Test your building skills here (it is the best to play it on some device with portrait screen).



Monday, January 23, 2017

Phaser tutorial: How to balance random booleans for game

 





Previous Phaser tutorials and articles:
Phaser tutorial: Fun with bitmap fonts
Phaser tutorial: Using Spriter player for Phaser
Phaser tutorial: Merging fonts into sprite atlas
Phaser: Typescript defs for Phaser Box2D plugin
Phaser tutorial: Spriter Pro features added to Spriter player for Phaser
Phaser tutorial: Using Phaser signals
Phaser tutorial: Breaking the (z-order) law!
Phaser tutorial: Phaser and Spriter skeletal animation
Phaser tutorial: DronShooter - simple game in Typescript - Part 3
Phaser tutorial: DronShooter - simple game in Typescript - Part 2
Phaser tutorial: adding 9-patch image support to Phaser
Phaser tutorial: DronShooter - simple game in Typescript - Part 1
Phaser tutorial: custom easing functions for tweening and easing functions with parameters
Phaser tutorial: sprites and custom properties for atlas frames
Phaser tutorial: manage different screen sizes
Phaser tutorial: How to wrap bitmap text


Introduction


 Last year I worked on many small games, were obstacles were generated procedurally on the fly. Getting random numbers from random numbers generator played big role in it. Unfortunately, randomness can be sometimes pretty ... random. Let's say you just want to get randomly true or false to place some obstacle to the right or left. Be sure, that very quickly you will encounter situations, when you will not like the result. Sometimes, there will be too many obstacles on one or other side and game may get boring for long time periods.
 Fast fix may be to add some counters to check if not too many obstacles is on one or other side.
 I was solving this often and to make situation worse, clients had requests like: "I want first 5 obstacles to be left and right in turns, so it will be kind of tutorial for player."


Solution


 So, I decided to solve it once and forever with small class, which I named RandomBooleanBalancer. Here is complete code for it in TypeScript:

namespace Helper {

    export class RandomBooleanBalancer {

        private _rnd: Phaser.RandomDataGenerator;
        private _lbound: number;
        private _ubound: number;
        private _currentBalance: number;

        // -------------------------------------------------------------------------
        // balancer - how many consecutive same values maximally
        public constructor(rnd: Phaser.RandomDataGenerator, balancer: number) {
            this._rnd = rnd;
            this.reset(balancer);
        }

        // -------------------------------------------------------------------------
        public reset(balancer: number): void {
            --balancer;

            let lbound = Math.ceil(balancer / 2);
            this._lbound = -lbound;
            this._ubound = balancer - lbound;

            this._currentBalance = balancer === 0 ? this._rnd.integerInRange(-1, 0) : 0;
        }

        // -------------------------------------------------------------------------
        public getBoolean(): boolean {

            let result = this._currentBalance + this._rnd.integerInRange(this._lbound, this._ubound);

            //console.log("lbound = " + (this._lbound + this._currentBalance) + ", ubound = " + (this._ubound + this._currentBalance) +
            //    ", currentBalance = " + this._currentBalance + ", value = " + (result >= 0));

            this._currentBalance += result >= 0 ? -1 : 1;

            return result >= 0;
        }
    }
}

 In constructor it takes random numbers generator and "magic number" called balancer. This number is your request, how many consecutive same values it shall return when you repeatedly call getBoolean() method.

 For example, if you want true or false maximally two times after each other, then set it to 2.

 reset() method allows you to change this request during runtime.


Test


 Let's do some tests. Our test code will be simple loop with 50 iterations - it just prints string with 50 comma separated results, where true / false is converted to 1 / 0 to shorten output. We will start with balancer value equal 1:

            let randomBalancer = new Helper.RandomBooleanBalancer(this.rnd, 1);
            let result = "";
            for (let i = 0; i < 50; i++) {
                result += (randomBalancer.getBoolean() ? "1" : "0") + (i < 50 - 1 ? ", " : "");
            }
            console.log(result);

 Here is output from console:

0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1

 As our request was to have maximally 1 consecutive true or false, we got them switching regularly. If you run this test multiple times, you will notice, that whole sequence starts randomly with true or false.

 Now, change number in constructor to 2 and run the test again. This is console output:

0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1

 As you can see, returned values are random, but you get maximally two randoms of the same value after each other.

 Now, change requested value in constructor to 5. You may get something like this:

1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0

 In my run I did not get any sequence of 5 ones or zeroes. This is another nice feature of this class. As you get more and more, let's say, ones, there is decreasing probability, that next random will be also one. It is more and more probable it will be zero. But of course, it is possible to get true or false 5 times in row - but this is cap, as you requested: "5 times true or false in row, but no more".


Conclusion


 I hope this small code snippet will make your life easier. If you are interested in how it works, you can uncomment debug output in getBoolean() method and watch it after each call.








Wednesday, September 21, 2016

Phaser book on making procedural endless runner finished






 After a few months of work I finally finished my first Phaser book. Its name is "Create procedural endless runner in Phaser with TypeScript".

 Create procedural endless runner in Phaser with TypeScript

 In the book you develop procedural endless runner game "Goblin Run". You can see and play final result at http://sbc.littlecolor.com/goblinrun. It is using popular HTML5 engine Phaser and code is written in TypeScript. TypeScript is superset of JavaScript and if you are JavaScript programmer you should have no problems to follow. 


  Game features procedural level generation, spikes, in-air bonus jumps and gold to gather. Whole book is one big tutorial from setting up project to finishing polished game.
 Book is accompanied with complete resource files as well as with folders with source project for every chapter. All source code in book and in files is well documented.

 You can get it at Gumroad, as well as see there detailed table of  contents.


 This book is not for absolute beginners, who are learning what is variable and how to make loop. It is for people who have some basic knowledge what is Phaser, how to make something simple with it and now want to make something “bigger”, what will be beyond simple how-to examples. Book is one big tutorial that does not end with working prototype, but ends with complete game.




Saturday, July 2, 2016

Phaser tutorial: Fun with bitmap fonts

 





Previous Phaser tutorials and articles:
Phaser tutorial: Using Spriter player for Phaser
Phaser tutorial: Merging fonts into sprite atlas
Phaser: Typescript defs for Phaser Box2D plugin
Phaser tutorial: Spriter Pro features added to Spriter player for Phaser
Phaser tutorial: Using Phaser signals
Phaser tutorial: Breaking the (z-order) law!
Phaser tutorial: Phaser and Spriter skeletal animation
Phaser tutorial: DronShooter - simple game in Typescript - Part 3
Phaser tutorial: DronShooter - simple game in Typescript - Part 2
Phaser tutorial: adding 9-patch image support to Phaser
Phaser tutorial: DronShooter - simple game in Typescript - Part 1
Phaser tutorial: custom easing functions for tweening and easing functions with parameters
Phaser tutorial: sprites and custom properties for atlas frames
Phaser tutorial: manage different screen sizes
Phaser tutorial: How to wrap bitmap text


Introduction


 Very often I need to display some information for player in GUI in my games. It is usually composed of some text and icon. And it also often takes some time to fine tune positioning of text and icon. Things get complicated if part of it can change width like number on following image:


 Then, if you update number, you also have to update position of icon. Making some longer text, like the one on image bellow, with small images inside of it, is tedious work and usually needs lot of code.



Solution


 Fortunately, solution is easy. We can add images as special characters into font and then print whole text, including images, in one call in code.
 Let's say you have font called "Font" and atlas called "Game". Font is made of texture with characters and xml metadata file. It can be font made with Littera or any other font tool. Atlas is standard atlas with your game images.
 After these are loaded in your preload function - for example like this:

            this.load.atlas("Game", "assets/Game.png", "assets/Game.json");
            this.load.bitmapFont("Font", "assets/Font.png", "assets/Font.xml");

 you can start your adjustments in create function. First we get reference to our loaded assets:

            let atlas = this.cache.getImage("Game", true);
            let font = this.cache.getBitmapFont("Font");

 Next we get reference to loaded font xml data and also reference to capital "A" character. Reason for this is, that we will center added images on the same level as center of "A" is.

            let fontData = font.font;
            let charA = fontData.chars[65];

 Now, in my case, I have 7 gem images in atlas with names Gem1 ... Gem7. I will add them as special characters. First, I have to choose character code for them. Here I chose 5000 for Gem1, 5001 for Gem2 ...

            for (let i = 0; i < 7; i++) {
                let f = this.cache.getFrameByName("Game", "Gem" + (i + 1));

                fontData.chars[5000 + i] = {
                    x: f.x,
                    y: f.y,
                    width: f.width,
                    height: f.height,
                    xOffset: 1,
                    yOffset: charA.yOffset + Math.floor((charA.height - f.height) / 2),
                    xAdvance: f.width + 2,
                    kerning: [],
                    texture: new PIXI.Texture(atlas["base"], new PIXI.Rectangle(f.x, f.y, f.width, f.height)) 
                };
            }

 First, we get Phaser.Frame from atlas, so we will have access to position and dimensions of image within atlas. Next, we add new object with all font metadata to current font characters data at position of character code we chose before. For yOffset we are doing small calculation to center added images relative to "A" - we want center of A and added images on the same level. xOffset is 1 and it says, that there will be 1 pixel space after previous character. xAdvance then says how much has font renderer step to draw next character. We set this to width + 2 (= xOffset + width + 1). On last line, we are setting texture property. Here you may get error - just head to phaser.d.ts and change BMFontChar interface to use PIXI.Texture instead of PIXI.BaseTexture.


Test


 To test our gem images in text add this code:

            let text = "Hi, " + String.fromCharCode(5000, 5005, 5006) + " there!\n\nHow are you? " + String.fromCharCode(5001, 5002);
            let bmText = new Phaser.BitmapText(this.game, 0, 0, "Font", text, 110);
            bmText.anchor.x = 0.5;
            this.world.add(bmText);

 To include gems we make string from character codes with call to String.fromCharCode(). You should see this on screen:



Draw calls


 While everything works, there is small issue you should be aware of. As our font images and gem images are in different textures, there can be more draw calls. In above case there are four draw calls to draw this single piece of text.

 Fortunately, there is also solution for this. Merge your font into atlas as described in one of previous tutorials. Code changes only very little:


            let font = this.cache.getBitmapFont("Font");
            let fontData = font.font;
            let charA = fontData.chars[65];

            for (let i = 0; i < Level.MAX_GEM; i++) {
                let f = this.cache.getFrameByName("Game", "Gem" + (i + 1));

                fontData.chars[5000 + i] = {
                    x: f.x,
                    y: f.y,
                    width: f.width,
                    height: f.height,
                    xOffset: 1,
                    yOffset: charA.yOffset + Math.floor((charA.height - f.height) / 2),
                    xAdvance: f.width + 2,
                    kerning: [],
                    texture: new PIXI.Texture(font.base, new PIXI.Rectangle(f.x, f.y, f.width, f.height)) 
                };
            }

 You do not need reference to atlas, because gem images are in the same texture as font characters and in last line you can get base texture from font data.

 This reduces draw calls to one.


Conclusion


 With presented solution you can easily mix text with icons. If you merge font with atlas, there are no additional costs in terms of draw calls.








Sunday, April 17, 2016

Phaser tutorial: Using Spriter player for Phaser

 





Previous Phaser tutorials and articles:
Phaser tutorial: Merging fonts into sprite atlas
Phaser: Typescript defs for Phaser Box2D plugin
Phaser tutorial: Spriter Pro features added to Spriter player for Phaser
Phaser tutorial: Using Phaser signals
Phaser tutorial: Breaking the (z-order) law!
Phaser tutorial: Phaser and Spriter skeletal animation
Phaser tutorial: DronShooter - simple game in Typescript - Part 3
Phaser tutorial: DronShooter - simple game in Typescript - Part 2
Phaser tutorial: adding 9-patch image support to Phaser
Phaser tutorial: DronShooter - simple game in Typescript - Part 1
Phaser tutorial: custom easing functions for tweening and easing functions with parameters
Phaser tutorial: sprites and custom properties for atlas frames
Phaser tutorial: manage different screen sizes
Phaser tutorial: How to wrap bitmap text



Introduction


 Some time ago I published here article about Spriter player for Phaser. I made the code freely available at GitHub. Player is written in Typescript and GitHub code contained both the player and small example on how to use it in one project. I thought it would be easy for others to use it, but I was wrong - for some coders it would be better if there was separate .js file and also there was lack of information on usage. But if you want to have nice animations in your game like the parrot above, small obstacles should not discourage you!
 
 So, I made a few changes - check GitHub:
  • player itself and example are both separated from each other,
  • there is added Build folder, where you can grab either spriter.js or spriter.min.js files ready to be used in your project.
 Splitting player and example also forced creation of Typescript defs for player. It can be found in spriter.d.ts file in Build directory.


Example


 I assume you are familiar with Phaser states. On GitHub go into Test/src/States. In Preloader.ts file I am loading export from Spriter program with standard Phaser loader. Export can by either .xml (.scml) od .json (scon). I am also loading atlas with all part visual parts of animation (for test use files from assets folder):

            // load assets
            var path: string = Global.assetsPath;

            // test
            this.load.atlas("TEST", path + "Atlas.png", path + "Atlas.json");
            this.load.xml("TESTXml", path + "TEST.xml");
            this.load.json("TESTJson", path + "TEST.json");

 You will need only to load either xml or json. Both lines are here only to show both possibilities. 

 What is important, Spriter exports list of visual parts with file extension like "head.png". Spriter player cuts the extension off and uses only part name (like "head"). Some tools for making sprite atlases export names with and some without extension. Make sure, that you create atlas with names without extension.

 When your data are loaded you can move to file Test.ts, where we will use it.

 First, we will do some basic setup. Data we loaded in previous step are either .xml or .json. But we need to turn it into some structure player is familiar with. To do it there is Spriter.Loader class. This class takes Spriter.SpriteFile (which can be Spriter.SpriterXml or Spriter.Spriter.JSON) and outputs complete Spriter.Spriter data structure. Loader can process as many files as you need - you do not need to create it for every single processing. All Spriter player classes are in Spriter namespace, so I will not further write it here.

 Let's create loader:

            // create Spriter loader - class that can change Spriter file into internal structure
            var spriterLoader = new Spriter.Loader();

 Now, we will create SpriterFile that loader can proces. It is one of derived classes - SpriterXml or SproterJSON (this time I will choose JSON and leave XML commented out):

            // create Spriter file object - it wraps XML/JSON loaded with Phaser Loader
            //var spriterFile = new Spriter.SpriterXml(this.cache.getXML("TESTXml"));
            var spriterFile = new Spriter.SpriterJSON(this.cache.getJSON("TESTJson"));

 Spriter files are way how to wrap data, so single loader class can ask for information so different formats like JSON or XML in some uniform way. (By the way, there is also possibility to load special binary format through SpriterBin, but this feature is not currently working as I have to add Spriter Pro features into it.)

 In next step we will pass our spriter file to loader and in output we get "unpacked" structure with all objects needed for animation (which sprites it uses, what charmaps are available, list of entities, animations, timelines, ...). This structure is "read only" and no data are stored in it. It means you can use it for many animations running simultaneously on screen.

 In last step we will create the animation itself. For this, player has SpriterGroup object. It extends standard Phaser.Group class. So, everything you can do with Phaser.Group, you can also do with SpriterGroup (scale, rotate, blend, ...). SpriterGroup is main class of Spriter player and most of the things you will need is done through this class (create _spriterGroup variable, so you can reference your animation later):

            // create actual renderable object - it is extension of Phaser.Group
            this._spriterGroup = new Spriter.SpriterGroup(this.game, spriterData, "TEST", "Hero", 0, 100);
            this._spriterGroup.position.setTo(420, 400);

            // adds SpriterGroup to Phaser.World to appear on screen
            this.world.add(this._spriterGroup);

 To tick animation add this into update method:

        update() {
            this._spriterGroup.updateAnimation();
        }

 This is little stupid, because Phaser calls update on Phaser.Group automatically. So, if animation update was in update method of SpriterGroup and not in updateAnimation, then this call would not be needed. I will probably change it in future. Until, you have to tick your animations explicitly.

 Running the example now, you should have animated character on screen. If you used assets from test, you will see this boy:


SpriterGroup features


 As already said, main class is SpriterGroup. So, I will go through its features here. I will use Typescript syntax as it includes type information, but it should be perfectly readable also for JS developers (take it as pseudocode).

 In example above we created new SpriterGroup like this:

this._spriterGroup = new Spriter.SpriterGroup(this.game, spriterData, "TEST", "Hero", 0, 100);

 Here is what these parameters mean:

        constructor(game: Phaser.Game, spriter: Spriter, texutreKey: string, entityName: string,
            animation?: string | number, animationSpeedPercent?: number);

 You need to pass Phaser.Game like for many other Phaser gameobjects. Next you have to pass Spriter animation structure that you processed with Spriter Loader class. Third is name of atlas with visual parts of animation. Last mandatory parameter is name of entity. Spriter file can have one or more entities. When you create SpriterGroup you have to pass which entity you want to use. You can not change this later.
 If you omit animation then first animation for entity is started. Every entity has one or more animations. Animations within entity can be switched. Last parameter is speed of animation in percent. default value is 100.

 SpriterGroup can inform you on a few events. This is done through standard Phaser.Signals. Here is list of signals you can use:

        // onLoop(SpriterGroup);
        onLoop: Phaser.Signal;
        // onFinish(SpriterGroup);
        onFinish: Phaser.Signal;

        // onSound(SpriterGroup, string); // string for line name which equals soud name without extension
        onSound: Phaser.Signal;
        // onEvent(SpriterGroup, string); // string for line name which equals event name
        onEvent: Phaser.Signal;
        // onTagChange(SpriterGroup, string, boolean); // string for tag name, boolean for change (true = set / false = unset)
        onTagChange: Phaser.Signal;
        // onVariableSet(SpriterGroup, Variable); // Variable is Spriter variable def with access to value
        onVariableSet: Phaser.Signal;

  • onLoop - subscribers are notified when animation loops,
  • onFinish - if animation does not loop, subscribers are notified on finishing,
  • onSound - Spriter Pro animations can have soundline, which allows great synchronization between animation and sounds. Spriter player does not actually play sounds, but notifies subscribers when sound shall be played. Signal dispatches SpriterGroup that fired event and name of  sound to play. In this way it is just specific sound event,
  • onEvent - in this Spriter player implementation it is the same as onSound, but not sound specific. Also here, name of the event is dispatched,
  • onTagChange - tags in Spriter animation says that something is on or off. When this changes you can read it through this signal. Imagine for example starting / stopping particle rain from sky when wizard casts spell (during "castRain" tag on). In this signal you get not only name of tag, but also its on/off state in next parameter,
  • onVariableSet - Spriter Pro animations can have variables, that are set in certain points to certain values. These variables are integers, floats and strings. Current implementation does not interpolate integer and float variables. Currently, it is only set to new value. You can listen to these events when variable is set and do something with its value. You can treat it as "event with value". Here you get Variable object that holds name, type and value.

 Here are few properties you can read:

        // get loaded Spriter structure
        spriter: Spriter;
        // get Spriter entity
        entity: Entity;
        // number of animations for current entity
        animationsCount: number;
        // name of current animation
        currentAnimationName: string;

 pause can be read and set:

        // is anim paused?
        paused: boolean;

 To play or change animation, set its playing speed and to update (tick) whole SpriterGroup, use these methods:

        // set speed of animation in percent (default = 100)
        setAnimationSpeedPercent(animationSpeedPercent: number): void;
        // play animation by Spriter animation id
        playAnimationById(aAnimationId: number): void;
        // play animation by name
        playAnimationByName(aAnimationName: string): void;
        // call this on every frame to tick animation
        updateAnimation(): void;

 Next set of method allows you to work with charmaps. Charmaps are sets of alternative visuals for animation (you can replace only some visuals). These charmaps can be stacked on each other. As a result you can achieve high variability with small amount of assets. Imagine evil orc as base character and charmap for replacing club with rusty sword and another charmap for helmet.

        // add charmap on top of charmap stacky by name
        pushCharMap(charMapName: string): void;
        // remove charmap from stack by name
        removeCharMap(charMapName: string): void;
        // remove all charmaps from charmap stack
        clearCharMaps(): void;

 With last set of methods you can question tags and variables:

        // check if animation tag with given name is on or off
        isTagOn(tagName: string): boolean;
        // check if animation tag with given id is on or off
        isTagOnById(tagId: number): boolean;
        // get animation variable by name
        getVariable(varName: string): Variable;
        // get animation variable by id
        getVariableById(varId: number): Variable;
        // get Spriter object by name - Spriter object contain actual Phaser.Sprite
        getObject(objectName: string): SpriterObject;


Conclusion


 I hope this tutorial helped to clarify some point, that were not clear before. Using Spriter animation as just another Phaser gameobject should be convenient. More, you can use all Phaser.Group methods with it.