Showing posts with label Animation. Show all posts
Showing posts with label Animation. Show all posts

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.
















Sunday, February 21, 2016

Phaser tutorial: Spriter Pro features added to Spriter player for Phaser

 





Previous Phaser tutorials:
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





   Some time ago I wrote Spriter player for Phaser. In that time, I had only free version of Spriter, so features available only in Pro version were not available in it. In the end of previous year I purchased Pro version and in these days I updated the player to work with new features. It includes:
  • character maps,
  • events,
  • sounds (actually not plying sound, but sending sound event),
  • tags,
  • variables (currently does not interpolate int and float variables)




  Here is live demo of the player:
  • press A to switch animations (demo has 2),
  • press C to stack character maps. There are two and are stacked on each other to give three visual states (first one is basic appearance),
  • text, the guy is saying is fired by string variable change in animation.


 You can get full Typescript source with working demo above at GitHub.






Tuesday, September 1, 2015

Phaser tutorial: Phaser and Spriter skeletal animation

 





Previous Phaser tutorials:
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


 Recently I was looking for some way how to play skeletal / bone animated characters in Phaser. Unfortunately, there is not too much choices if you just want to try some tool in end-to-end way (from creating animation in tool to playing it in Phaser game).
 Finally, I managed to do it and it is what this article is about. So, read on...


Tools overview

 First I was looking for available tools. I found four which interested me and which I decided to examine deeper:
  • Creature - looks very impressive. From Phaser 2.4.0 it is even supported in engine. But, it costs $99 for Basic and $170 for Pro version. In Trial version you cannot save or export your project. It can be good for artist to try the tool, but I am coder and, as already mentioned, my attempt was to try end-to-end implementation. Beside this, it looks that WebGL rendering mode is needed,
  • DragonBones - this tool attracted me with it price - it is free. But it looks you need Flash Pro to use it. DragonBones is supported by Adobe. So, buy Adobe Flash Pro to get DragonBones for free :-) Beside this, I did not find any documentation on tool's export files,
  • Spine - this tool has documentation on export format, but it does not let you to save and export in trial version. Essential version costs $89 and Professional $289. Hey, I just want to try to make simple animation, export it and implement it in Phaser. I will not blindly buy any tool that does not let me do this - what if its export is horrible mess and making the player will turn into nightmare?,
  • Spriter - this tool made by BrashMonkey has also free and Pro version for $59. But, finally tool, that let me try it, export my animation into .xml or .json. Has some documentation on format. Beside this, its use is simple even for programmer and there is also series of video tutorials, that will guide you through program functions. It also shows, what is only in Pro version.
 From above list I selected Spriter. And if in future I wanted to go Pro with some of the tools, I would definitely do so with Spriter, as I now know it little and I invested time into making runtime for Phaser.


Runtimes

 Despite some other tools, Spriter does not come with runtimes. It is up to you to find some already existing one or to write your own. Spriter has forum, where peoples using it and coder implementing runtimes meets. There you can get links to various runtime implementations. From those I found these two attracted me most:
  • spriter-scon-js by Dean Giberson. It is reading .scon files, which is .json export from Sprites. The implementation is minimal, but reading it helps you to find what is in export and what are relations between its data structures. Also its length encourages you to write your own!,
  • spriter by Trixt0r (Heinrich Reich). This one is more massive supporting Java2D, libGDX and others. I regret that I did not find it earlier. I found it with half of my implementation finished, when I was searching internet for solving reverted y axis issue. At least, I used its test character animation instead of my crappy programmer animation I was using before.

Runtime for Phaser

 Before I will go further here is result: Spriter bone animation running in Phaser (press A to switch to next animation):


 Runtime is written in Typescript and significant part of it is just structure of all objects needed for animation and filling these structures when loading animation data. Currently, this is first version of implementation and only tweening between two positions is linear (will add curves later), but I am happy with the result! Also some features, that are available only in Spriter Pro are not implemented (character maps, sounds, events, ...).
 Second part of source is the player, that takes loaded data and tweens bones and sprites between keyframes and also transforms it from its local spaces into world space.
 Phaser specific is that all visible parts are Phser.Sprite objects and whole character is Phaser.Group object. So, you can further take it and transform (scale, move, rotate) - it is part of scene graph.


