Saturday, September 19, 2015

Mobile Income Report #14 - August 2015






previous parts
  Mobile Income Report #13 - July 2015
  Mobile Income Report #12 - June 2015
  Mobile Income Report #11 - May 2015
  Mobile Income Report #10 - April 2015
  Mobile Income Report #9 - March 2015
  Mobile Income Report #8 - January and February 2015
  Mobile Income Report #7 - December 2014
  Mobile Income Report #6 - November 2014
  Mobile Income Report #5 - October 2014 
  Mobile Income Report #4 - September 2014 
  Mobile Income Report #3 - August 2014
  Mobile Income Report #2 - July 2014
  Mobile Income Report #1 - June 2014
  Apps page - Portfolio (what are my assets?)


 If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.

 Under Apps page you can see my portfolio. It is list of the games that are then reported in Income Reports. The portfolio is regularly updated with new information (releases for new platforms, new updates, ...)


What I did in August

  • in August I continued work on our new HTML5 game, which will be match-3 game. Thanks to experience from our minimalistic Android/iOS match-3 game Flat Jewels Match 3 I had good start. Currently whole core mechanics are implemented and working together with system of level targets. We can ask players to:
    • achieve some score,
    • match X gems of given type (either threes or fours),
    • unlock any amount of treasure chests locked with lock and chains,
    • collect special items,
    • dig in sand covering board to find hidden treasures,
    • release gems from spider webs and gems frozen in ice cubes,
    • cut your way through jungle,
    • fight enemy ships, rescue friends, fight bosses
  • here you can see two screenshots from current progress:

  • ships on the second image are fully animated as during development of this game I made skeletal animations player for Phaser for animations exported from Spriter. I also wrote tutorial on this topic here. It opens great opportunities how to make game much better and attractive, while keeping code clean,
  • you can also note, that there are some numbers upside down on second image. These are score particles flying and rotating after gems match in funny directions. These are particles and BitmapText in the same time! Phaser has particle system, but unfortunately it did not meet my current needs, so I had to write my own. As a result I can easily make particles that are animated, contains another particle emitters, contains text and so on. With this I can spawn these score particles with "fire and forget" manner and I do not need to have prerendered numbers for all possible score values,
  • in August I wrote one more Phaser tutorial. It is easy trick how to make fake z-order in two moving groups. In fact z-order is real, all items are in one group, but are transformed as if they were in another group,
  • we continued also on our work in Unity on Futoshiki game. Game is almost finished. Now we have to test in-app purchases. This time I tried to implement Heyzap mediation for ads. Now I am exploring some ways how to optimize size of the build. Here are two screenshots:





Report

 Here are figures for paid apps in August:


 It remains more or less on the same level as July.

 Most of the income is from our brickbreaker Shards as usually.

 Free version with ads are here:

 There is increase by $50 compared to July. Most of the increase is from Chartboost ads and part is from AdMob.


 For August we have no earnings from HTML5 licences.

 Total income for August is $21,3 + $153,7 = $175. It is -84% decrease - mainly because no HTML5 license sales. But the match-3 game we are working on looks to be strong asset.


Next

 I hope we will finish and publish our new Unity version of Futoshiki. I will also continue work on our match-3 HTML5 game - all basic gameplay features are working and now we will need some level editor.




Saturday, September 5, 2015

Phaser tutorial: Breaking the (z-order) law!

 





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


 When building scene tree in Phaser engine the sprites added as last are rendered on top. Unlike, for example, in Unity, you cannot change order of sprites with setting its z position. You can only set z property and sort sprites within one group.

 Now, take a look at following example:


You can try to achieve this with:
  1.  making two groups (walls and gems) and tween them. But, in such case all gems will be under or above walls, depending on groups order,
  2. making one group with all the walls and gems, but to move them you will have to create 8 tweens.
 There is third way which allows you to put all sprites in one group (like in 2.) and transform gems and walls at once (like in 1.).

 To achieve it you have to create 3 groups: one for all the sprites and two empty. In group with sprites you will maintain your z order and empty groups will be tweened. Now comes the trick - sprites will not be transformed with their parent group, but walls will be transformed with on of the empty groups and gems with the second. In other words: when engine is transforming sprite, you give it group parent different from its original one.

 Source code for this example is short and self explanatory. Sprites are created and added to spritesGroup. All sprites are MySprite class objects and they are given another group they will use as their parent when updating transform. Two empty groups are named group1 and group2. These groups are then tweened.

 While the code is simple, the final effect looks like complicated pattern of sprites and groups.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
class Game extends Phaser.Game {
    // -------------------------------------------------------------------------
    constructor() {
        // init game
        super(640, 400, Phaser.CANVAS, "content", State);
    }
}

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

    private _parentTransform: Phaser.Group;

    // -------------------------------------------------------------------------
    constructor(aGame: Phaser.Game, aX: number, aY: number, aKey: string, aParentTransform: Phaser.Group) {
        super(aGame, aX, aY, aKey);
        this._parentTransform = aParentTransform;
    }

    // -------------------------------------------------------------------------
    public updateTransform(): void {
        if (!this.visible) {
            return;
        }

        this.displayObjectUpdateTransform(this._parentTransform);
    }
}

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

    // -------------------------------------------------------------------------
    preload() {
        // sprites
        this.load.image("Wall", "assets/Wall.png");
        this.load.image("Gem0", "assets/Gem0.png");
        this.load.image("Gem1", "assets/Gem1.png");
        this.load.image("Gem2", "assets/Gem2.png");
        this.load.image("Gem3", "assets/Gem3.png");
    }

    // -------------------------------------------------------------------------
    create() {
        this.stage.backgroundColor = 0x0F3043;

        var group1 = this.add.group();
        var group2 = this.add.group();

        var spritesGroup = this.add.group();

        for (var i = 0; i < 4; i++) {
            // wall sprite
            var wall = new MySprite(this.game, 50, 90 + i * 70, "Wall", group1);
            wall.width = 440;
            wall.z = i * 2;
            spritesGroup.add(wall);

            // gem sprite
            var gem = new MySprite(this.game, 170 + 100 * i, 50, "Gem" + i, group2);
            gem.anchor.setTo(0.5, 0.5);
            gem.z = i * 2 + 1;
            spritesGroup.add(gem);
        }

        // move groups
        this.add.tween(group1).to({ x: 100 }, 1000, Phaser.Easing.Sinusoidal.InOut, true, 0, -1, true);
        this.add.tween(group2).to({ y: 320 }, 3000, Phaser.Easing.Linear.None, true, 0, -1, true);
    }
}

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






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.