Quick export structure overview

 Export begins with information on folders and files. Files are in fact files with individual sprite parts. As I am using atlas I use file names as frame names. Folders can help you to organize your assets, but with atlas I am not using them.

Spriter editor


 Next part is Entity. Entity is your character and one file can contain multiple entities. Entity has one or more animations. Entity is that grey guy and animations are short sequences you can either loop or play only once.

 Core of each animation is main timeline - bottom third on editor picture. Whenever you change some part (either bone or sprite) it creates keyframe on main timeline. These keyframes reference to particular timelines for individual bones or sprites. Keyframes are those small vertical rectangles on picture. It keeps information on time, position, rotation, scale, spin ... and file and folder for sprites.

 Of course, during implementation, you will encounter lot of issues. My biggest problem was correct handling of y axis. In Spriter 0,0 point is in top left corner, but when rotating, 90 degrees points up. In export coordinates are exported in "OpenGL" way with 0,0 in bottom left corner, and 90 degrees points up (and after long debugging I also found, that sprite y pivots were reverted during export). In Phaser 0,0 is in top left corner again, but 90 degrees points down. It was necessary to flip all angles along horizontal axis and also correctly handle spins. Spins say in which direction bone or sprite should rotate to its target position.

 Detailed information on structure can be found here and also examining other implementations can fill holes where documentation is not actual or missing.


Conclusion and download

 I am really happy that I managed to make it work. I hope it will help great Phaser community. If you are interested, you can get whole project (MS Visual Studio 2015) here: SpriterExample.zip
 Most of the project is the Spriter player and the rest are some small help classes necessary to run the example.



Saturday, May 23, 2015

Phaser tutorial: DronShooter - simple game in Typescript - Part 3

 





Previous Phaser tutorials:
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


 This is third and final part of short tutorial series on creating simple Phaser shooter game with Typescript. In Part 1 we ended with drone sprite hanging in the air above postapocalyptic city. In Part 2 we animated it and made it move.
 In this part we will add cannon, missiles and collisions with drones. To do this we have to check input and employ physics. We will use P2 physics engine.


Adding cannon


 First adjust your State class with adding some constants and private variables and also delete most of the create() method:

class State extends Phaser.State {

    private static CANNON_SPEED = 2;
    private static MISSILE_SPEED = 6;

    private _cannon: Phaser.Sprite;
    private _cannonTip: Phaser.Point = new Phaser.Point();

    private _space: Phaser.Key;

    // -------------------------------------------------------------------------
    preload() {
        // background image
        this.game.load.image("BG", "bg.jpg");
        // load sprite images in atlas
        this.game.load.atlas("Atlas", "atlas.png", "atlas.json");
    }

    // -------------------------------------------------------------------------
    create() {
        // background
        this.add.image(0, 0, "BG");

        // set physiscs to P2 physics engin
        this.game.physics.startSystem(Phaser.Physics.P2JS);
    }
}

 Next add new lines into create() method:

    create() {
        // background
        this.add.image(0, 0, "BG");

        // set physiscs to P2 physics engin
        this.game.physics.startSystem(Phaser.Physics.P2JS);

        // cannon - place it in the bottom center
        this._cannon = this.game.add.sprite(this.world.centerX, this.world.height, "Atlas", "cannon");
        // offset it from position
        this._cannon.anchor.setTo(-0.75, 0.5);
        // make it point straight up
        this._cannon.rotation = -Math.PI / 2;
        
        // cannon base - place over cannon, so it overlaps it
        var base = this.game.add.sprite(this.world.centerX, this.world.height, "Atlas", "base");
        base.anchor.setTo(0.5, 1);
    }

 The first line creates cannon barrel sprite and places it in the middle bootom. Next we adjust anchor of it as shown on this image:

 New anchor is point around which rotations will be done.
 Next, we are rotating it to point straight up. Rotation is -π/2, which may be confusing at first sight. From school we know, that 90 degrees is π/2. But in Phaser the y coordinate is flipped and y axis has values increasing downwards with 0, 0 in top left corner. Here are some values on unit circle (values in parenthesis are alternative values you can use - it does not matter if you rotate -π/2 or 3π/2). The red arc is showing our future limits for cannon movement from -π/4 to -3π/4:
 With last line we add cannon base sprite. This sprite covers part of the cannon barrel and it is static part of cannon.

 If you now compile and run you should see this construct in the bottom of the screen:



Moving cannon


 Now, let's move it. Add next few lines to create() method:

        //  Game input
        this.game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
        this.game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
        this._space = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        // following keys will not be propagated to browser
        this.game.input.keyboard.addKeyCapture([Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT, Phaser.Keyboard.SPACEBAR]);

 With this we say which keys we will use and we also prevent propagating presses of these keys to browser - it will be consumed by our game.

 Beside this we have to add update() method to our State class. This method is called every frame and we will check key presses in it:

    update() {
        // shortcut
        var keyboard: Phaser.Keyboard = this.game.input.keyboard;

        // left and right key
        if (keyboard.isDown(Phaser.Keyboard.LEFT)) {
            // calculate frame independent speed - 45 degrees (PI/4) in 1 second adjusted with cannon speed
            this._cannon.rotation -= this.time.elapsedMS * State.CANNON_SPEED / 1000 * (Math.PI / 4);
        } else if (keyboard.isDown(Phaser.Keyboard.RIGHT)) {
            this._cannon.rotation += this.time.elapsedMS * State.CANNON_SPEED / 1000 * (Math.PI / 4);
        } else if (this._space.justDown) {  // fire missile

            console.log("Fire missile");
        }
        
        // limit cannon rotation to left and right to +/- 45 degrees ... -135 to -45 degrees here
        this._cannon.rotation = Phaser.Math.clamp(this._cannon.rotation, -1.5 * Math.PI / 2, -0.5 * Math.PI / 2);
    }

 We check left and right key and if pressed (isDown()), then we adjust cannon rotation. The speed of rotation is π/4 in sec. by CANNON_SPEED, which is 2. So, cannon is rotation with speed π/2 in second.
 Space key is tested differently. We do not want to know, whether it is down, but whether it was pressed. If so, we will lunch missile. Currently, as we do not have missiles yet, we just lunch message to console.
 In the end we check whether cannon rotation is not beyond its limits. We use clamp method from Phaser.Math class for it. This method helps you to keep value between two limits with single line of code.


Swarm


 Now we have drone and moving cannon. Next, we will spawn swarm of drones. Our dron class is ready from previous part, so this will should be easy. Add few private variables to State class:

    private _drones: Phaser.Group;
    private _dronesCollisionGroup: Phaser.Physics.P2.CollisionGroup;
    private _missiles: Phaser.Group;
    private _missilesCollisionGroup: Phaser.Physics.P2.CollisionGroup;

 And add next lines to create method:

        // allow inpact events
        this.game.physics.p2.setImpactEvents(true);

        //  collision groups for drones
        this._dronesCollisionGroup = this.game.physics.p2.createCollisionGroup();
        //  collision groups for missiles
        this._missilesCollisionGroup = this.physics.p2.createCollisionGroup();


        // drones group
        this._drones = this.add.group();
        this._drones.physicsBodyType = Phaser.Physics.P2JS;
        this._drones.enableBody = true;

        // create 8 drones
        this._drones.classType = Dron;
        this._drones.createMultiple(8, "Atlas", "dron1");
        this._drones.forEach(function (aDron: Dron) {
            // setup movements and animations
            aDron.setUp();
            // setup physics
            var body: Phaser.Physics.P2.Body = aDron.body;
            body.setCircle(aDron.width / 2);
            body.kinematic = true; // does not respond to forces
            body.setCollisionGroup(this._dronesCollisionGroup);
            // adds group drones will collide with and callback
            body.collides(this._missilesCollisionGroup, this.hitDron, this);
            //body.debug = true;
        }, this);

 First, we are allowing impact events. Early we will also add missiles and we want to check collisions between them and drones. We will want P2 engine call our callback method when there is collision. If we forget to allow impact events our callback will not be called.

 Next, we define two collision groups. One for drones and second for missiles. This helps us easily check collisions between all drones and all missiles.

 For all the drones we create standard Phaser.Group. Setting physicsBodyType and enableBody on group means that these vales will be set on all sprites in this group. Our group contains 8 drones. We create them with call to createMultiple. As we are not creating standard sprites, but we want to create instances of our Dron class, which derives fro Phaser.Sprite, we first set classType to Dron.
 Once drones are created we take one by one and set them. setUp() method randomizes position and movement. In next lines we create its physics shape - circle fits nice to our drone. We also put it into prepared collision group, so each drone is in it and we can refer them all in once as _dronesCollisionGroup. Finally, we say that this drone can collide with _missiles CollisionGroup, which will group similarly all missiles. Part of this setting is callback method if collision occurs. In our case it is hitDron() method. We add it to our State class:

    private hitDron(aObject1: any, aObject2: any) {
        // explode dron and remove missile - kill it, not destroy
        (<Dron> aObject1.sprite).explode();
        (<Phaser.Sprite> aObject2.sprite).kill();
    }

 Callback method hitDrone() is called by P2 engine with two parameters - first is drone that collided and second is object it collided with. All we do, is let the drone explode and we kill missile. If you recall explode() method in our Drone class, you will remember that after explosion animation is finished, drone is killed too.


Missiles


 Similarly to drones, we add missiles in create() method:

        // missiles group
        this._missiles = this.add.group();
        this._missiles.physicsBodyType = Phaser.Physics.P2JS;
        this._missiles.enableBody = true;

        // create 10 missiles
        this._missiles.createMultiple(10, "Atlas", "missile");
        this._missiles.forEach(function (aMissile: Phaser.Sprite) {
            aMissile.anchor.setTo(0.5, 0.5);
            // physics
            var body: Phaser.Physics.P2.Body = aMissile.body;
            body.setRectangle(aMissile.width, aMissile.height);
            body.setCollisionGroup(this._missilesCollisionGroup);
            body.collides(this._dronesCollisionGroup);
            // body.debug = true;
        }, this);

 Only differences are: shape is not circle, but rectangle and we do not set collision callback here as it is enough if it is called from drone side once. It is enough to say that missiles can collide with all drones grouped in _dronesCollisionGroup.

 While you still can not fire missiles you can compile and run game. You see swarm of drones in the sky. If you would like to check whether you set collision bodies right, you can uncomment "body.debug = true;" when iterating drones and missiles and add this render() method to your State class:

    render() {
        // uncomment to visual debug, also uncommnet "body.debug = true;" when creating missiles and drones
        this._drones.forEach(function (aDron: Dron) {
            this.game.debug.body(aDron);
        }, this);

        this._missiles.forEach(function (aMissile: Phaser.Sprite) {
            this.game.debug.body(aMissile);
        }, this);
    }

 With these color debug circles all deadly drones now looks like jolly carnival balloons:


 And here is last and final piece - launching missiles. Go into update() method and replace console log with this code:

            // get firtst missile from pool
            var missile: Phaser.Sprite = this._missiles.getFirstExists(false);

            if (missile) {
                // calculate position of cannon tip. Put distance from cannon base along x axis and rotate it to cannon angle
                this._cannonTip.setTo(this._cannon.width * 2, 0);
                this._cannonTip.rotate(0, 0, this._cannon.rotation);

                missile.reset(this._cannon.x + this._cannonTip.x, this._cannon.y + this._cannonTip.y);
                (<Phaser.Physics.P2.Body> missile.body).rotation = this._cannon.rotation;
                // life of missile in millis
                missile.lifespan = 1500;
                // set velocity of missile in direction of cannon barrel
                (<Phaser.Physics.P2.Body> missile.body).velocity.x = this._cannonTip.x * State.MISSILE_SPEED;
                (<Phaser.Physics.P2.Body> missile.body).velocity.y = this._cannonTip.y * State.MISSILE_SPEED;
            }

 In first line we ask for free missile in group. It works like pool. When we created missiles, all of them were set exists = false. Now, we want to find first that does not exist, revive it and after it is killed (or its time expires), it falls into exists = false again.

 We check, whether we got any free missile. If yes, we calculate position on the tip of cannon barrel and set with reset() method position of missile. Calling reset sets exists = true. Rotation of the missile is the same as rotation of cannon. Lifetime of missile is limited to 1.5 second. If this time is expired, missile falls automatically into exists = false and is ready for reuse.


Conclusion


 If you compile and run now, you can move your cannon left to right with arrow keys. With space bar you can launch missiles and shoot drones.
 During tutorial we created very simple game in less than 240 lines - see full listing bellow or download whole project.
 While it is simple, it creates our Dron class derived from Phaser.Sprite, we use animations and custom tweening function, we handle input and also use P2 physics.

 Here is our final game in action:



Complete code:

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
class Game extends Phaser.Game {
    // -------------------------------------------------------------------------
    constructor() {
        // init game
        super(640, 400, Phaser.CANVAS, "content", State);
    }
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
class State extends Phaser.State {

    private static CANNON_SPEED = 2;
    private static MISSILE_SPEED = 6;

    private _cannon: Phaser.Sprite;
    private _cannonTip: Phaser.Point = new Phaser.Point();

    private _space: Phaser.Key;

    private _drones: Phaser.Group;
    private _dronesCollisionGroup: Phaser.Physics.P2.CollisionGroup;
    private _missiles: Phaser.Group;
    private _missilesCollisionGroup: Phaser.Physics.P2.CollisionGroup;

    // -------------------------------------------------------------------------
    preload() {
        // background image
        this.game.load.image("BG", "bg.jpg");
        // load sprite images in atlas
        this.game.load.atlas("Atlas", "atlas.png", "atlas.json");
    }

    // -------------------------------------------------------------------------
    create() {
        // background
        this.add.image(0, 0, "BG");

        // set physiscs to P2 physics engin
        this.game.physics.startSystem(Phaser.Physics.P2JS);

        // cannon - place it in the bottom center
        this._cannon = this.game.add.sprite(this.world.centerX, this.world.height, "Atlas", "cannon");
        // offset it from position
        this._cannon.anchor.setTo(-0.75, 0.5);
        // make it point straight up
        this._cannon.rotation = -Math.PI / 2;
        
        // cannon base - place over cannon, so it overlaps it
        var base = this.game.add.sprite(this.world.centerX, this.world.height, "Atlas", "base");
        base.anchor.setTo(0.5, 1);


        //  Game input
        this.game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
        this.game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
        this._space = this.game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        // following keys will not be propagated to browser
        this.game.input.keyboard.addKeyCapture([Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT, Phaser.Keyboard.SPACEBAR]);


        // allow inpact events
        this.game.physics.p2.setImpactEvents(true);

        //  collision groups for drones
        this._dronesCollisionGroup = this.game.physics.p2.createCollisionGroup();
        //  collision groups for missiles
        this._missilesCollisionGroup = this.physics.p2.createCollisionGroup();


        // drones group
        this._drones = this.add.group();
        this._drones.physicsBodyType = Phaser.Physics.P2JS;
        this._drones.enableBody = true;

        // create 8 drones
        this._drones.classType = Dron;
        this._drones.createMultiple(8, "Atlas", "dron1");
        this._drones.forEach(function (aDron: Dron) {
            // setup movements and animations
            aDron.setUp();
            // setup physics
            var body: Phaser.Physics.P2.Body = aDron.body;
            body.setCircle(aDron.width / 2);
            body.kinematic = true; // does not respond to forces
            body.setCollisionGroup(this._dronesCollisionGroup);
            // adds group drones will collide with and callback
            body.collides(this._missilesCollisionGroup, this.hitDron, this);
            //body.debug = true;
        }, this);

        // missiles group
        this._missiles = this.add.group();
        this._missiles.physicsBodyType = Phaser.Physics.P2JS;
        this._missiles.enableBody = true;

        // create 10 missiles
        this._missiles.createMultiple(10, "Atlas", "missile");
        this._missiles.forEach(function (aMissile: Phaser.Sprite) {
            aMissile.anchor.setTo(0.5, 0.5);
            // physics
            var body: Phaser.Physics.P2.Body = aMissile.body;
            body.setRectangle(aMissile.width, aMissile.height);
            body.setCollisionGroup(this._missilesCollisionGroup);
            body.collides(this._dronesCollisionGroup);
            // body.debug = true;
        }, this);
    }

    // -------------------------------------------------------------------------
    update() {
        // shortcut
        var keyboard: Phaser.Keyboard = this.game.input.keyboard;

        // left and right key
        if (keyboard.isDown(Phaser.Keyboard.LEFT)) {
            // calculate frame independent speed - 45 degrees (PI/4) in 1 second adjusted with cannon speed
            this._cannon.rotation -= this.time.elapsedMS * State.CANNON_SPEED / 1000 * (Math.PI / 4);
        } else if (keyboard.isDown(Phaser.Keyboard.RIGHT)) {
            this._cannon.rotation += this.time.elapsedMS * State.CANNON_SPEED / 1000 * (Math.PI / 4);
        } else if (this._space.justDown) {  // fire missile
            // get firtst missile from pool
            var missile: Phaser.Sprite = this._missiles.getFirstExists(false);

            if (missile) {
                // calculate position of cannon tip. Put distance from cannon base along x axis and rotate it to cannon angle
                this._cannonTip.setTo(this._cannon.width * 2, 0);
                this._cannonTip.rotate(0, 0, this._cannon.rotation);

                missile.reset(this._cannon.x + this._cannonTip.x, this._cannon.y + this._cannonTip.y);
                (<Phaser.Physics.P2.Body> missile.body).rotation = this._cannon.rotation;
                // life of missile in millis
                missile.lifespan = 1500;
                // set velocity of missile in direction of cannon barrel
                (<Phaser.Physics.P2.Body> missile.body).velocity.x = this._cannonTip.x * State.MISSILE_SPEED;
                (<Phaser.Physics.P2.Body> missile.body).velocity.y = this._cannonTip.y * State.MISSILE_SPEED;
            }
        }
        
        // limit cannon rotation to left and right to +/- 45 degrees ... -135 to -45 degrees here
        this._cannon.rotation = Phaser.Math.clamp(this._cannon.rotation, -1.5 * Math.PI / 2, -0.5 * Math.PI / 2);
    }

    // -------------------------------------------------------------------------
    render() {
        /*
        // uncomment to visual debug, also uncommnet "body.debug = true;" when creating missiles and drones
        this._drones.forEach(function (aDron: Dron) {
            this.game.debug.body(aDron);
        }, this);

        this._missiles.forEach(function (aMissile: Phaser.Sprite) {
            this.game.debug.body(aMissile);
        }, this);
        */
    }

    // -------------------------------------------------------------------------
    private hitDron(aObject1: any, aObject2: any) {
        // explode dron and remove missile - kill it, not destroy
        (<Dron> aObject1.sprite).explode();
        (<Phaser.Sprite> aObject2.sprite).kill();
    }
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
class Dron extends Phaser.Sprite {

    // -------------------------------------------------------------------------
    public setUp() {
        this.anchor.setTo(0.5, 0.5);

        // random position
        this.reset(this.game.rnd.between(40, 600), this.game.rnd.between(60, 150));

        // random movement range
        var range: number = this.game.rnd.between(60, 120);
        // random duration of complete move
        var duration: number = this.game.rnd.between(30000, 50000);
        // random parameters for wiggle easing function
        var xPeriod1: number = this.game.rnd.between(2, 13);
        var xPeriod2: number = this.game.rnd.between(2, 13);
        var yPeriod1: number = this.game.rnd.between(2, 13);
        var yPeriod2: number = this.game.rnd.between(2, 13);

        // set tweens for horizontal and vertical movement
        var xTween = this.game.add.tween(this.body)
        xTween.to({ x: this.position.x + range }, duration, function (aProgress: number) {
            return wiggle(aProgress, xPeriod1, xPeriod2);
        }, true, 0, -1);

        var yTween = this.game.add.tween(this.body)
        yTween.to({ y: this.position.y + range }, duration, function (aProgress: number) {
            return wiggle(aProgress, yPeriod1, yPeriod2);
        }, true, 0, -1);

        // define animations
        this.animations.add("anim", ["dron1", "dron2"], this.game.rnd.between(2, 5), true);
        this.animations.add("explosion", Phaser.Animation.generateFrameNames("explosion", 1, 6, "", 3));

        // play first animation as default
        this.play("anim");
    }

    // -------------------------------------------------------------------------
    public explode() {
        // remove movement tweens
        this.game.tweens.removeFrom(this.body);
        // explode dron and kill it on complete
        this.play("explosion", 8, false, true);
    }
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
function wiggle(aProgress: number, aPeriod1: number, aPeriod2: number): number {
    var current1: number = aProgress * Math.PI * 2 * aPeriod1;
    var current2: number = aProgress * Math.PI * 2 * aPeriod2;

    return Math.sin(current1) * Math.cos(current2);
}

// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
window.onload = () => {
    new Game();
};