tag:blogger.com,1999:blog-40611838753752412562024-03-19T01:48:46.487-07:00Mobile Games DevelopmentFocus on HTML5 game development with Phaser and Typescript and on Unity game development. Tutorials and practical how-to guides as well as regular indie developer income reports.
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.comBlogger102125tag:blogger.com,1999:blog-4061183875375241256.post-71269620568059020832020-01-11T07:59:00.002-08:002020-01-11T08:09:36.122-08:00We moved...<br />
<br />
<span style="font-size: large;"><b>Hi all, we moved to new site: <a href="http://sbcgames.io/">sbcgames.io</a></b></span><br />
<br />
<br />
<br />
<br />
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.comtag:blogger.com,1999:blog-4061183875375241256.post-63613844659848377082017-12-05T09:43:00.001-08:002017-12-05T09:43:32.754-08:00Shards at Yahoo! Japan<div class="g-plusone" style="text-align: center;">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<br />
<div style="text-align: left;">
<span style="text-align: justify;"> On 28th November our game Shards was published at </span><a href="https://games.yahoo.co.jp/play/" style="text-align: justify;">Yahoo! Japan</a><span style="text-align: justify;">. Game was published by </span><a href="http://www.wkb.jp/en/" style="text-align: justify;">Worker Bee Inc.</a><span style="text-align: justify;"> and you can play it on their site </span><a href="http://games.wkb.jp/ykg/?game_id=shards" style="text-align: justify;">here</a><span style="text-align: justify;">.</span></div>
<div style="text-align: left;">
<span style="text-align: justify;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-cwVxdSMAd8o/WibasRnklDI/AAAAAAAACdw/_A321EMB5TYDi-bTJuQ3RTqeedz8s04SwCLcBGAs/s1600/Shards_Yahoo_Japan.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="635" data-original-width="952" height="426" src="https://2.bp.blogspot.com/-cwVxdSMAd8o/WibasRnklDI/AAAAAAAACdw/_A321EMB5TYDi-bTJuQ3RTqeedz8s04SwCLcBGAs/s640/Shards_Yahoo_Japan.jpg" width="640" /></a></div>
<div style="text-align: left;">
<span style="text-align: justify;"><br /></span></div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com10tag:blogger.com,1999:blog-4061183875375241256.post-43745721640221533152017-09-30T09:48:00.000-07:002017-10-02T08:47:59.335-07:00Unity tutorial: Optimize removes from List<div class="g-plusone" style="text-align: center;">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This is how code for method<a href="https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,877"> List.RemoveAt()</a> looks:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">void</span> <span style="color: #a6e22e;">RemoveAt</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">index)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">((</span><span style="color: #66d9ef;">uint</span><span style="color: #f8f8f2;">)index</span> <span style="color: #f8f8f2;">>=</span> <span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">uint</span><span style="color: #f8f8f2;">)_size)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">ThrowHelper.ThrowArgumentOutOfRangeException();</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">Contract.EndContractBlock();</span>
<span style="color: #f8f8f2;">_size--;</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(index</span> <span style="color: #f8f8f2;"><</span> <span style="color: #f8f8f2;">_size)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">Array.Copy(_items,</span> <span style="color: #f8f8f2;">index</span> <span style="color: #f8f8f2;">+</span> <span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">,</span> <span style="color: #f8f8f2;">_items,</span> <span style="color: #f8f8f2;">index,</span> <span style="color: #f8f8f2;">_size</span> <span style="color: #f8f8f2;">-</span> <span style="color: #f8f8f2;">index);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">_items[_size]</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">default</span><span style="color: #f8f8f2;">(T);</span>
<span style="color: #f8f8f2;">_version++;</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
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:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">System.Collections.Generic;</span>
<span style="color: #66d9ef;">using</span> <span style="color: #f8f8f2;">UnityEngine;</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">static</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">ListExtensions</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">static</span> <span style="color: #66d9ef;">void</span> <span style="color: #f8f8f2;">FastRemoveAt<T>(</span><span style="color: #66d9ef;">this</span> <span style="color: #f8f8f2;">IList<T></span> <span style="color: #f8f8f2;">list,</span> <span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">index)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// fast remove swaps item to remove with last item and then removes it</span>
<span style="color: #75715e;">// it should avoid internal Array.Copy, but changes order of items in List</span>
<span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">lastIndex</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">list.Count</span> <span style="color: #f8f8f2;">-</span> <span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f8f8f2;">T</span> <span style="color: #f8f8f2;">tmp</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">list[index];</span>
<span style="color: #f8f8f2;">list[index]</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">list[lastIndex];</span>
<span style="color: #f8f8f2;">list[lastIndex]</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">tmp;</span>
<span style="color: #f8f8f2;">list.RemoveAt(lastIndex);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
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:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// test</span>
<span style="color: #f8f8f2;">Debug.Log(</span><span style="color: #e6db74;">"========================================="</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">var</span> <span style="color: #f8f8f2;">startTime</span> <span style="color: #f8f8f2;">=</span> <span style="color: #f8f8f2;">Time.realtimeSinceStartup;</span>
<span style="color: #66d9ef;">var</span> <span style="color: #f8f8f2;">list</span> <span style="color: #f8f8f2;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #f8f8f2;">List<</span><span style="color: #66d9ef;">int</span><span style="color: #f8f8f2;">>();</span>
<span style="color: #66d9ef;">var</span> <span style="color: #f8f8f2;">val</span> <span style="color: #f8f8f2;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">for</span> <span style="color: #f8f8f2;">(;</span> <span style="color: #f8f8f2;">val</span> <span style="color: #f8f8f2;"><</span> <span style="color: #ae81ff;">100000</span><span style="color: #f8f8f2;">;</span> <span style="color: #f8f8f2;">val++)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #f8f8f2;">list.Add(val);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">for</span> <span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">int</span> <span style="color: #f8f8f2;">i</span> <span style="color: #f8f8f2;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span> <span style="color: #f8f8f2;">i</span> <span style="color: #f8f8f2;"><</span> <span style="color: #ae81ff;">1000000</span><span style="color: #f8f8f2;">;</span> <span style="color: #f8f8f2;">i++)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">//list.RemoveAt(0);</span>
<span style="color: #f8f8f2;">list.FastRemoveAt(</span><span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">);</span>
<span style="color: #f8f8f2;">list.Add(val++);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">Debug.Log(</span><span style="color: #e6db74;">"Time taken = "</span> <span style="color: #f8f8f2;">+</span> <span style="color: #f8f8f2;">(Time.realtimeSinceStartup</span> <span style="color: #f8f8f2;">-</span> <span style="color: #f8f8f2;">startTime));</span>
<span style="color: #f8f8f2;">Debug.Log(</span><span style="color: #e6db74;">"========================================="</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
With both methods RemoveAt() and FastRemoveAt() I got these results for various number of updates:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-BBycy51OPT0/Wc_IfYl7NJI/AAAAAAAACZg/dlwo4RQ14QQ3sMrGiP3Rlzd5CiDgixL_QCPcBGAYYCw/s1600/List_removes_test.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="123" data-original-width="316" src="https://4.bp.blogspot.com/-BBycy51OPT0/Wc_IfYl7NJI/AAAAAAAACZg/dlwo4RQ14QQ3sMrGiP3Rlzd5CiDgixL_QCPcBGAYYCw/s1600/List_removes_test.png" /></a></div>
<br />
As you can see, FastRemoveAt() is much faster then RemoveAt().<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com13tag:blogger.com,1999:blog-4061183875375241256.post-82055502219439913602017-09-17T01:16:00.000-07:002017-09-17T01:23:04.648-07:00Pirates! - the match 3 made it into Apple AppStore<div class="g-plusone" style="text-align: center;">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/--iw7CoWF6sY/Wb4s3iA2MNI/AAAAAAAACY0/4K-gdgOkC3sSTohjQZ1SnJY2jOuYuFK3ACEwYBhgL/s1600/Pirates_1024x500.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="500" data-original-width="1024" height="312" src="https://3.bp.blogspot.com/--iw7CoWF6sY/Wb4s3iA2MNI/AAAAAAAACY0/4K-gdgOkC3sSTohjQZ1SnJY2jOuYuFK3ACEwYBhgL/s640/Pirates_1024x500.jpg" width="640" /></a></div>
<br />
<div style="text-align: justify;">
Our game Pirates! - the match 3 is finally finished and its iOS version just made it into Apple AppStore. You can get it here:<br />
<br /></div>
<div style="text-align: center;">
<a href="https://itunes.apple.com/us/app/pirates-the-match-3/id1282267161?mt=8" style="background-size: contain; background: url("//linkmaker.itunes.apple.com/assets/shared/badges/en-us/appstore-lrg.svg") no-repeat; display: inline-block; height: 40px; overflow: hidden; width: 135px;"></a>
</div>
<br />
<div style="text-align: justify;">
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 <a href="http://www.littlecolor.com/">Tomáš Kopecký</a> and music was composed by Juraj Růžička from <a href="https://audiojungle.net/user/soundrosestudio">SoundRoseStudio</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-rga20OLDHSQ/Wb4s35_pIpI/AAAAAAAACZI/LYalJwPY6hAnya6xw_9ALEG5oz39CTx2wCEwYBhgL/s1600/Pirates_screenshot_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="546" data-original-width="410" height="320" src="https://4.bp.blogspot.com/-rga20OLDHSQ/Wb4s35_pIpI/AAAAAAAACZI/LYalJwPY6hAnya6xw_9ALEG5oz39CTx2wCEwYBhgL/s320/Pirates_screenshot_1.jpg" width="240" /></a><a href="https://4.bp.blogspot.com/-IggxQq6GSz8/Wb4s3x_k51I/AAAAAAAACZI/RtpMUKnehbUJJ-3zZUkVPNC_PBM6svp9ACEwYBhgL/s1600/Pirates_screenshot_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="546" data-original-width="410" height="320" src="https://4.bp.blogspot.com/-IggxQq6GSz8/Wb4s3x_k51I/AAAAAAAACZI/RtpMUKnehbUJJ-3zZUkVPNC_PBM6svp9ACEwYBhgL/s320/Pirates_screenshot_2.jpg" width="240" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-al7K3hJu5Z8/Wb4s4E9u22I/AAAAAAAACZI/r8PsAOQbpJU-saGAYPBV0WegL84wRdaQACEwYBhgL/s1600/Pirates_screenshot_3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="546" data-original-width="410" height="320" src="https://1.bp.blogspot.com/-al7K3hJu5Z8/Wb4s4E9u22I/AAAAAAAACZI/r8PsAOQbpJU-saGAYPBV0WegL84wRdaQACEwYBhgL/s320/Pirates_screenshot_3.jpg" width="240" /></a><a href="https://4.bp.blogspot.com/-5unwo0p3d6M/Wb4s4XevGoI/AAAAAAAACZI/fVAJOhq3rDosDMYgOE5cwzCkEAUTNb6zQCEwYBhgL/s1600/Pirates_screenshot_4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="546" data-original-width="410" height="320" src="https://4.bp.blogspot.com/-5unwo0p3d6M/Wb4s4XevGoI/AAAAAAAACZI/fVAJOhq3rDosDMYgOE5cwzCkEAUTNb6zQCEwYBhgL/s320/Pirates_screenshot_4.jpg" width="240" /></a></div>
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com3tag:blogger.com,1999:blog-4061183875375241256.post-62085162844395793132017-09-17T00:52:00.003-07:002017-09-17T00:52:42.125-07:00Flat Jewels Match 3 at Yahoo! Japan<div class="g-plusone" style="text-align: center;">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<div style="text-align: justify;">
On 11th September our game Flat Jewels Match 3 was published at <a href="https://games.yahoo.co.jp/play/">Yahoo! Japan</a>. Game was published by <a href="http://www.wkb.jp/en/">Worker Bee Inc.</a> and you can play it on their site <a href="http://games.wkb.jp/ykg/?game_id=flatjewelslevels">here</a>.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://games.wkb.jp/ykg/?game_id=flatjewelslevels"><img alt="http://games.wkb.jp/ykg/?game_id=flatjewelslevels" border="0" data-original-height="732" data-original-width="814" height="574" src="https://4.bp.blogspot.com/-RRx6HwQkOKA/Wb4olDsxYKI/AAAAAAAACYo/IwsRf7bpLegPmjjQpEumSLD-neFPcU8cgCPcBGAYYCw/s640/FJM3_Yahoo_Japan.jpg" width="640" /> </a></div>
<br />
<br />
<br /></div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-72590413002851498832017-07-12T23:53:00.000-07:002017-07-12T23:53:37.759-07:00Fruit Dating at Yahoo! Japan<div class="g-plusone" style="text-align: center;">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<div style="text-align: justify;">
Our logical puzzle game Fruit Dating was published at <a href="https://games.yahoo.co.jp/play/">Yahoo! Japan</a> today. It was published by <a href="http://www.wkb.jp/en/">Worker Bee Inc.</a> and you can play it <a href="http://games.wkb.jp/ykg/?game_id=fruitdating">here</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-4NZdIL8VoMo/WWcXL31nLtI/AAAAAAAACXE/6401EfbOPoQjCzDWSyenBo8u6XWzpjhFQCPcBGAYYCw/s1600/FD.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="869" data-original-width="799" height="640" src="https://3.bp.blogspot.com/-4NZdIL8VoMo/WWcXL31nLtI/AAAAAAAACXE/6401EfbOPoQjCzDWSyenBo8u6XWzpjhFQCPcBGAYYCw/s640/FD.jpg" width="587" /></a></div>
<br /></div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com2tag:blogger.com,1999:blog-4061183875375241256.post-82674927220795540352017-06-30T13:02:00.004-07:002017-06-30T13:02:51.615-07:00Shards available in Windows Store<div class="g-plusone" style="text-align: center;">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<br />
<div style="text-align: justify;">
<a href="https://1.bp.blogspot.com/-PpTNIYvnae0/WVasapvj8yI/AAAAAAAACWs/VuoO-iPbCPAyzmOVTQvZuMY0D4GROlgwwCLcBGAs/s1600/Shards.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="270" data-original-width="180" src="https://1.bp.blogspot.com/-PpTNIYvnae0/WVasapvj8yI/AAAAAAAACWs/VuoO-iPbCPAyzmOVTQvZuMY0D4GROlgwwCLcBGAs/s1600/Shards.jpg" /></a> Shards - the brickbreaker is now available in Microsoft's Windows Store as UWP aplication for Windows 10 phones.<br />
<br />
</div>
<div style="height: 600px; text-align: center; width: 1000px;">
<a href="https://www.microsoft.com/store/apps/9nmrnnrc33ps?ocid=badge"><img alt="Get it on Windows 10" height="72" src="https://assets.windowsphone.com/f2f77ec7-9ba9-4850-9ebe-77e366d08adc/English_Get_it_Win_10_InvariantCulture_Default.png" width="200" /></a>
</div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com1tag:blogger.com,1999:blog-4061183875375241256.post-13034865301700174972017-06-29T07:44:00.000-07:002017-06-29T07:50:26.214-07:00Shards and Fruit Dating is available on Tizen Store<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<div style="text-align: justify;">
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!</div>
<br />
<br />
<a href="http://www.tizenstore.com/main/getDetail.as?Id=com.sbcgames.shards"><b>Shards</b></a><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.tizenstore.com/main/getDetail.as?Id=com.sbcgames.shards"><img alt="Shards at Tizen Store" border="0" data-original-height="520" data-original-width="699" src="https://4.bp.blogspot.com/-LlLxEh1kJFA/WVURvLkNPNI/AAAAAAAACWY/2VPUicSq4Pcxt3VejuWAl2z4lKfrjsRSwCLcBGAs/s1600/Shards_Tizen.jpg" /></a></div>
<br />
<br />
<br />
<br />
<a href="http://www.tizenstore.com/main/getDetail.as?Id=com.sbcgames.fruitdating"><b>Fruit Dating</b></a><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.tizenstore.com/main/getDetail.as?Id=com.sbcgames.fruitdating"><img alt="Fruit Dating at Tizen Store" border="0" data-original-height="407" data-original-width="700" src="https://2.bp.blogspot.com/-YITwZWf5z6w/WVURvLK8EhI/AAAAAAAACWc/JW9qbFSn5a0xgqEFuTa8fCvc6MJIxB9EQCEwYBhgL/s1600/FruitDating_Tizen.jpg" /></a></div>
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com3tag:blogger.com,1999:blog-4061183875375241256.post-54325318748918080302017-04-19T09:48:00.000-07:002017-04-19T09:48:21.615-07:00New games released: Elsa Jewels, JumpTuber and Brick Stacker<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<div style="text-align: justify;">
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.</div>
<br />
<br />
<h4>
Elsa Jewels</h4>
<br />
<div style="text-align: justify;">
Elsa Jewels was exclusively made for Famobi. It features popular Disney's characters - Anna and Elsa from Frozen. And yes, Olaf is there too!</div>
<div style="text-align: justify;">
You can play the game <span id="goog_1305145444"></span><a href="https://play.famobi.com/disney-jewels">here<span id="goog_1305145445"></span></a>.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-BeD3LYaMxDg/WPeRa-yMS5I/AAAAAAAACU0/FrN3avxuDiIVuutww-lD09L3BfQc2uGUgCLcB/s1600/ElsaJewels.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/-BeD3LYaMxDg/WPeRa-yMS5I/AAAAAAAACU0/FrN3avxuDiIVuutww-lD09L3BfQc2uGUgCLcB/s400/ElsaJewels.jpg" width="248" /></a><a href="https://2.bp.blogspot.com/-ZuOAJL5_uKA/WPeRa8XmpTI/AAAAAAAACU4/wScW27CMxis6jQ3W7fL9mHWFBAJHAaqDQCLcB/s1600/ElsaJewels2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-ZuOAJL5_uKA/WPeRa8XmpTI/AAAAAAAACU4/wScW27CMxis6jQ3W7fL9mHWFBAJHAaqDQCLcB/s400/ElsaJewels2.jpg" width="248" /></a></div>
<br />
<br />
<br />
<h4>
JumpTuber</h4>
<br />
<div style="text-align: justify;">
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 <a href="http://www.gameeapp.com/game/YFFGD9Q">here</a>.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-6jsZNJESbXA/WPeRdSYJ8AI/AAAAAAAACVM/oN7NBU4XFNAVh9ktBylzyIrw5sy8zPAsQCEw/s1600/JirkKral01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/-6jsZNJESbXA/WPeRdSYJ8AI/AAAAAAAACVM/oN7NBU4XFNAVh9ktBylzyIrw5sy8zPAsQCEw/s400/JirkKral01.jpg" width="237" /></a><a href="https://2.bp.blogspot.com/-UIllo6M2xEs/WPeRddvPQAI/AAAAAAAACVM/D7YPuZy_pu8lqayg770_yMjTH3m8Ua3FwCEw/s1600/JirkKral02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-UIllo6M2xEs/WPeRddvPQAI/AAAAAAAACVM/D7YPuZy_pu8lqayg770_yMjTH3m8Ua3FwCEw/s400/JirkKral02.jpg" width="237" /></a></div>
<br />
<br />
<br />
<h4>
Brick Stacker</h4>
<br />
<div style="text-align: justify;">
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 <a href="http://www.gameeapp.com/game/zxyM4Kb">here</a> (it is the best to play it on some device with portrait screen).</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-H7wlGx7tIxU/WPeRdZOoN_I/AAAAAAAACVM/KLM2OyLMANcaIV8wiZt9cdqd-LIbF0aNACEw/s1600/BrickStacker01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-H7wlGx7tIxU/WPeRdZOoN_I/AAAAAAAACVM/KLM2OyLMANcaIV8wiZt9cdqd-LIbF0aNACEw/s320/BrickStacker01.jpg" width="320" /></a><a href="https://4.bp.blogspot.com/-UepgnObpkhE/WPeRdN7rVcI/AAAAAAAACVM/1Hp6LOuE6MU2uIvXxQQhtbM47ttWpXrmwCEw/s1600/BrickStacker02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-UepgnObpkhE/WPeRdN7rVcI/AAAAAAAACVM/1Hp6LOuE6MU2uIvXxQQhtbM47ttWpXrmwCEw/s320/BrickStacker02.jpg" width="320" /></a></div>
<br />
<div style="text-align: justify;">
<br /></div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-28151789565210803092017-01-23T09:38:00.003-08:002017-04-19T09:13:56.145-07:00Phaser tutorial: How to balance random booleans for game<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>Previous Phaser tutorials and articles:</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/07/phaser-tutorial-fun-with-bitmap-fonts.html">Phaser tutorial: Fun with bitmap fonts</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/phaser-tutorial-using-spriter-player.html">Phaser tutorial: Using Spriter player for Phaser</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-tutorial-merging-fonts-into.html">Phaser tutorial: Merging fonts into sprite atlas</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-typescript-defs-for-phaser-box2d.html">Phaser: Typescript defs for Phaser Box2D plugin</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/phaser-tutorial-spriter-pro-features.html">Phaser tutorial: Spriter Pro features added to Spriter player for Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/phaser-tutorial-using-phaser-signals.html">Phaser tutorial: Using Phaser signals</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-breaking-z-order-law.html">Phaser tutorial: Breaking the (z-order) law!</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-phaser-and-spriter.html">Phaser tutorial: Phaser and Spriter skeletal animation</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_23.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 3</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_9.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 2</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-adding-9-patch-image.html">Phaser tutorial: adding 9-patch image support to Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 1</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-custom-easing-functions.html">Phaser tutorial: custom easing functions for tweening and easing functions with parameters</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-sprites-and-custom.html">Phaser tutorial: sprites and custom properties for atlas frames</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-manage-different-screen.html">Phaser tutorial: manage different screen sizes</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/02/phaser-tutorial-how-to-wrap-bitmap-text.html">Phaser tutorial: How to wrap bitmap text</a><br />
<br />
<br />
<h4>
Introduction</h4>
<div style="text-align: justify;">
<br />
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.<br />
Fast fix may be to add some counters to check if not too many obstacles is on one or other side.<br />
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."</div>
<br />
<br />
<h4>
Solution</h4>
<br />
So, I decided to solve it once and forever with small class, which I named RandomBooleanBalancer. Here is complete code for it in TypeScript:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">namespace Helper {
<span style="color: blue;">export</span> <span style="color: blue;">class</span> RandomBooleanBalancer {
<span style="color: blue;">private</span> _rnd: <span style="color: #2b91af;">Phaser.RandomDataGenerator</span>;
<span style="color: blue;">private</span> _lbound: <span style="color: #2b91af;">number</span>;
<span style="color: blue;">private</span> _ubound: <span style="color: #2b91af;">number</span>;
<span style="color: blue;">private</span> _currentBalance: <span style="color: #2b91af;">number</span>;
<span style="color: green;">// -------------------------------------------------------------------------</span>
<span style="color: green;">// balancer - how many consecutive same values maximally</span>
<span style="color: blue;">public</span> <span style="color: blue;">constructor</span>(rnd: <span style="color: #2b91af;">Phaser.RandomDataGenerator</span>, balancer: <span style="color: #2b91af;">number</span>) {
<span style="color: blue;">this</span>._rnd = rnd;
<span style="color: blue;">this</span>.reset(balancer);
}
<span style="color: green;">// -------------------------------------------------------------------------</span>
<span style="color: blue;">public</span> reset(balancer: <span style="color: #2b91af;">number</span>): <span style="color: blue;">void</span> {
--balancer;
<span style="color: blue;">let</span> lbound = Math.ceil(balancer / 2);
<span style="color: blue;">this</span>._lbound = -lbound;
<span style="color: blue;">this</span>._ubound = balancer - lbound;
<span style="color: blue;">this</span>._currentBalance = balancer === 0 ? <span style="color: blue;">this</span>._rnd.integerInRange(-1, 0) : 0;
}
<span style="color: green;">// -------------------------------------------------------------------------</span>
<span style="color: blue;">public</span> getBoolean(): <span style="color: blue;">boolean</span> {
<span style="color: blue;">let</span> result = <span style="color: blue;">this</span>._currentBalance + <span style="color: blue;">this</span>._rnd.integerInRange(<span style="color: blue;">this</span>._lbound, <span style="color: blue;">this</span>._ubound);
<span style="color: green;">//console.log("lbound = " + (this._lbound + this._currentBalance) + ", ubound = " + (this._ubound + this._currentBalance) +</span>
<span style="color: green;">// ", currentBalance = " + this._currentBalance + ", value = " + (result >= 0));</span>
<span style="color: blue;">this</span>._currentBalance += result >= 0 ? -1 : <span style="color: #2b91af;">1</span>;
<span style="color: blue;">return</span> result >= 0;
}
}
}
</pre>
</div>
<br />
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For example, if you want true or false maximally two times after each other, then set it to 2.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
reset() method allows you to change this request during runtime. </div>
<div style="text-align: justify;">
</div>
<br />
<br />
<h4>
Test</h4>
<div style="text-align: justify;">
<br />
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:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: blue;">let</span> randomBalancer = <span style="color: blue;">new</span> Helper.RandomBooleanBalancer(<span style="color: blue;">this</span>.rnd, 1);
<span style="color: blue;">let</span> result = <span style="color: #a31515;">""</span>;
<span style="color: blue;">for</span> (<span style="color: blue;">let</span> i = 0; i < 50; i++) {
result += (randomBalancer.getBoolean() ? <span style="color: #a31515;">"1"</span> : <span style="color: #a31515;">"0"</span>) + (i < 50 - 1 ? <span style="color: #a31515;">", "</span> : <span style="color: #a31515;">""</span>);
}
console.log(result);
</pre>
</div>
<div style="text-align: justify;">
<br />
Here is output from console:<br />
<br />
<span style="color: orange;"><span style="font-family: "courier new" , "courier" , monospace;">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</span></span></div>
<div style="text-align: justify;">
<br />
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.<br />
<br />
Now, change number in constructor to 2 and run the test again. This is console output:</div>
<div style="text-align: justify;">
<br />
<span style="color: orange;"><span style="font-family: "courier new" , "courier" , monospace;">0, 1, 0, 1, 0, 1, 0, <b><span style="color: #b45f06;">1, 1, 0, 0, 1, 1, 0, 0</span></b>, 1, 0, 1, 0, <span style="color: #b45f06;"><b>1, 1</b></span>, 0, 1, 0, 1, 0, 1, <span style="color: #b45f06;"><b>0, 0</b></span>, 1, 0, <b><span style="color: #b45f06;">1, 1</span></b>, 0, 1, 0, 1, 0, 1, 0, 1, <span style="color: #b45f06;"><b>0, 0, 1, 1, 0, 0</b></span>, 1, 0, 1</span></span><br />
<br />
As you can see, returned values are random, but you get maximally two randoms of the same value after each other.<br />
<br />
Now, change requested value in constructor to 5. You may get something like this:<br />
<br />
<span style="color: orange;"><span style="font-family: "courier new" , "courier" , monospace;">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</span></span></div>
<br />
<div style="text-align: justify;">
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".</div>
<br />
<br />
<h4>
Conclusion</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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.</div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-42642383286329231802017-01-23T07:58:00.000-08:002017-01-23T07:58:14.548-08:00Mobile Income Report #30 - December 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/12/mobile-income-report-29-november-2016.html">Mobile Income Report #29 - November 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/11/mobile-income-report-28-october-2016.html">Mobile Income Report #28 - October 2016</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/10/mobile-income-report-27-september-2016.html">Mobile Income Report #27 - September 2016</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/09/mobile-income-report-26-august-2016.html">Mobile Income Report #26 - August 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/08/mobile-income-report-25-july-2016.html">Mobile Income Report #25 - July 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/07/mobile-income-report-24-june-2016.html">Mobile Income Report #24 - June 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/06/mobile-income-report-23-may-2016.html">Mobile Income Report #23 - May 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<br />
:<br />
: <br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<br />
<br />
<h4>
What I did in December</h4>
<ul style="text-align: justify;">
<li>as usual, I was working on client projects. One of them, one-button game Little Plane, was already published at <a href="https://www.gameeapp.com/game/5IsYwla">Gamee</a>: </li>
</ul>
<div style="text-align: center;">
<a href="https://4.bp.blogspot.com/-eJp4OfWNzos/WIYeRbbK56I/AAAAAAAACSg/NXDwe7Mc-o4HKXba9rd9vfGV5rTZMZ8-ACLcB/s1600/LittlePlane2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-eJp4OfWNzos/WIYeRbbK56I/AAAAAAAACSg/NXDwe7Mc-o4HKXba9rd9vfGV5rTZMZ8-ACLcB/s320/LittlePlane2.jpg" width="320" /></a><a href="https://3.bp.blogspot.com/-vOqkUu3A_jo/WIYeRC0cqqI/AAAAAAAACSY/Te7Zmnkv6Tg65chMk3RIS1F1fi79lxYCwCLcB/s1600/LittlePlane1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-vOqkUu3A_jo/WIYeRC0cqqI/AAAAAAAACSY/Te7Zmnkv6Tg65chMk3RIS1F1fi79lxYCwCLcB/s320/LittlePlane1.jpg" width="320" /></a></div>
<br />
<ul style="text-align: justify;">
<li>worked on both Unity and HTML5 version of our match-3 game Pirates! 58 of 62 levels in world 1 are finished and we are doing finishing touches like adding more particle effects. Our friend Juraj from <a href="https://audiojungle.net/user/soundrosestudio">SoundRose studio</a> made music tracks for game and is now working on sound effects.</li>
</ul>
<span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"></span></span></span></span></span></span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-Rsxgoog5Og4/WIYeRozVE6I/AAAAAAAACSs/-xaUgCtw8Z4ifLX4dIXoV0OXU-nSRwUXwCEw/s1600/Pirates_title.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://1.bp.blogspot.com/-Rsxgoog5Og4/WIYeRozVE6I/AAAAAAAACSs/-xaUgCtw8Z4ifLX4dIXoV0OXU-nSRwUXwCEw/s400/Pirates_title.jpg" width="250" /></a><a href="https://1.bp.blogspot.com/-Qa97cN2T8LM/WIYeRnRe-uI/AAAAAAAACSs/5chPBezMzwQb2P_Yk8dw715i0mN8s-xiwCEw/s1600/Pirates_game.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://1.bp.blogspot.com/-Qa97cN2T8LM/WIYeRnRe-uI/AAAAAAAACSs/5chPBezMzwQb2P_Yk8dw715i0mN8s-xiwCEw/s400/Pirates_game.jpg" width="250" /></a></div>
<div style="margin-left: 1em; margin-right: 1em;">
</div>
<br />
<div style="text-align: center;">
<span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"><span style="color: #0000ee;"></span></span></span></span></span></span></div>
<ul style="text-align: justify;">
<li>my book <span id="goog_98085069"></span><a href="https://gumroad.com/l/CZuhn"> "Create procedural endless runner in Phaser with<span id="goog_98085072"></span><span id="goog_98085073"></span> TypeScript"<span id="goog_98085070"></span></a> crossed first 100 of sales.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://gumroad.com/l/CZuhn"><img alt="Create procedural endless runner in Phaser with TypeScript" border="0" height="400" src="https://2.bp.blogspot.com/-AvpAeUJWbZE/V-Kh6o3pHhI/AAAAAAAACMU/SY4jpy_d1kYpg81w0gX3FDgIrAjWiEBCgCPcB/s400/Book_new_350.png" width="315" /></a></div>
<br />
<br />
<br />
<br />
<h4>
Report</h4>
<br />
<div style="text-align: justify;">
As already announced in November, this is last income report. I decided to end it, because it started as income report from mobile
games, but it is more and more about HTML5 games as income from mobile
ones is still pretty low. Picking such a small figures from many
internet consoles is boring and time consuming. I decided to invest saved time into
writing more tutorials and technical articles.</div>
<br />
Figures for December are here:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-iVQTcgspPcM/WIYlAxbtL3I/AAAAAAAACS8/BxWNB_zRjq4LfProYqmN880sItPacoFlwCEw/s1600/2016_December_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-iVQTcgspPcM/WIYlAxbtL3I/AAAAAAAACS8/BxWNB_zRjq4LfProYqmN880sItPacoFlwCEw/s1600/2016_December_table.png" /></a></div>
<br />
<div style="text-align: justify;">
There is again decrease compared to November ($107,3). But, as I already said in past, I did nothing with this my mobile portfolio for very long time. I hope this will change in 2017 as I plan to focus more on Unity and spread my time between it and Phaser. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-Incmx-QaRUM/WIYlA68RXII/AAAAAAAACS4/Balb2X3XR_wG8EfuFPxhGBMlni77fDkiQCEw/s1600/2016_December_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-Incmx-QaRUM/WIYlA68RXII/AAAAAAAACS4/Balb2X3XR_wG8EfuFPxhGBMlni77fDkiQCEw/s1600/2016_December_chart.png" /></a></div>
Most of the income is still from ad in Shards - the brickbreaker game.<br />
<br />
<div style="text-align: justify;">
Income from HTML5 hired work and HTML5 licences for December is $1 968,3.<br />
<br />
Income from my <a href="https://gumroad.com/l/CZuhn">book</a> for December is $252,6. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Total income for December is <b>$2 303,0</b>.
It is 28,9% increase, compared to November ($1 787,0).</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<br />
<h4>
Next</h4>
<div style="text-align: justify;">
<br />
In January I am still working on some games for clients and continue with levels and finishing touches for first world of Pirates! I am also taking some Unity video courses I purchased on Udemy.</div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-45482517052189358082016-12-20T02:29:00.001-08:002016-12-20T02:31:55.231-08:00Mobile Income Report #29 - November 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/11/mobile-income-report-28-october-2016.html">Mobile Income Report #28 - October 2016</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/10/mobile-income-report-27-september-2016.html">Mobile Income Report #27 - September 2016</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/09/mobile-income-report-26-august-2016.html">Mobile Income Report #26 - August 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/08/mobile-income-report-25-july-2016.html">Mobile Income Report #25 - July 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/07/mobile-income-report-24-june-2016.html">Mobile Income Report #24 - June 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/06/mobile-income-report-23-may-2016.html">Mobile Income Report #23 - May 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
:<br />
: <br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<h4>
What I did in November</h4>
<ul>
<li style="text-align: justify;">spent some time with work on client projects. Will bring screenshots in next report,</li>
<li style="text-align: justify;">added new levels to HTML5 version of Pirates! - the match 3. Still have to test it:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-M3m9livyrdg/WFkA1XnS6FI/AAAAAAAACRM/nyqQfYruvQchwqV2-ZiJoHSAzNpq1lMcACLcB/s1600/Pirates-HTML5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://4.bp.blogspot.com/-M3m9livyrdg/WFkA1XnS6FI/AAAAAAAACRM/nyqQfYruvQchwqV2-ZiJoHSAzNpq1lMcACLcB/s400/Pirates-HTML5.jpg" width="250" /></a></div>
<ul>
<li>worked on Unity version of Pirates. Currently, main menu, map selection and map scenes are working. Only missing little thing is game itself :-)</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-OaCIPVVi028/WFkBJxaeO9I/AAAAAAAACRQ/biP2gI1QnwM3eKXcewbtR0duQwFW2wfWgCLcB/s1600/Pirates-Unity.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="418" src="https://1.bp.blogspot.com/-OaCIPVVi028/WFkBJxaeO9I/AAAAAAAACRQ/biP2gI1QnwM3eKXcewbtR0duQwFW2wfWgCLcB/s640/Pirates-Unity.jpg" width="640" /></a></div>
<ul>
<li style="text-align: justify;">if you examined screenshot above, you may noticed some markers on map. In November I invested into a few Unity plugins:</li>
<ul style="text-align: justify;">
<li><a href="https://www.assetstore.unity3d.com/en/#!/content/17662">Text Mesh Pro</a> - really great plugin for working with texts,</li>
<li><a href="https://www.assetstore.unity3d.com/en/#!/content/42095">Pro Camera 2D</a> - very nice plugin for various camera handlings,</li>
<li><a href="https://www.assetstore.unity3d.com/en/#!/content/3558">ProBuilder Advanced</a> - tool for rapid prototyping of 3D levels,</li>
<li><a href="https://www.assetstore.unity3d.com/en/#!/content/2943">UFPS: Ultimate FPS</a> - base platform for FPS games</li>
</ul>
<div class="separator" style="clear: both; text-align: justify;">
So, my Christmas happen already in November. Last two plugins are 3D related and shows my interests in next year - I finally want to create also something in 3D! </div>
</ul>
<ul>
<li>my first book <a href="https://gumroad.com/l/CZuhn">"Create procedural endless runner in Phaser with TypeScript"</a> reached 80 sales.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-AvpAeUJWbZE/V-Kh6o3pHhI/AAAAAAAACMU/SY4jpy_d1kYpg81w0gX3FDgIrAjWiEBCgCPcB/s1600/Book_new_350.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-AvpAeUJWbZE/V-Kh6o3pHhI/AAAAAAAACMU/SY4jpy_d1kYpg81w0gX3FDgIrAjWiEBCgCPcB/s320/Book_new_350.png" width="252" /></a></div>
<span id="goog_801536632"></span><br />
<br />
<h4>
Report</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here is first of last two income reports. I decided to end it in December to close year 2016. It started as income report from mobile games, but it is more and more about HTML5 games as income from mobile ones is still pretty low. Picking such a small figures from many internet consoles is boring and I decided to invest saved time into writing more tutorials and technical articles next year. </div>
<br />
Here is income from mobile games in November:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-aJCXlZvfmK4/WFkExOQxqgI/AAAAAAAACRg/snR5SXacOX4Yrdxs3De_N9yfemRToax1wCLcB/s1600/2016_November_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-aJCXlZvfmK4/WFkExOQxqgI/AAAAAAAACRg/snR5SXacOX4Yrdxs3De_N9yfemRToax1wCLcB/s1600/2016_November_table.png" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Figures are slightly better than in October ($84,3)</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-5bOLyVqwOYw/WFkGCmfNH9I/AAAAAAAACRo/s0vYvZb6zVA0p2Oo1WGEgh1An3QjipPAQCLcB/s1600/2016_November_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-5bOLyVqwOYw/WFkGCmfNH9I/AAAAAAAACRo/s0vYvZb6zVA0p2Oo1WGEgh1An3QjipPAQCLcB/s1600/2016_November_chart.png" /></a></div>
<br />
As usually, the highest income is from ads.<br />
<br />
<br />
<div style="text-align: justify;">
Income from HTML5 hired work and HTML5 licences for November is $1 480,9.<br />
<br />
Income from my <a href="https://gumroad.com/l/CZuhn">book</a> for November is $198,8. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Total income for November is <b>$1 787,0</b>.
It is 28,3% decrease, compared to October ($2 490,8).</div>
<br />
<br />
<h4>
Next</h4>
<br />
In December I am again working on some client projects. Beside it, I am rewriting Pirates into Unity and making new levels for it.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-47683138974097248142016-11-22T08:15:00.000-08:002016-11-22T08:15:34.996-08:00Mobile Income Report #28 - October 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/10/mobile-income-report-27-september-2016.html">Mobile Income Report #27 - September 2016</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/09/mobile-income-report-26-august-2016.html">Mobile Income Report #26 - August 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/08/mobile-income-report-25-july-2016.html">Mobile Income Report #25 - July 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/07/mobile-income-report-24-june-2016.html">Mobile Income Report #24 - June 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/06/mobile-income-report-23-may-2016.html">Mobile Income Report #23 - May 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<br />
:<br />
: <br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<h4>
What I did in October</h4>
<ul style="text-align: justify;">
<li>in October I finished another one-button game for Gamee platform. Its name is <a href="https://www.gameeapp.com/game/G1oy49taR">Gravity Ninja</a> and it is fast paced runner with gravity flipping. You can play it <a href="https://www.gameeapp.com/game/G1oy49taR">here</a>. Now, when writing this post, it already has 2.4 millions of plays!</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-vU6hNJT0RKQ/WDRoQW3-NFI/AAAAAAAACQM/_VWrxiIbH9UQtIqXi9300oz6TkjLaW0YQCLcB/s1600/GravityNinja02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-vU6hNJT0RKQ/WDRoQW3-NFI/AAAAAAAACQM/_VWrxiIbH9UQtIqXi9300oz6TkjLaW0YQCLcB/s320/GravityNinja02.jpg" width="320" /></a><a href="https://1.bp.blogspot.com/-p8BsWH0Y2-M/WDRoQckbeuI/AAAAAAAACQI/gA7JEAkddMYjMKe6ppZblIsH9sVcIkysgCLcB/s1600/GravityNinja01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-p8BsWH0Y2-M/WDRoQckbeuI/AAAAAAAACQI/gA7JEAkddMYjMKe6ppZblIsH9sVcIkysgCLcB/s320/GravityNinja01.jpg" width="320" /></a></div>
<ul>
<li>my first book <a href="https://gumroad.com/l/CZuhn">"Create procedural endless runner in Phaser with TypeScript"</a> reached 60 sales.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://gumroad.com/l/CZuhn"><img alt="Buy at Gumroad" border="0" height="320" src="https://2.bp.blogspot.com/-AvpAeUJWbZE/V-Kh6o3pHhI/AAAAAAAACMU/SY4jpy_d1kYpg81w0gX3FDgIrAjWiEBCgCPcB/s320/Book_new_350.png" width="252" /></a></div>
<ul style="text-align: justify;">
<li>finally, I got back to "Pirates - the match-3". But in little bit different way. While finishing HTML5 version on one side, I started to convert it into Unity on other side. We also have new main menu screen:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-5BHu5A9Xlqk/WDRqSyY3ieI/AAAAAAAACQY/ORFH0awZIuIzcFv7HJhc-2gVoaD4Za58QCLcB/s1600/Pirates.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-5BHu5A9Xlqk/WDRqSyY3ieI/AAAAAAAACQY/ORFH0awZIuIzcFv7HJhc-2gVoaD4Za58QCLcB/s400/Pirates.jpg" width="248" /></a></div>
<br /><br /><br />
<br />
<h4>
Report</h4>
<br />
Here is income from mobile games for October:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-w-i169djgyE/WDRrLqYPQLI/AAAAAAAACQk/Eleqw_lsE7ItDbS99eUpa4DYcKWOewqRQCLcB/s1600/2016_October_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-w-i169djgyE/WDRrLqYPQLI/AAAAAAAACQk/Eleqw_lsE7ItDbS99eUpa4DYcKWOewqRQCLcB/s1600/2016_October_table.png" /></a></div>
<br />
<div style="text-align: justify;">
There is big decrease, compared to September ($124,8). But it is also true, that I did no changes or updates to my mobile apps for very long time.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-aX8gYREDfCk/WDRrLl739VI/AAAAAAAACQg/7mUF5Tel97Q-6dNH5lAha3WK-DFjhPL6QCEw/s1600/2016_October_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-aX8gYREDfCk/WDRrLl739VI/AAAAAAAACQg/7mUF5Tel97Q-6dNH5lAha3WK-DFjhPL6QCEw/s1600/2016_October_chart.png" /></a></div>
As in past, the highest income is from ads.<br />
<br />
<br />
<div style="text-align: justify;">
Income from HTML5 hired work and HTML5 licences for October is $2 063,8.<br />
<br />
Income from my <a href="https://gumroad.com/l/CZuhn">book</a> for October is $342,7. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Total income for October is <b>$2 490,8</b>.
It is 20,9% decrease, compared to September ($3 147,8).</div>
<br />
<br />
<br />
<h4>
Next</h4>
<br />
In November I am again working on games for clients. I finally got back to Pirates - I am working on HTML5 version as well as on Unity version. I am starting to take my Unity exploration seriously.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-25337264946677866882016-10-25T02:26:00.001-07:002016-10-25T02:26:56.066-07:00Mobile Income Report #27 - September 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/09/mobile-income-report-26-august-2016.html">Mobile Income Report #26 - August 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/08/mobile-income-report-25-july-2016.html">Mobile Income Report #25 - July 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/07/mobile-income-report-24-june-2016.html">Mobile Income Report #24 - June 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/06/mobile-income-report-23-may-2016.html">Mobile Income Report #23 - May 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
:<br />
: <br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<h4>
</h4>
<h4>
What I did in September</h4>
<ul>
<li> finished another one-button game for Gamee platform. It is called <a href="https://www.gameeapp.com/game/yo9dVVzSRi">Ridhwan's Unicorn</a>. In this game I used P2 physics and developed some new procedures for my future games.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-HXYA2GSjf98/WA8eUWBxveI/AAAAAAAACOk/yC-4G8NGC4sKmgw6ax4TXwiF7Sk2l0HwACLcB/s1600/Ridhwan01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-HXYA2GSjf98/WA8eUWBxveI/AAAAAAAACOk/yC-4G8NGC4sKmgw6ax4TXwiF7Sk2l0HwACLcB/s320/Ridhwan01.jpg" width="320" /></a><a href="https://2.bp.blogspot.com/-n70mo6HMbm8/WA8eUq-Ow1I/AAAAAAAACOo/bRcdqb_HmUIuwqBghLFqEwA5w8BJxOmowCLcB/s1600/Ridhwan02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-n70mo6HMbm8/WA8eUq-Ow1I/AAAAAAAACOo/bRcdqb_HmUIuwqBghLFqEwA5w8BJxOmowCLcB/s320/Ridhwan02.jpg" width="320" /></a></div>
<ul style="text-align: justify;">
<li> last time I mentioned <a href="https://play.famobi.com/jewel-jungle">Jewel Jungle</a> game made for <a href="https://famobi.com/">Famobi</a>, but I did not attached screenshots. So, here are some as I think <a href="http://www.littlecolor.com/portfolio/">Tomas</a> made really nice graphics.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-CGeFEpYEcFk/WA8gBSj0V1I/AAAAAAAACO0/5_o0S8AFkHsXvAoLb29rwP6HN-qiq7DUwCLcB/s1600/JJ1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-CGeFEpYEcFk/WA8gBSj0V1I/AAAAAAAACO0/5_o0S8AFkHsXvAoLb29rwP6HN-qiq7DUwCLcB/s400/JJ1.jpg" width="250" /></a><a href="https://3.bp.blogspot.com/-LpUFJjS6G9Q/WA8gBtuSv_I/AAAAAAAACO4/kI8vFd7gZhstDF2vW3DhDgPZ1qS2FAlmACLcB/s1600/JJ2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/-LpUFJjS6G9Q/WA8gBtuSv_I/AAAAAAAACO4/kI8vFd7gZhstDF2vW3DhDgPZ1qS2FAlmACLcB/s400/JJ2.jpg" width="246" /></a></div>
<ul style="text-align: justify;">
<li>sales of my first book <a href="https://gumroad.com/l/CZuhn">"Create procedural endless runner in Phaser with TypeScript"</a> are getting close to first 50 sales. Currently, there is 46 of them.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-i50XGynyvMI/V-lDYgzKTOI/AAAAAAAACMs/WR5qGIEjfiEPhCussAeP8wu-g3ZiDc9NwCPcB/s1600/Book_new.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="512" src="https://4.bp.blogspot.com/-i50XGynyvMI/V-lDYgzKTOI/AAAAAAAACMs/WR5qGIEjfiEPhCussAeP8wu-g3ZiDc9NwCPcB/s640/Book_new.jpg" width="640" /></a></div>
<ul style="text-align: justify;">
<li>working on another client game. Next, month I will add details and screenshots.</li>
</ul>
<br />
<br />
<br />
<h4>
</h4>
<h4>
Report</h4>
<br />
Bellow you can see table with data for income from mobile games:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Wx7ouXvPHBg/WA8iLSHgosI/AAAAAAAACPE/llY9yQOKkBA-cWdo--1TIBAQnXJEHPOMQCLcB/s1600/2016_September_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-Wx7ouXvPHBg/WA8iLSHgosI/AAAAAAAACPE/llY9yQOKkBA-cWdo--1TIBAQnXJEHPOMQCLcB/s1600/2016_September_table.png" /></a></div>
<br />
<div style="text-align: justify;">
There is $9 increase, compared to August ($115,8). As in past, strongest asset in my mobile portfolio is Shards.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-erpbrIBWjAc/WA8iLe98csI/AAAAAAAACPM/e5RMjGxz9fwu4Qbq6t5CzngZ0GGcJec4wCEw/s1600/2016_September_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-erpbrIBWjAc/WA8iLe98csI/AAAAAAAACPM/e5RMjGxz9fwu4Qbq6t5CzngZ0GGcJec4wCEw/s1600/2016_September_chart.png" /></a></div>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Most of the income still comes from ads - 90% (85% in August).</div>
<br />
<div style="text-align: justify;">
Income from HTML5 hired work and HTML5 licences for September is $2 845,70.<br />
<br />
This month, there is new type of income first time - income from my <a href="https://gumroad.com/l/CZuhn">book</a>. For September it earned $177,30. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Total income for September is <b>$3 147,80</b>.
It is 51,7% increase, compared to August ($2 074,40), but not all the
earnings are mine (I have to share with other team members).</div>
<br />
<br />
<h4>
</h4>
<h4>
Next</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In October, I am again working on some client projects. Unfortunately, I still did not get back to Pirates and my Unity experiments.</div>
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-90359657983377451402016-09-26T09:36:00.000-07:002016-09-26T09:36:33.037-07:00Mobile Income Report #26 - August 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/08/mobile-income-report-25-july-2016.html">Mobile Income Report #25 - July 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/07/mobile-income-report-24-june-2016.html">Mobile Income Report #24 - June 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/06/mobile-income-report-23-may-2016.html">Mobile Income Report #23 - May 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/mobile-income-report-14-august-2015.html">Mobile Income Report #14 - August 2015</a> <br />
<br />
:<br />
: <br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<h4>
<b>
What I did in August</b></h4>
<ul style="text-align: justify;">
<li>most exciting point first. My first book is finished and is available for purchase. Name is "Create procedural endless runner in Phaser with TypeScript". Book is one long tutorial, that guides reader through process of creating endless runner. Final game can be seen and <a href="http://sbc.littlecolor.com/goblinrun">played here</a>. In individual topics reader will go through creating very flexible generator, skeletal animations for main goblin character, adding new features into game (like spikes, bonus jumps), adding sounds and music, etc. Of course, popular questions on handling different screen sizes are also covered. Book can be purchased <a href="https://gum.co/CZuhn">here at Gumroad</a>.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://gum.co/CZuhn"><img alt="Create procedural endless runner in Phaser with TypeScript" border="0" height="512" src="https://2.bp.blogspot.com/-i50XGynyvMI/V-lDYgzKTOI/AAAAAAAACMk/Yas6Acqw4Nwd8ziNI6dc0SltKR3y5IbeACLcB/s640/Book_new.jpg" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-9ItYgdi3ClU/V-lDYFz2jBI/AAAAAAAACMg/Ys7Fjlvp-2AqvhuryZLPfkVvePAU768UgCLcB/s1600/GoblinRun03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://3.bp.blogspot.com/-9ItYgdi3ClU/V-lDYFz2jBI/AAAAAAAACMg/Ys7Fjlvp-2AqvhuryZLPfkVvePAU768UgCLcB/s320/GoblinRun03.png" width="320" /></a><a href="https://1.bp.blogspot.com/-1azpt0BObpo/V-lDY1cIleI/AAAAAAAACMo/c0eNMFLrL6k_1f2u3E0f3bAymCaM90YuQCLcB/s1600/GoblinRun04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://1.bp.blogspot.com/-1azpt0BObpo/V-lDY1cIleI/AAAAAAAACMo/c0eNMFLrL6k_1f2u3E0f3bAymCaM90YuQCLcB/s320/GoblinRun04.png" width="320" /></a></div>
<ul style="text-align: justify;">
<li> we finished exclusive reskin of our Flat Jewels Match 3 game for Famobi. It is named Jewel Jungle and I think <a href="http://www.littlecolor.com/portfolio/">Tomas from Littlecolor</a> made really nice graphics. You can play final game <a href="https://play.famobi.com/jewel-jungle">Jewel Jungle</a>,</li>
<li>did some other work for clients - next month I will publish screenshots from very crazy game,</li>
<li>purchased book "<a href="https://www.raywenderlich.com/store/unity-games-by-tutorials">Unity Games by Tutorials</a>" from <a href="https://www.raywenderlich.com/">RayWenderlich.com</a> site. They are making very quality tutorials and I learned a lot from it. Book is still in early access, but will be finished soon.</li>
</ul>
<br />
<br />
<br />
<br />
<h4>
<b>
Report</b></h4>
Here is report for mobile games in August:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-8zktPGqIAPI/V-lLTxlzoRI/AAAAAAAACM4/_JiNTerrWpQfuh17ttKUkjr5nGAQHeldgCLcB/s1600/2016_August_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-8zktPGqIAPI/V-lLTxlzoRI/AAAAAAAACM4/_JiNTerrWpQfuh17ttKUkjr5nGAQHeldgCLcB/s1600/2016_August_table.png" /></a></div>
<br />
<div style="text-align: justify;">
There is $25 increase, compared to July ($90,6), which was very weak month. But, it is still behind figures from the first half of the year. All earnings are determined by Shards, as usual.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-Jv_Zn4B6gH8/V-lL__vRTJI/AAAAAAAACNA/l2CRIks2HrAt2JCI-ZRycgbK4sQ_QSgoACLcB/s1600/2016_August_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-Jv_Zn4B6gH8/V-lL__vRTJI/AAAAAAAACNA/l2CRIks2HrAt2JCI-ZRycgbK4sQ_QSgoACLcB/s1600/2016_August_chart.png" /></a></div>
<div style="text-align: justify;">
Most of the income still comes from ads - 85% (84% in July).</div>
<br />
<div style="text-align: justify;">
Income from HTML5 hired work and HTML5 licences for August is $1 958,60. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Total income for August is <b>$2 074,40</b>. It is 9,1% decrease, compared to July ($2 282,80) and not all the earnings are mine (I have to share with other team members), but I am happy with it.<br />
<br />
<br />
<br />
</div>
<h4>
<b>
Next</b></h4>
<div style="text-align: justify;">
In September I am still working on some client works. I hope, I will finally return back to Pirates!</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-2939652725195946712016-09-21T02:26:00.000-07:002016-09-26T09:39:14.737-07:00Phaser book on making procedural endless runner finished<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
After a few months of work I finally finished my first Phaser book. Its name is "<a href="https://gum.co/CZuhn">Create procedural endless runner in Phaser with TypeScript</a>".<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://gum.co/CZuhn"><img alt=" Create procedural endless runner in Phaser with TypeScript" border="0" height="512" src="https://3.bp.blogspot.com/-8exAlqQ40xU/V-KiOXLjBEI/AAAAAAAACMM/RIVkCnDJHrAy44DR2QhBVoh3j4vPXJUPACLcB/s640/Book_new.jpg" width="640" /></a></div>
<br />
<div style="text-align: justify;">
In the book you develop procedural endless runner game "Goblin Run". You can see and play final result at
<a href="http://sbc.littlecolor.com/goblinrun">http://sbc.littlecolor.com/goblinrun</a>. It is using popular HTML5 engine
<a href="http://www.phaser.io/">Phaser</a> and code is written in <a href="https://www.typescriptlang.org/">TypeScript</a>. TypeScript is superset of
JavaScript and if you are JavaScript programmer you should have no
problems to follow. </div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-UCH-sBdgcvo/V-JJ9xw1JWI/AAAAAAAACLc/kFZkbAht5kAldBrzjNl9K8qywojPOHnGwCLcB/s1600/GoblinRun01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://2.bp.blogspot.com/-UCH-sBdgcvo/V-JJ9xw1JWI/AAAAAAAACLc/kFZkbAht5kAldBrzjNl9K8qywojPOHnGwCLcB/s320/GoblinRun01.png" width="320" /></a><a href="https://2.bp.blogspot.com/-GkoFx1Q6lmY/V-JJ9u99l9I/AAAAAAAACLY/RlzyXk1XCOAhhVgj_MU6nqZqnWF_ioTcACLcB/s1600/GoblinRun03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://2.bp.blogspot.com/-GkoFx1Q6lmY/V-JJ9u99l9I/AAAAAAAACLY/RlzyXk1XCOAhhVgj_MU6nqZqnWF_ioTcACLcB/s320/GoblinRun03.png" width="320" /></a></div>
<br />
<div style="text-align: justify;">
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.<br />
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.<br />
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
You can get it at <a href="https://gum.co/CZuhn">Gumroad</a>, as well as see there detailed table of contents.</div>
<div style="text-align: justify;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-gyz-qtTjtS4/V-JPjKrYgjI/AAAAAAAACLw/ct0CKLBUsxcQBtqqbqo3Krl7iaqe9zoCACLcB/s1600/Pages.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="452" src="https://1.bp.blogspot.com/-gyz-qtTjtS4/V-JPjKrYgjI/AAAAAAAACLw/ct0CKLBUsxcQBtqqbqo3Krl7iaqe9zoCACLcB/s640/Pages.jpg" width="640" /></a></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
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.</div>
</div>
<div style="text-align: justify;">
<br />
<br />
<br />
<br /></div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-11578411637558792042016-08-25T09:48:00.001-07:002016-09-26T09:28:57.733-07:00Mobile Income Report #25 - July 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/07/mobile-income-report-24-june-2016.html">Mobile Income Report #24 - June 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/06/mobile-income-report-23-may-2016.html">Mobile Income Report #23 - May 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/mobile-income-report-14-august-2015.html">Mobile Income Report #14 - August 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/08/mobile-income-report-13-july-2015.html">Mobile Income Report #13 - July 2015</a><br />
:<br />
: <br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<h4>
<b>
What I did in July</b></h4>
<ul style="text-align: justify;">
<li>worked on two small games for Gamee platform. One of them, Rio Sprint, was already released and you can play it <a href="https://www.gameeapp.com/game/rd4Rewu3fR">here</a>:</li>
</ul>
<div style="text-align: center;">
<a href="https://4.bp.blogspot.com/-HL1rn80lJ50/V78Z9XEQbDI/AAAAAAAACJU/pHMbd0pkzZw1TgLi0eNippgrljAFKyfBwCLcB/s1600/RioSprint1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://4.bp.blogspot.com/-HL1rn80lJ50/V78Z9XEQbDI/AAAAAAAACJU/pHMbd0pkzZw1TgLi0eNippgrljAFKyfBwCLcB/s200/RioSprint1.jpg" width="200" /></a><a href="https://4.bp.blogspot.com/-viMtjdPeJkc/V78Z9bw-myI/AAAAAAAACJQ/ASs0zHDd9GQrgUADrHziEY98ZEEUQ5jvACLcB/s1600/RioSprint2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://4.bp.blogspot.com/-viMtjdPeJkc/V78Z9bw-myI/AAAAAAAACJQ/ASs0zHDd9GQrgUADrHziEY98ZEEUQ5jvACLcB/s200/RioSprint2.jpg" width="200" /></a></div>
<span style="color: #0000ee;"><u></u></span> <br />
<ul>
<li>did some small work on levels for "Pirates! - the match-3", but not too much. I was negligent of it lately which I would like to change,</li>
<li style="text-align: justify;">most of the time I spent on writing my first book. Currently I have over 140 pages and I am almost finished. Books theme is how to write procedural endless runner with Phaser and Typescript. Reader following steps in book will create game like this:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-T3u8dr2wn_g/V78dMStF26I/AAAAAAAACJo/yxO82gdau5ocHENS2pjFzO0Jb3dFngqXgCLcB/s1600/GoblinRun2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://1.bp.blogspot.com/-T3u8dr2wn_g/V78dMStF26I/AAAAAAAACJo/yxO82gdau5ocHENS2pjFzO0Jb3dFngqXgCLcB/s400/GoblinRun2.jpg" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Za9a18sleCw/V78dMBZVYjI/AAAAAAAACJg/MmJUBLeryOgVDXFm3nP4dmpt9Fw8vpohwCLcB/s1600/GoblinRun1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="226" src="https://4.bp.blogspot.com/-Za9a18sleCw/V78dMBZVYjI/AAAAAAAACJg/MmJUBLeryOgVDXFm3nP4dmpt9Fw8vpohwCLcB/s400/GoblinRun1.jpg" width="400" /></a></div>
<br />
<br />
<br />
<h4>
<b>Report</b></h4>
<h4>
</h4>
Income from mobile games in July is simply tragic:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-EGT5uuhKeBE/V78dMBONzuI/AAAAAAAACJs/_879F1c3ymkVR3bJwURObTaosp_cmvXjACEw/s1600/2016_July_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-EGT5uuhKeBE/V78dMBONzuI/AAAAAAAACJs/_879F1c3ymkVR3bJwURObTaosp_cmvXjACEw/s1600/2016_July_table.png" /></a></div>
<br />
<div style="text-align: justify;">
There is decrease from $143,1 in June to $90,6. From what I can see from August data, there is return back to better figures.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-_x2TlGfqgzQ/V78dML4sSaI/AAAAAAAACJs/7LdqL9qVdiYlD_TyAVm1qlnnDD2zqlFgACEw/s1600/2016_July_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-_x2TlGfqgzQ/V78dML4sSaI/AAAAAAAACJs/7LdqL9qVdiYlD_TyAVm1qlnnDD2zqlFgACEw/s1600/2016_July_chart.png" /></a></div>
Share of income from ads is stable. There is almost no income from in-apps this month.<br />
<br />
<div style="text-align: justify;">
Income from HTML5 hired work and HTML5 licences for July is $2 192,20. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Total income for July is <b>$2 282,80</b>.</div>
<br />
<br />
<br />
<h4>
<b>Next</b></h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In August I am still working on some client works. In the end I would like to return to Pirates! Also work on book continues and I hope I will finish first draft soon.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-40866713935829698982016-07-17T08:54:00.000-07:002016-08-25T09:13:42.958-07:00Mobile Income Report #24 - June 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/06/mobile-income-report-23-may-2016.html">Mobile Income Report #23 - May 2016 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/mobile-income-report-14-august-2015.html">Mobile Income Report #14 - August 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/08/mobile-income-report-13-july-2015.html">Mobile Income Report #13 - July 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/07/mobile-income-report-12-june-2015.html">Mobile Income Report #12 - June 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/06/mobile-income-report-11-may-2015.html"></a> <br />
:<br />
: <br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<h4>
</h4>
<h4>
What I did in June</h4>
<ul>
<li>in the very end of June finished Football Star game for Gamee platform. You can play it <a href="https://www.gameeapp.com/game/ufwpn9K">here</a>: </li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-at9cC3KO274/V4ujWNPv6UI/AAAAAAAACIQ/T6STG8DwmJ4gFqOAaf2VYpP6dVoUOBo0ACLcB/s1600/FootballStar.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://4.bp.blogspot.com/-at9cC3KO274/V4ujWNPv6UI/AAAAAAAACIQ/T6STG8DwmJ4gFqOAaf2VYpP6dVoUOBo0ACLcB/s200/FootballStar.jpg" width="200" /></a><a href="https://2.bp.blogspot.com/-QES4Ny5H7Rc/V4ujWJLl1VI/AAAAAAAACIU/IdhxhAL-30QOcYrM3WHzV5ET-LzEyJFwACLcB/s1600/FootballStar2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://2.bp.blogspot.com/-QES4Ny5H7Rc/V4ujWJLl1VI/AAAAAAAACIU/IdhxhAL-30QOcYrM3WHzV5ET-LzEyJFwACLcB/s200/FootballStar2.jpg" width="200" /></a></div>
<ul style="text-align: justify;">
<li> during month we did small adjustments requested by customers to HTML5 version of Shards. It is now published by Famobi and you can play it <a href="https://play.famobi.com/shards/">here</a>:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-gGUZsy8Prb8/V4ujVSkvN0I/AAAAAAAACIg/D9YsVu_HSisHRAINgmfgco1H-uhfOjwwwCEw/s1600/006.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-gGUZsy8Prb8/V4ujVSkvN0I/AAAAAAAACIg/D9YsVu_HSisHRAINgmfgco1H-uhfOjwwwCEw/s320/006.jpg" width="213" /></a><a href="https://1.bp.blogspot.com/-Hy_M1D3zUWk/V4ujVvMSciI/AAAAAAAACIg/PxaHo2JOLN05cyD5bFxRnzZGvponQ7SWQCEw/s1600/002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-Hy_M1D3zUWk/V4ujVvMSciI/AAAAAAAACIg/PxaHo2JOLN05cyD5bFxRnzZGvponQ7SWQCEw/s320/002.jpg" width="213" /></a></div>
<ul style="text-align: justify;">
<li> started work on levels for our big game "Pirates! - the match-3". We build Cordova version with Google Analytics for testing. In Google Analytics we collect data on how difficult it was to finish levels. Currently, we have levels for half of the first world:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-W-HMMyaWr8U/V4ujWWQiQpI/AAAAAAAACIg/QHMWcwzoZ9opIzGmdcQ5FIyEV0twikwvACEw/s1600/Pirates1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-W-HMMyaWr8U/V4ujWWQiQpI/AAAAAAAACIg/QHMWcwzoZ9opIzGmdcQ5FIyEV0twikwvACEw/s320/Pirates1.jpg" width="200" /></a><a href="https://2.bp.blogspot.com/-bH7YKzphsHw/V4ujWu4gBNI/AAAAAAAACIg/h4LEN1RZCnQ9vpxYe2jvxq8nbYMsPGzhQCEw/s1600/Pirates2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-bH7YKzphsHw/V4ujWu4gBNI/AAAAAAAACIg/h4LEN1RZCnQ9vpxYe2jvxq8nbYMsPGzhQCEw/s320/Pirates2.jpg" width="200" /></a></div>
<ul style="text-align: justify;">
<li> in the end of June I started work on HTML5 version of our older Android/iOS game Flat Jewels Match 3. It is now finished and we are looking for sponsors. Game is very simple, but fast paced match 3 game. You are given simple tasks in 150 levels or you can target highest score in Time Attack mode:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-0Muv5p19XAE/V4ujVluy3YI/AAAAAAAACIg/vwwP5e6fvS4M5RoUlerLT2ZSXRmn8j_MQCEw/s1600/FJM3_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-0Muv5p19XAE/V4ujVluy3YI/AAAAAAAACIg/vwwP5e6fvS4M5RoUlerLT2ZSXRmn8j_MQCEw/s320/FJM3_1.jpg" width="199" /></a><a href="https://2.bp.blogspot.com/-Z3NwRbUMxPw/V4ujV0wVmtI/AAAAAAAACIg/n7gYm4AnNkADrgk3nybrwGP9xiUCRx_vQCEw/s1600/FJM3_2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-Z3NwRbUMxPw/V4ujV0wVmtI/AAAAAAAACIg/n7gYm4AnNkADrgk3nybrwGP9xiUCRx_vQCEw/s320/FJM3_2.jpg" width="199" /></a></div>
<ul>
<li> during work on Flat Jewels I wrote small <a href="http://sbcgamesdev.blogspot.com/2016/07/phaser-tutorial-fun-with-bitmap-fonts.html">tutorial</a>, that was published in beginning of July. In it I explain how to add images into font definitions, so you can print them along with other text,</li>
<li style="text-align: justify;">started to write book! Its theme is how to make complete procedurally generated horizontal infinite runner in Typescript with <a href="http://phaser.io/">Phaser</a> engine. First 5 chapters (about 50 pages) is finished.</li>
</ul>
<br />
<br />
<br />
<h4>
Report</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here is income from mobile games:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-N5m-wu2VjcA/V4ujVqdL3wI/AAAAAAAACIg/fWzSQQZSyNMKphXmJ3VtOsJigMNaD43OACEw/s1600/2016_June_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-N5m-wu2VjcA/V4ujVqdL3wI/AAAAAAAACIg/fWzSQQZSyNMKphXmJ3VtOsJigMNaD43OACEw/s1600/2016_June_table.png" /></a></div>
<br />
<div style="text-align: justify;">
It is better, than previous month ($119,6), which was really weak. I am afraid, that July will be bad month again.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-qYTF9onBGfs/V4ujVcbBq3I/AAAAAAAACIg/OcBVOCT0eMUi4DRoZax4JsoM4WOVb-EyACEw/s1600/2016_June_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-qYTF9onBGfs/V4ujVcbBq3I/AAAAAAAACIg/OcBVOCT0eMUi4DRoZax4JsoM4WOVb-EyACEw/s1600/2016_June_chart.png" /></a></div>
<div style="text-align: justify;">
More income from paid apps and from in-apps decreased Ads share from 91% in May to 83%. But still, most income is from ads.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Income from HTML5 hired work and HTML5 licences for June is $2 440,20. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Total income for June is <b>$2 583,30</b>. It would be great if I managed to keep it on this level in future.</div>
<br />
<br />
<br />
<br />
<h4>
Next</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In July we will try to get next sponsors for Shards and for Flat Jewels Match 3. I will continue to build new levels for Pirates! - the match-3 and to fine tune older ones. I will also continue work on my first Phaser book. Beside this, I have some client work to do.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-77184319903721862712016-07-02T09:50:00.001-07:002016-07-02T12:07:00.991-07:00Phaser tutorial: Fun with bitmap fonts<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>Previous Phaser tutorials and articles:</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/phaser-tutorial-using-spriter-player.html">Phaser tutorial: Using Spriter player for Phaser</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-tutorial-merging-fonts-into.html">Phaser tutorial: Merging fonts into sprite atlas</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-typescript-defs-for-phaser-box2d.html">Phaser: Typescript defs for Phaser Box2D plugin</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/phaser-tutorial-spriter-pro-features.html">Phaser tutorial: Spriter Pro features added to Spriter player for Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/phaser-tutorial-using-phaser-signals.html">Phaser tutorial: Using Phaser signals</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-breaking-z-order-law.html">Phaser tutorial: Breaking the (z-order) law!</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-phaser-and-spriter.html">Phaser tutorial: Phaser and Spriter skeletal animation</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_23.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 3</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_9.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 2</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-adding-9-patch-image.html">Phaser tutorial: adding 9-patch image support to Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 1</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-custom-easing-functions.html">Phaser tutorial: custom easing functions for tweening and easing functions with parameters</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-sprites-and-custom.html">Phaser tutorial: sprites and custom properties for atlas frames</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-manage-different-screen.html">Phaser tutorial: manage different screen sizes</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/02/phaser-tutorial-how-to-wrap-bitmap-text.html">Phaser tutorial: How to wrap bitmap text</a><br />
<br />
<br />
<h4 style="text-align: justify;">
<b>Introduction</b></h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-QayPiFWjafA/V3fkS0wAMCI/AAAAAAAACG0/DLuVHwAapvkrPZHI-9zEF6VZ6-CflJrowCLcB/s1600/textWidth.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-QayPiFWjafA/V3fkS0wAMCI/AAAAAAAACG0/DLuVHwAapvkrPZHI-9zEF6VZ6-CflJrowCLcB/s1600/textWidth.png" /></a></div>
<br />
<div style="text-align: justify;">
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.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-rj9MIhAQS5w/V3fmgIjxGlI/AAAAAAAACHA/yKD4zNZ6ZTQUUzw_DMk0irCya6N92VwLwCLcB/s1600/textWithImage.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="104" src="https://3.bp.blogspot.com/-rj9MIhAQS5w/V3fmgIjxGlI/AAAAAAAACHA/yKD4zNZ6ZTQUUzw_DMk0irCya6N92VwLwCLcB/s320/textWithImage.png" width="320" /></a></div>
<br />
<br />
<h4>
<b>Solution</b></h4>
<br />
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
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 <a href="http://kvazars.com/littera/">Littera</a> or any other font tool. Atlas is standard atlas with your game images.</div>
<div style="text-align: justify;">
After these are loaded in your preload function - for example like this:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">atlas</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Game"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Game.png"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Game.json"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">bitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Font.png"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Font.xml"</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
you can start your adjustments in create function. First we get reference to our loaded assets:<br />
<br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">atlas</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getImage</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Game"</span><span style="color: #f8f8f2;">,</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">font</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getBitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
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.<br />
<br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">fontData</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">font</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">font</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">charA</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">fontData</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">chars</span><span style="color: #f8f8f2;">[</span><span style="color: #ae81ff;">65</span><span style="color: #f8f8f2;">];</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
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 ...</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">for</span> <span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">i</span> <span style="color: #f92672;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span> <span style="color: #a6e22e;">i</span> <span style="color: #f92672;"><</span> <span style="color: #a6e22e;">7</span><span style="color: #a6e22e;"></span><span style="color: #f8f8f2;">;</span> <span style="color: #a6e22e;">i</span><span style="color: #f92672;">++</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">f</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getFrameByName</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Game"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"Gem"</span> <span style="color: #f92672;">+</span> <span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">i</span> <span style="color: #f92672;">+</span> <span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">));</span>
<span style="color: #a6e22e;">fontData</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">chars</span><span style="color: #f8f8f2;">[</span><span style="color: #ae81ff;">5000</span> <span style="color: #f92672;">+</span> <span style="color: #a6e22e;">i</span><span style="color: #f8f8f2;">]</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #a6e22e;">x</span>: <span style="color: #66d9ef;">f.x</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">y</span>: <span style="color: #66d9ef;">f.y</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">width</span>: <span style="color: #66d9ef;">f.width</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">height</span>: <span style="color: #66d9ef;">f.height</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">xOffset</span>: <span style="color: #66d9ef;">1</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">yOffset</span>: <span style="color: #66d9ef;">charA.yOffset</span> <span style="color: #f92672;">+</span> <span style="color: #f8f8f2;">Math.</span><span style="color: #a6e22e;">floor</span><span style="color: #f8f8f2;">((</span><span style="color: #a6e22e;">charA</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">height</span> <span style="color: #f92672;">-</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">height</span><span style="color: #f8f8f2;">)</span> <span style="color: #f92672;">/</span> <span style="color: #ae81ff;">2</span><span style="color: #f8f8f2;">),</span>
<span style="color: #a6e22e;">xAdvance</span>: <span style="color: #66d9ef;">f.width</span> <span style="color: #f92672;">+</span> <span style="color: #ae81ff;">2</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">kerning</span><span style="color: #f92672;">:</span> <span style="color: #f8f8f2;">[],</span>
<span style="color: #a6e22e;">texture</span>: <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">PIXI</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">Texture</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">atlas</span><span style="color: #f8f8f2;">[</span><span style="color: #e6db74;">"base"</span><span style="color: #f8f8f2;">],</span> <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">PIXI</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">Rectangle</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">x</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">y</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">width</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">height</span><span style="color: #f8f8f2;">))</span>
<span style="color: #f8f8f2;">};</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
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.<br />
<br />
<br /></div>
<h4>
<b>Test</b></h4>
<br />
To test our gem images in text add this code:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">text</span> <span style="color: #f92672;">=</span> <span style="color: #e6db74;">"Hi, "</span> <span style="color: #f92672;">+</span> <span style="color: #f8f8f2;">String.</span><span style="color: #a6e22e;">fromCharCode</span><span style="color: #f8f8f2;">(</span><span style="color: #ae81ff;">5000</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">5005</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">5006</span><span style="color: #f8f8f2;">)</span> <span style="color: #f92672;">+</span> <span style="color: #e6db74;">" there!\n\nHow are you? "</span> <span style="color: #f92672;">+</span> <span style="color: #f8f8f2;">String.</span><span style="color: #a6e22e;">fromCharCode</span><span style="color: #f8f8f2;">(</span><span style="color: #ae81ff;">5001</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">5002</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">bmText</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">Phaser</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">BitmapText</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">game</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">text</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">110</span><span style="color: #f8f8f2;">);</span>
<span style="color: #a6e22e;">bmText</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">anchor</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">x</span> <span style="color: #f92672;">=</span> <span style="color: #ae81ff;">0.5</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">world</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">add</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">bmText</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
To include gems we make string from character codes with call to String.fromCharCode(). You should see this on screen:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-OdMFz4_1eXg/V3fs-4X994I/AAAAAAAACHQ/H0PKEK5b7WEuXMXSheA_xx-62GK-gNX1ACLcB/s1600/bitmapFont.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="207" src="https://3.bp.blogspot.com/-OdMFz4_1eXg/V3fs-4X994I/AAAAAAAACHQ/H0PKEK5b7WEuXMXSheA_xx-62GK-gNX1ACLcB/s320/bitmapFont.png" width="320" /></a></div>
<br />
<br />
<h4>
<b>Draw calls</b></h4>
<div style="text-align: justify;">
<br />
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.</div>
<br />
<div style="text-align: justify;">
Fortunately, there is also solution for this. Merge your font into atlas as described in one of previous <a href="http://sbcgamesdev.blogspot.cz/2016/03/phaser-tutorial-merging-fonts-into.html">tutorials</a>. Code changes only very little:</div>
<div style="text-align: justify;">
<br /></div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">font</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getBitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">fontData</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">font</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">font</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">charA</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">fontData</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">chars</span><span style="color: #f8f8f2;">[</span><span style="color: #ae81ff;">65</span><span style="color: #f8f8f2;">];</span>
<span style="color: #66d9ef;">for</span> <span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">i</span> <span style="color: #f92672;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span> <span style="color: #a6e22e;">i</span> <span style="color: #f92672;"><</span> <span style="color: #a6e22e;">Level</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">MAX_GEM</span><span style="color: #f8f8f2;">;</span> <span style="color: #a6e22e;">i</span><span style="color: #f92672;">++</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">let</span> <span style="color: #a6e22e;">f</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getFrameByName</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Game"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"Gem"</span> <span style="color: #f92672;">+</span> <span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">i</span> <span style="color: #f92672;">+</span> <span style="color: #ae81ff;">1</span><span style="color: #f8f8f2;">));</span>
<span style="color: #a6e22e;">fontData</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">chars</span><span style="color: #f8f8f2;">[</span><span style="color: #ae81ff;">5000</span> <span style="color: #f92672;">+</span> <span style="color: #a6e22e;">i</span><span style="color: #f8f8f2;">]</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #a6e22e;">x</span>: <span style="color: #66d9ef;">f.x</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">y</span>: <span style="color: #66d9ef;">f.y</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">width</span>: <span style="color: #66d9ef;">f.width</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">height</span>: <span style="color: #66d9ef;">f.height</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">xOffset</span>: <span style="color: #66d9ef;">1</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">yOffset</span>: <span style="color: #66d9ef;">charA.yOffset</span> <span style="color: #f92672;">+</span> <span style="color: #f8f8f2;">Math.</span><span style="color: #a6e22e;">floor</span><span style="color: #f8f8f2;">((</span><span style="color: #a6e22e;">charA</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">height</span> <span style="color: #f92672;">-</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">height</span><span style="color: #f8f8f2;">)</span> <span style="color: #f92672;">/</span> <span style="color: #ae81ff;">2</span><span style="color: #f8f8f2;">),</span>
<span style="color: #a6e22e;">xAdvance</span>: <span style="color: #66d9ef;">f.width</span> <span style="color: #f92672;">+</span> <span style="color: #ae81ff;">2</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">kerning</span><span style="color: #f92672;">:</span> <span style="color: #f8f8f2;">[],</span>
<span style="color: #a6e22e;">texture</span>: <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">PIXI</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">Texture</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">font</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">base</span><span style="color: #f8f8f2;">,</span> <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">PIXI</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">Rectangle</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">x</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">y</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">width</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">f</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">height</span><span style="color: #f8f8f2;">))</span>
<span style="color: #f8f8f2;">};</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This reduces draw calls to one.</div>
<br />
<br />
<h4>
<b>Conclusion</b></h4>
<br />
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.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-65295029916157902382016-06-21T02:25:00.000-07:002016-07-17T08:39:16.417-07:00Mobile Income Report #23 - May 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/05/mobile-income-report-22-april-2016.html">Mobile Income Report #22 - April 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/mobile-income-report-14-august-2015.html">Mobile Income Report #14 - August 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/08/mobile-income-report-13-july-2015.html">Mobile Income Report #13 - July 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/07/mobile-income-report-12-june-2015.html">Mobile Income Report #12 - June 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/06/mobile-income-report-11-may-2015.html">Mobile Income Report #11 - May 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/mobile-income-report-9-april-2015.html">Mobile Income Report #10 - April 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/mobile-income-report-9-march-2015.html">Mobile Income Report #9 - March 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/03/mobile-income-report-7-january-february.html">Mobile Income Report #8 - January and February 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/01/mobile-income-report-7-december-2014.html">Mobile Income Report #7 - December 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/12/mobile-income-report-6-november-2014.html">Mobile Income Report #6 - November 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/11/mobile-income-report-5-october-2014.html">Mobile Income Report #5 - October 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/10/mobile-income-report-4-september-2014.html">Mobile Income Report #4 - September 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/09/mobile-income-report-3-august-2014.html">Mobile Income Report #3 - August 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/08/mobile-income-report-2-july-2014.html">Mobile Income Report #2 - July 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
you can see my portfolio. It is list of the games that are then
reported in Income Reports.<br />
<br />
<br />
<h4>
<b>What I did in May</b></h4>
<ul style="text-align: justify;">
<li>worked on endless procedural platformer runner for <a href="https://www.gameeapp.com/">Gamee</a> platform. Game is finished and I am really prod of the generator. It generates platforms in real time and the result is not looking bad. For player animation I utilized my <a href="https://github.com/SBCGames/Spriter-Player-for-Phaser">Spriter player</a> for <a href="http://www.phaser.io/">Phaser</a>:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-BrSYRmdYZZc/V2kBh0u48VI/AAAAAAAACF0/BcEDzIA0kBky5ePq93tH4x-u3BwqIwC5gCLcB/s1600/Leto2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://2.bp.blogspot.com/-BrSYRmdYZZc/V2kBh0u48VI/AAAAAAAACF0/BcEDzIA0kBky5ePq93tH4x-u3BwqIwC5gCLcB/s200/Leto2.jpg" width="200" /></a><a href="https://3.bp.blogspot.com/-2cSyr51LZtc/V2kBhiOvZxI/AAAAAAAACFo/8j_sO3u7WNk1IHZXn9-z4tNy2M9dKbtoACLcB/s1600/Leto.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://3.bp.blogspot.com/-2cSyr51LZtc/V2kBhiOvZxI/AAAAAAAACFo/8j_sO3u7WNk1IHZXn9-z4tNy2M9dKbtoACLcB/s200/Leto.jpg" width="200" /></a></div>
<ul>
<li>continued work on "Pirates! - the match-3". We started to create final levels. For this I have built Cordova version of game for Android using Google Analytics. In the evenings we can play it and generate statistics for tuning.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-A8R60dcNZ-Y/V2kBipyJmcI/AAAAAAAACGQ/_HuDaBesZuYMjmFPBBK-3LCnpc0plTiHwCKgB/s1600/Pirates2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-A8R60dcNZ-Y/V2kBipyJmcI/AAAAAAAACGQ/_HuDaBesZuYMjmFPBBK-3LCnpc0plTiHwCKgB/s320/Pirates2.jpg" width="200" /></a><a href="https://3.bp.blogspot.com/-MLjWrVleFCw/V2kBiBNxbpI/AAAAAAAACGQ/AR70xRA8w4gv_sF4piQA43rXOi6gpQpNgCKgB/s1600/Pirates.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-MLjWrVleFCw/V2kBiBNxbpI/AAAAAAAACGQ/AR70xRA8w4gv_sF4piQA43rXOi6gpQpNgCKgB/s320/Pirates.jpg" width="200" /></a></div>
<br />
<br />
<br />
<h4>
<b>Report</b></h4>
<br />
Figures for mobile games are these:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-hWvTayUUlto/V2kBhkEA-JI/AAAAAAAACGQ/_J_bPIPfqh8d-IoywVPLFOZFoXu8ZlP-QCKgB/s1600/2016_May_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-hWvTayUUlto/V2kBhkEA-JI/AAAAAAAACGQ/_J_bPIPfqh8d-IoywVPLFOZFoXu8ZlP-QCKgB/s1600/2016_May_table.png" /></a></div>
<br />
<div style="text-align: justify;">
There is big decrease, compared to April, from $154,5 to $116,9. I did not investigate the reason, but number of downloads is more or less stable.</div>
<div style="text-align: justify;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-CaSZsG5pKR4/V2kBhoCdRJI/AAAAAAAACGQ/CpPhHeolADwzWR2b2UhLWzM3q0DHJEdEwCKgB/s1600/2016_May_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-CaSZsG5pKR4/V2kBhoCdRJI/AAAAAAAACGQ/CpPhHeolADwzWR2b2UhLWzM3q0DHJEdEwCKgB/s1600/2016_May_chart.png" /></a></div>
<br />
More than 90% of income is again from ads.<br />
<br />
Beside this, we got some small fee for our HTML5 games - $95,3.<br />
<br />
This month, I did not get any income for hired work - it is shifted to June.<br />
<br />
Total income for May is <b>$212,2</b>. It is a lot less than in April ($1 391,1) because of absence of income from hired work.<br />
<br />
<br />
<br />
<h4>
<b>Next </b></h4>
<h4>
<b> </b></h4>
<div style="text-align: justify;">
In June I am still working on "Pirates! - the match-3" - creating final levels and testing it. Working on another client work. We are also trying to sell licences for HTML5 version of Shards - the brickbreaker.</div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-48791795839483410472016-05-20T04:13:00.000-07:002016-05-20T04:13:00.767-07:00Mobile Income Report #22 - April 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/04/mobile-income-report-21-march-2016.html">Mobile Income Report #21 - March 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/mobile-income-report-14-august-2015.html">Mobile Income Report #14 - August 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/08/mobile-income-report-13-july-2015.html">Mobile Income Report #13 - July 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/07/mobile-income-report-12-june-2015.html">Mobile Income Report #12 - June 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/06/mobile-income-report-11-may-2015.html">Mobile Income Report #11 - May 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/mobile-income-report-9-april-2015.html">Mobile Income Report #10 - April 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/mobile-income-report-9-march-2015.html">Mobile Income Report #9 - March 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/03/mobile-income-report-7-january-february.html">Mobile Income Report #8 - January and February 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/01/mobile-income-report-7-december-2014.html">Mobile Income Report #7 - December 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/12/mobile-income-report-6-november-2014.html">Mobile Income Report #6 - November 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/11/mobile-income-report-5-october-2014.html">Mobile Income Report #5 - October 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/10/mobile-income-report-4-september-2014.html">Mobile Income Report #4 - September 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/09/mobile-income-report-3-august-2014.html">Mobile Income Report #3 - August 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/08/mobile-income-report-2-july-2014.html">Mobile Income Report #2 - July 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
<div style="text-align: justify;">
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
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, ...)<br />
<br />
<br />
<br />
<br />
<h4>
<b>What I did in April</b></h4>
<ul>
<li>finished HTML5 version of Shards - the brickbreaker. Game was rewritten in <a href="http://www.phaser.io/">Phaser</a> engine. Currently we are looking for sponsors. Shards is modern Arkanoid / Brickbreaker clone with glass bricks and glassy enemies - Shardiens. Game has 80 levels and every single one has its own fractal background:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-xpMdc1IgJeA/Vz7qBB9myUI/AAAAAAAACEk/e5nznov2IdkKLvxO_gK53Si0qN7LGgB2gCKgB/s1600/Shards1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-xpMdc1IgJeA/Vz7qBB9myUI/AAAAAAAACEk/e5nznov2IdkKLvxO_gK53Si0qN7LGgB2gCKgB/s400/Shards1.jpg" width="248" /></a><a href="https://2.bp.blogspot.com/-Z6-NnWULOHI/Vz7qBWxvqOI/AAAAAAAACEo/XsKVvYqhpmgImofd6a9aXaVlizYR7ptdgCKgB/s1600/Shards2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-Z6-NnWULOHI/Vz7qBWxvqOI/AAAAAAAACEo/XsKVvYqhpmgImofd6a9aXaVlizYR7ptdgCKgB/s400/Shards2.jpg" width="248" /></a></div>
<br />
<ul>
<li>finished hired HTML5 work on game Meteoric for <a href="http://www.gameeapp.com/">Gamee</a> platform<b>.</b> It is fast paced puzzle in which you merge asteroids into planets and planets into suns:</li>
</ul>
<b></b><br />
<div class="separator" style="clear: both; text-align: center;">
<b><a href="https://3.bp.blogspot.com/-gYlhQ6IlBzU/Vz7qASLlUdI/AAAAAAAACEs/ODuosC8r3TY0FaeCi38kWrSCb0vThvAmQCKgB/s1600/Meteoric2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://3.bp.blogspot.com/-gYlhQ6IlBzU/Vz7qASLlUdI/AAAAAAAACEs/ODuosC8r3TY0FaeCi38kWrSCb0vThvAmQCKgB/s200/Meteoric2.jpg" width="200" /></a><a href="https://3.bp.blogspot.com/-8LVGzVjOkQ0/Vz7qAX7hF2I/AAAAAAAACEs/Q7xfybU5s04rpv2iPwkUiCp79LxUHGQIACKgB/s1600/Meteoric.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://3.bp.blogspot.com/-8LVGzVjOkQ0/Vz7qAX7hF2I/AAAAAAAACEs/Q7xfybU5s04rpv2iPwkUiCp79LxUHGQIACKgB/s200/Meteoric.jpg" width="200" /></a></b></div>
<b>
</b><br />
<ul>
<li><b><span style="font-weight: normal;">also working on our game "Pirates! - the match-3", which is, as the name says, match-3 game:</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-qxsVpUUTAhU/Vz7qAva2gBI/AAAAAAAACEs/SdmKU2xxg_83UlDFnQK077Jx91Qys5HywCKgB/s1600/Pirates1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://2.bp.blogspot.com/-qxsVpUUTAhU/Vz7qAva2gBI/AAAAAAAACEs/SdmKU2xxg_83UlDFnQK077Jx91Qys5HywCKgB/s400/Pirates1.jpg" width="250" /></a><a href="https://3.bp.blogspot.com/-gII8LB14-7g/Vz7qA20OKuI/AAAAAAAACEs/ch9zlkAIdMwS7EQ0ryWeQkXrXlO_Q4-mgCKgB/s1600/Pirates2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/-gII8LB14-7g/Vz7qA20OKuI/AAAAAAAACEs/ch9zlkAIdMwS7EQ0ryWeQkXrXlO_Q4-mgCKgB/s400/Pirates2.jpg" width="250" /></a></div>
<br />
<br />
</b></li>
</ul>
<h4>
<b>Report</b></h4>
<br />
Here are April figures for mobile games:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-bCcng1B1TaA/Vz7rs8iOhPI/AAAAAAAACE4/UhmJxOzrzhs7ZUk7x6iDLfziphuG6sFywCLcB/s1600/2016_April_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-bCcng1B1TaA/Vz7rs8iOhPI/AAAAAAAACE4/UhmJxOzrzhs7ZUk7x6iDLfziphuG6sFywCLcB/s1600/2016_April_table.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-NiCLzSmhNJc/VxNUA0GKg9I/AAAAAAAACDc/CguuMaEV-EUNQVo8SolEMHTJ-sefo3wKACLcB/s1600/2016_March_table.png" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<br />
Income from mobile games is still quite stable ($175,8 in March) ... and low. Most profitable game remains Shards - the brickbreaker.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-TUGOENn2Mtw/Vz7rs4atRXI/AAAAAAAACE8/t5Qcj3cuSXcHnAoHZiq15dpQkEgxjb3OwCKgB/s1600/2016_April_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-TUGOENn2Mtw/Vz7rs4atRXI/AAAAAAAACE8/t5Qcj3cuSXcHnAoHZiq15dpQkEgxjb3OwCKgB/s1600/2016_April_chart.png" /></a></div>
<br />
Most of the income is from ads (88% in March) - share of paid apps and in-app purchases decreased.<br />
<br />
In April I got also some income from licences and hired work: $1 223.<br />
<br />
<div style="text-align: justify;">
Total income for April is:<b> $1 391,1</b>. This is similar to February ($1 323,0) and much more than March ($175,8). </div>
<br />
<br />
<br />
<br />
<h4>
<b>Next</b></h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b> </b>In May I am still working on "Pirates!, the match-3". This is my priority now as game is working in all direction. What we are missing are levels. We are also replacing placeholder graphics with our own as well as some static images with animations.<br />
I am also doing another hired work.<br />
<br />
<br />
<br />
<br />
<br />
</div>
</div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-33974826676485692212016-04-17T14:34:00.000-07:002016-04-18T05:18:15.551-07:00Phaser tutorial: Using Spriter player for Phaser<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>Previous Phaser tutorials and articles:</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-tutorial-merging-fonts-into.html">Phaser tutorial: Merging fonts into sprite atlas</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-typescript-defs-for-phaser-box2d.html">Phaser: Typescript defs for Phaser Box2D plugin</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/phaser-tutorial-spriter-pro-features.html">Phaser tutorial: Spriter Pro features added to Spriter player for Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/phaser-tutorial-using-phaser-signals.html">Phaser tutorial: Using Phaser signals</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-breaking-z-order-law.html">Phaser tutorial: Breaking the (z-order) law!</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-phaser-and-spriter.html">Phaser tutorial: Phaser and Spriter skeletal animation</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_23.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 3</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_9.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 2</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-adding-9-patch-image.html">Phaser tutorial: adding 9-patch image support to Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 1</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-custom-easing-functions.html">Phaser tutorial: custom easing functions for tweening and easing functions with parameters</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-sprites-and-custom.html">Phaser tutorial: sprites and custom properties for atlas frames</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-manage-different-screen.html">Phaser tutorial: manage different screen sizes</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/02/phaser-tutorial-how-to-wrap-bitmap-text.html">Phaser tutorial: How to wrap bitmap text</a><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-xHg1trfScUk/VxPo7IMwewI/AAAAAAAACDs/R1YUmZfELncJd3suRQ6ZiTFFelaar2V1QCLcB/s1600/Parrot.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-xHg1trfScUk/VxPo7IMwewI/AAAAAAAACDs/R1YUmZfELncJd3suRQ6ZiTFFelaar2V1QCLcB/s1600/Parrot.gif" /></a></div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
<b>Introduction</b> </h4>
<div style="text-align: justify;">
<br />
Some time ago I published here article about <a href="http://sbcgamesdev.blogspot.com/2016/02/phaser-tutorial-spriter-pro-features.html">Spriter player for Phaser</a>. 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!<br />
<br />
So, I made a few changes - check <a href="https://github.com/SBCGames/Spriter-Player-for-Phaser">GitHub</a>:</div>
<ul>
<li>player itself and example are both separated from each other,</li>
<li>there is added Build folder, where you can grab either spriter.js or spriter.min.js files ready to be used in your project.</li>
</ul>
<div style="text-align: justify;">
Splitting player and example also forced creation of Typescript defs for player. It can be found in spriter.d.ts file in Build directory.</div>
<br />
<br />
<h4>
<b>Example</b></h4>
<div style="text-align: justify;">
<br />
I assume you are familiar with Phaser states. On <a href="https://github.com/SBCGames/Spriter-Player-for-Phaser/tree/master/Test/src/States">GitHub</a> 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 <a href="https://github.com/SBCGames/Spriter-Player-for-Phaser/tree/master/Test/assets">assets folder</a>):</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// load assets</span>
<span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">path</span>: <span style="color: #66d9ef;">string</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">Global</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">assetsPath</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// test</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">atlas</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"TEST"</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">path</span> <span style="color: #f92672;">+</span> <span style="color: #e6db74;">"Atlas.png"</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">path</span> <span style="color: #f92672;">+</span> <span style="color: #e6db74;">"Atlas.json"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">xml</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"TESTXml"</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">path</span> <span style="color: #f92672;">+</span> <span style="color: #e6db74;">"TEST.xml"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">json</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"TESTJson"</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">path</span> <span style="color: #f92672;">+</span> <span style="color: #e6db74;">"TEST.json"</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
You will need only to load either xml or json. Both lines are here only to show both possibilities. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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.</div>
<br />
When your data are loaded you can move to file Test.ts, where we will use it.<br />
<br />
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.<br />
<br />
Let's create loader:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// create Spriter loader - class that can change Spriter file into internal structure</span>
<span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">spriterLoader</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">Spriter</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">Loader</span><span style="color: #f8f8f2;">();</span>
</pre>
</div>
<br />
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):<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// create Spriter file object - it wraps XML/JSON loaded with Phaser Loader</span>
<span style="color: #75715e;">//var spriterFile = new Spriter.SpriterXml(this.cache.getXML("TESTXml"));</span>
<span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">spriterFile</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">Spriter</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">SpriterJSON</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getJSON</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"TESTJson"</span><span style="color: #f8f8f2;">));</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
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.)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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):</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// create actual renderable object - it is extension of Phaser.Group</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">_spriterGroup</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">Spriter</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">SpriterGroup</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">game</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">spriterData</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"TEST"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"Hero"</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">100</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">_spriterGroup</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">position</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">setTo</span><span style="color: #f8f8f2;">(</span><span style="color: #ae81ff;">420</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">400</span><span style="color: #f8f8f2;">);</span>
<span style="color: #75715e;">// adds SpriterGroup to Phaser.World to appear on screen</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">world</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">add</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">_spriterGroup</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
To tick animation add this into update method:<br />
<!-- HTML generated using hilite.me -->
<br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #a6e22e;">update() {</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">_spriterGroup</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">updateAnimation</span><span style="color: #f8f8f2;">();</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
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.</div>
<br />
<div style="text-align: justify;">
Running the example now, you should have animated character on screen. If you used assets from test, you will see this boy:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-g4ITx0ra_P0/Vslzmz3mbtI/AAAAAAAACAQ/AWm68VPu6ykKScJpswXu7NQD9MrvTU6rACKgB/s1600/SpriterProTest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-g4ITx0ra_P0/Vslzmz3mbtI/AAAAAAAACAQ/AWm68VPu6ykKScJpswXu7NQD9MrvTU6rACKgB/s1600/SpriterProTest.png" /></a></div>
<div style="text-align: justify;">
<br /></div>
<h4>
SpriterGroup features</h4>
<div style="text-align: justify;">
<br />
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).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In example above we created new SpriterGroup like this:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">_spriterGroup</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">Spriter</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">SpriterGroup</span><span style="color: #f8f8f2;">(</span><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">game</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">spriterData</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"TEST"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"Hero"</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">100</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
Here is what these parameters mean:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #66d9ef;">constructor</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">game</span>: <span style="color: #66d9ef;">Phaser.Game</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">spriter</span>: <span style="color: #66d9ef;">Spriter</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">texutreKey</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">entityName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">animation?</span>: <span style="color: #66d9ef;">string</span> <span style="color: #f92672;">|</span> <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">animationSpeedPercent?</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
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.<br />
<br />
SpriterGroup can inform you on a few events. This is done through standard Phaser.Signals. Here is list of signals you can use: </div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// onLoop(SpriterGroup);</span>
<span style="color: #a6e22e;">onLoop</span>: <span style="color: #66d9ef;">Phaser.Signal</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// onFinish(SpriterGroup);</span>
<span style="color: #a6e22e;">onFinish</span>: <span style="color: #66d9ef;">Phaser.Signal</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// onSound(SpriterGroup, string); // string for line name which equals soud name without extension</span>
<span style="color: #a6e22e;">onSound</span>: <span style="color: #66d9ef;">Phaser.Signal</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// onEvent(SpriterGroup, string); // string for line name which equals event name</span>
<span style="color: #a6e22e;">onEvent</span>: <span style="color: #66d9ef;">Phaser.Signal</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// onTagChange(SpriterGroup, string, boolean); // string for tag name, boolean for change (true = set / false = unset)</span>
<span style="color: #a6e22e;">onTagChange</span>: <span style="color: #66d9ef;">Phaser.Signal</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// onVariableSet(SpriterGroup, Variable); // Variable is Spriter variable def with access to value</span>
<span style="color: #a6e22e;">onVariableSet</span>: <span style="color: #66d9ef;">Phaser.Signal</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
<ul>
<li>onLoop - subscribers are notified when animation loops,</li>
<li>onFinish - if animation does not loop, subscribers are notified on finishing,</li>
<li style="text-align: justify;">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,</li>
<li style="text-align: justify;">onEvent - in this Spriter player implementation it is the same as onSound, but not sound specific. Also here, name of the event is dispatched,</li>
<li style="text-align: justify;">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,</li>
<li style="text-align: justify;">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.</li>
</ul>
<br />
Here are few properties you can read:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// get loaded Spriter structure</span>
<span style="color: #a6e22e;">spriter</span>: <span style="color: #66d9ef;">Spriter</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// get Spriter entity</span>
<span style="color: #a6e22e;">entity</span>: <span style="color: #66d9ef;">Entity</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// number of animations for current entity</span>
<span style="color: #a6e22e;">animationsCount</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// name of current animation</span>
<span style="color: #a6e22e;">currentAnimationName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
pause can be read and set:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// is anim paused?</span>
<span style="color: #a6e22e;">paused</span>: <span style="color: #66d9ef;">boolean</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
To play or change animation, set its playing speed and to update (tick) whole SpriterGroup, use these methods:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// set speed of animation in percent (default = 100)</span>
<span style="color: #a6e22e;">setAnimationSpeedPercent</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">animationSpeedPercent</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// play animation by Spriter animation id</span>
<span style="color: #a6e22e;">playAnimationById</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">aAnimationId</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// play animation by name</span>
<span style="color: #a6e22e;">playAnimationByName</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">aAnimationName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// call this on every frame to tick animation</span>
<span style="color: #a6e22e;">updateAnimation</span><span style="color: #f8f8f2;">()</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
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.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// add charmap on top of charmap stacky by name</span>
<span style="color: #a6e22e;">pushCharMap</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">charMapName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// remove charmap from stack by name</span>
<span style="color: #a6e22e;">removeCharMap</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">charMapName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// remove all charmaps from charmap stack</span>
<span style="color: #a6e22e;">clearCharMaps</span><span style="color: #f8f8f2;">()</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
With last set of methods you can question tags and variables:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #75715e;">// check if animation tag with given name is on or off</span>
<span style="color: #a6e22e;">isTagOn</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">tagName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">boolean</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// check if animation tag with given id is on or off</span>
<span style="color: #a6e22e;">isTagOnById</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">tagId</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">boolean</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// get animation variable by name</span>
<span style="color: #a6e22e;">getVariable</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">varName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #a6e22e;">Variable</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// get animation variable by id</span>
<span style="color: #a6e22e;">getVariableById</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">varId</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #a6e22e;">Variable</span><span style="color: #f8f8f2;">;</span>
<span style="color: #75715e;">// get Spriter object by name - Spriter object contain actual Phaser.Sprite</span>
<span style="color: #a6e22e;">getObject</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">objectName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #a6e22e;">SpriterObject</span><span style="color: #f8f8f2;">;</span>
</pre>
</div>
<br />
<br />
<h4>
Conclusion</h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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.</div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-28855567387286752262016-04-17T02:28:00.001-07:002016-04-17T02:28:07.792-07:00Mobile Income Report #21 - March 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>previous parts</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/mobile-income-report-20-february-2016.html">Mobile Income Report #20 - February 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/mobile-income-report-14-august-2015.html">Mobile Income Report #14 - August 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/08/mobile-income-report-13-july-2015.html">Mobile Income Report #13 - July 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/07/mobile-income-report-12-june-2015.html">Mobile Income Report #12 - June 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/06/mobile-income-report-11-may-2015.html">Mobile Income Report #11 - May 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/mobile-income-report-9-april-2015.html">Mobile Income Report #10 - April 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/mobile-income-report-9-march-2015.html">Mobile Income Report #9 - March 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/03/mobile-income-report-7-january-february.html">Mobile Income Report #8 - January and February 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/01/mobile-income-report-7-december-2014.html">Mobile Income Report #7 - December 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/12/mobile-income-report-6-november-2014.html">Mobile Income Report #6 - November 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/11/mobile-income-report-5-october-2014.html">Mobile Income Report #5 - October 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/10/mobile-income-report-4-september-2014.html">Mobile Income Report #4 - September 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/09/mobile-income-report-3-august-2014.html">Mobile Income Report #3 - August 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/08/mobile-income-report-2-july-2014.html">Mobile Income Report #2 - July 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
<div style="text-align: justify;">
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
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, ...)<br />
<br />
<br />
<br /></div>
<h4>
<b>What I did in March</b></h4>
<ul style="text-align: justify;">
<li>in the very beginning of March I published Typescript defs for <a href="http://phaser.io/shop/plugins">Phaser Box2D plugin</a> at <a href="https://github.com/SBCGames/Phaser-Box2D-Typescript-defs">GitHub</a>,</li>
<li>I wrote another <a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-tutorial-merging-fonts-into.html">Phaser tutorial</a> - how to merge fonts generated with <a href="http://kvazars.com/littera/">Kvazar's Littera</a> or other program for generating fonts into your sprite atlas and thus decrease number of draw calls,</li>
<li>continued work on "Pirates!, the match3" game. <a href="http://www.littlecolor.com/portfolio/">Tomas Kopecky</a> painted some new sprites, so we are removing placeholders and finishing individual parts of game. Game has really lot of different tasks for players. On first image below you can see digging treasures from sand. On second image, there is another test level with web stick gems.</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-iAh9Bc22V9I/VxNRRjl-VKI/AAAAAAAACC8/skdUwhQTFO0gmJU_C3OtqI8roTcP1sJ8QCKgB/s1600/Pirates.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-iAh9Bc22V9I/VxNRRjl-VKI/AAAAAAAACC8/skdUwhQTFO0gmJU_C3OtqI8roTcP1sJ8QCKgB/s320/Pirates.jpg" width="200" /></a><a href="https://1.bp.blogspot.com/-jTXF5pc5kxA/VxNRRyUOpKI/AAAAAAAACDA/dUl-CNwemkcMId8Sq1XAdjNnQOWvtjPiACKgB/s1600/Pirates2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://1.bp.blogspot.com/-jTXF5pc5kxA/VxNRRyUOpKI/AAAAAAAACDA/dUl-CNwemkcMId8Sq1XAdjNnQOWvtjPiACKgB/s320/Pirates2.jpg" width="200" /></a></div>
<ul style="text-align: justify;">
<li> in March I also started conversion of our game Shards - the brickbreaker, which was originally for <a href="https://play.google.com/store/apps/details?id=com.sbcgames.shardsl">Android</a> / <a href="https://itunes.apple.com/us/app/shards-the-brick-breaker-lite/id979268730">iOS</a>, into HTML5. I am using Phaser Box2D plugin. Currently, most of it is finished. Following screenshots are from actual version:</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-y_fFRn2Kj9k/VxNRSLEXStI/AAAAAAAACDM/5S21CK8X0xY2PuKZiYLE1pkxCV37tzN5ACKgB/s1600/Shards.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-y_fFRn2Kj9k/VxNRSLEXStI/AAAAAAAACDM/5S21CK8X0xY2PuKZiYLE1pkxCV37tzN5ACKgB/s320/Shards.jpg" width="200" /></a><a href="https://2.bp.blogspot.com/-gOnPrP5QSPo/VxNRSYGCEyI/AAAAAAAACDM/Ym9Nr1pCu-Qizpnsn9NeDcTnmgcdtahbQCKgB/s1600/Shards2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://2.bp.blogspot.com/-gOnPrP5QSPo/VxNRSYGCEyI/AAAAAAAACDM/Ym9Nr1pCu-Qizpnsn9NeDcTnmgcdtahbQCKgB/s320/Shards2.jpg" width="200" /></a></div>
<ul>
<li> finished some hired work on small HTML5 game.</li>
</ul>
<ul style="text-align: justify;">
</ul>
<br />
<br />
<br />
<h4>
<b>Report</b></h4>
<br />
Here are March figures for mobile games:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-NiCLzSmhNJc/VxNUA0GKg9I/AAAAAAAACDc/CguuMaEV-EUNQVo8SolEMHTJ-sefo3wKACLcB/s1600/2016_March_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-NiCLzSmhNJc/VxNUA0GKg9I/AAAAAAAACDc/CguuMaEV-EUNQVo8SolEMHTJ-sefo3wKACLcB/s1600/2016_March_table.png" /></a></div>
<br />
Income is more or less stable from January: $173,3 - $166,0 - $175,8. Most profitable game remains Shards - the brickbreaker.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-xkHbovsyKTE/VxNUA6lHJzI/AAAAAAAACDY/-1nIZKsna987Z6PDrvyK517NVvg3YZr3ACKgB/s1600/2016_March_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://1.bp.blogspot.com/-xkHbovsyKTE/VxNUA6lHJzI/AAAAAAAACDY/-1nIZKsna987Z6PDrvyK517NVvg3YZr3ACKgB/s1600/2016_March_chart.png" /></a></div>
Also structure of income is stable - most of the income is from ads.<br />
<br />
I had no other income this month from HTML5 licences nor hired HTML5 work.<br />
<br />
<div style="text-align: justify;">
Total income for March is:<b> $175,8</b>. It is decrease compared to February ($1 323,0). But I am expecting some income from hired work I finished and we also have "frozen" income in our current work: Pirates!, the match3 and Shards - the brickbreaker.</div>
<br />
<br />
<br />
<h4>
<b>Next</b></h4>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<b> </b>In April I am working further on our game
"Pirates!, the match-3" and finishing Shards - the brickbreaker. I am still slowly experimenting with Unity and learning
WPF.</div>
<div style="text-align: justify;">
<br /></div>
<br />
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-59163735502290342222016-03-20T02:11:00.002-07:002016-03-20T02:23:56.574-07:00Mobile Income Report #20 - February 2016<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<b>previous parts</b><br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/mobile-income-report-19-january-2016.html">Mobile Income Report #19 - January 2016</a><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/mobile-income-report-18-december-2015.html">Mobile Income Report #18 - December 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/12/mobile-income-report-17-november-2015.html">Mobile Income Report #17 - November 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/11/mobile-income-report-16-october-2015.html">Mobile Income Report #16 - October 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/10/mobile-income-report-15-september-2015.html">Mobile Income Report #15 - September 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/mobile-income-report-14-august-2015.html">Mobile Income Report #14 - August 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/08/mobile-income-report-13-july-2015.html">Mobile Income Report #13 - July 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/07/mobile-income-report-12-june-2015.html">Mobile Income Report #12 - June 2015</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/06/mobile-income-report-11-may-2015.html">Mobile Income Report #11 - May 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/mobile-income-report-9-april-2015.html">Mobile Income Report #10 - April 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/mobile-income-report-9-march-2015.html">Mobile Income Report #9 - March 2015 </a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/03/mobile-income-report-7-january-february.html">Mobile Income Report #8 - January and February 2015</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/01/mobile-income-report-7-december-2014.html">Mobile Income Report #7 - December 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/12/mobile-income-report-6-november-2014.html">Mobile Income Report #6 - November 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/11/mobile-income-report-5-october-2014.html">Mobile Income Report #5 - October 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/10/mobile-income-report-4-september-2014.html">Mobile Income Report #4 - September 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/09/mobile-income-report-3-august-2014.html">Mobile Income Report #3 - August 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/08/mobile-income-report-2-july-2014.html">Mobile Income Report #2 - July 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-1-june-2014.html">Mobile Income Report #1 - June 2014</a><br />
<a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page - Portfolio</a> (what are my assets?)<br />
<br />
If you do not want to miss any of my Income Reports you can follow me on Twitter. Just click the button above.<br />
<br />
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Under <a href="http://sbcgamesdev.blogspot.com/2014/07/mobile-income-report-0-portfolio.html">Apps page</a>
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, ...)<br />
<br />
<br />
<br />
<h4>
<b>What I did in February</b></h4>
<ul>
<li>worked on our game "Pirates!, the match-3". In February I did only small changes as I was mainly updating <a href="https://github.com/SBCGames/Spriter-Player-for-Phaser">Spriter player for Phaser</a>, which the game uses,</li>
<li>big update of <a href="https://github.com/SBCGames/Spriter-Player-for-Phaser">Spriter player for Phaser</a>. Most of the Pro features is now supported, including character maps, events, tags, variables, sounds. See live <a href="http://sbcgamesdev.blogspot.com/2016/02/phaser-tutorial-spriter-pro-features.html">demo here</a>,</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-g4ITx0ra_P0/Vslzmz3mbtI/AAAAAAAACAQ/J7ZPdg6nneEy2zapl31wPCvuZdaBQ6sVw/s1600/SpriterProTest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-g4ITx0ra_P0/Vslzmz3mbtI/AAAAAAAACAQ/J7ZPdg6nneEy2zapl31wPCvuZdaBQ6sVw/s1600/SpriterProTest.png" /></a></div>
<ul>
<li>in the end of 2015 I purchased <a href="http://phaser.io/shop/plugins">Phaser Box2D plugin</a>. As it is missing Typescript defs, I decided to make mine. In the very beginning of March I put result on public <a href="https://github.com/SBCGames/Phaser-Box2D-Typescript-defs">GitHub repository</a> (short post <a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-typescript-defs-for-phaser-box2d.html">here</a>), </li>
<li>did another hired HTML5 work on fast paced puzzle game.</li>
</ul>
<b> </b><br />
<br />
<br />
<br />
<h4>
<b>Report</b></h4>
<br />
Here is February table with income from mobile games:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Yhr1s9R5Rx4/Vu27Xt_RnUI/AAAAAAAACCY/OSoxy10hYSc_2rNwaawHtOXtZRV98fNew/s1600/2016_February_table.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-Yhr1s9R5Rx4/Vu27Xt_RnUI/AAAAAAAACCY/OSoxy10hYSc_2rNwaawHtOXtZRV98fNew/s1600/2016_February_table.png" /></a></div>
<br />
Income remains more or less stable ($173,3 in January). As in previous months, the most profitable game is still Shards - the brickbreaker (<a href="https://itunes.apple.com/us/app/shards-the-brick-breaker/id892348419">iOS</a>, <a href="https://play.google.com/store/apps/details?id=com.sbcgames.shardsl">Android</a>).<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-1DXzV0FV1Z8/Vu27XoQRubI/AAAAAAAACCg/y29jlQQ-388NrN1WIDbrxaIjYcajV149A/s1600/2016_February_chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-1DXzV0FV1Z8/Vu27XoQRubI/AAAAAAAACCg/y29jlQQ-388NrN1WIDbrxaIjYcajV149A/s1600/2016_February_chart.png" /></a></div>
<br />
Most<b> </b>of the income came from ads (85%), which decreased a little compared to January (90%). Futoshiki (<a href="https://itunes.apple.com/us/app/futoshiki-puzzle/id1049837643">iOS</a>, <a href="https://play.google.com/store/apps/details?id=cz.sbcgames.futoshiki">Android</a>) game has very low download rate (2-3 downloads a day). But it has good conversion rate - looks like people who enjoy Futoshiki puzzle appreciate built in puzzle generator and are willing to pay for unlocking unlimited number of puzzles. And it also has better visual presentation than other Futoshiki games in my opinion.<br />
<br />
Beside income from mobile games I got some money for HTML5 hired work ($1 157).<br />
<br />
Total income for February for mobile games and HTML5 hired work is: $166,0 +$1 157,0 = <b>$1 323,0</b>. It is increase compared to January ($1 128,9) by 17%.<br />
<br />
<br />
<br />
<br />
<h4>
<b>Next</b></h4>
<br />
<b> </b>In March I am continuing in some hired work and also on our game "Pirates!, the match-3". Beside this I am playing with Phaser Box2D plugin. And finally, I am still experimenting with Unity and learinig WPF.<br />
<br />
<br />
<br />
<br />
<br /></div>
Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com0tag:blogger.com,1999:blog-4061183875375241256.post-29433074507956877662016-03-17T03:07:00.000-07:002017-04-19T09:07:11.120-07:00Phaser tutorial: Merging fonts into sprite atlas<div class="g-plusone">
</div>
<!-- Place this tag after the last +1 button tag. --><script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script><br />
<br />
<a class="twitter-follow-button" data-show-count="false" href="https://twitter.com/SBC_Games">Follow @SBC_Games</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<br />
<br />
<br />
<i><b>Previous Phaser tutorials and articles:</b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/03/phaser-typescript-defs-for-phaser-box2d.html">Phaser: Typescript defs for Phaser Box2D plugin</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2016/02/phaser-tutorial-spriter-pro-features.html">Phaser tutorial: Spriter Pro features added to Spriter player for Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2016/01/phaser-tutorial-using-phaser-signals.html">Phaser tutorial: Using Phaser signals</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-breaking-z-order-law.html">Phaser tutorial: Breaking the (z-order) law!</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/09/phaser-tutorial-phaser-and-spriter.html">Phaser tutorial: Phaser and Spriter skeletal animation</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_23.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 3</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game_9.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 2</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-adding-9-patch-image.html">Phaser tutorial: adding 9-patch image support to Phaser</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/05/phaser-tutorial-dronshooter-simple-game.html">Phaser tutorial: DronShooter - simple game in Typescript - Part 1</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-custom-easing-functions.html">Phaser tutorial: custom easing functions for tweening and easing functions with parameters</a> <br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-sprites-and-custom.html">Phaser tutorial: sprites and custom properties for atlas frames</a><i><b> </b></i><br />
<a href="http://sbcgamesdev.blogspot.com/2015/04/phaser-tutorial-manage-different-screen.html">Phaser tutorial: manage different screen sizes</a><br />
<a href="http://sbcgamesdev.blogspot.com/2015/02/phaser-tutorial-how-to-wrap-bitmap-text.html">Phaser tutorial: How to wrap bitmap text</a><br />
<br />
<br />
<div style="text-align: justify;">
<h4>
Introduction </h4>
<br />
Everybody with at least short experience in game development came across sprite atlases. Its benefits are in merging multiple sprites into one large bitmap and so decreasing draw calls. We can simplify draw call as request to GPU to draw something with some set of parameters. One of these parameters is also texture. Changing any of parameters results into quite expensive setup on GPU side (flushing current work and doing setup for different set of parameters) - this is reason why to build larger textures made from individual sprites.</div>
<div style="text-align: justify;">
Currently there is lot of tools, that help you with creating sprite atlas from individual sprites. But, when it comes to fonts, the situation starts to get complicated.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
For creating fonts I am using on-line tool <a href="http://kvazars.com/littera/">Littera</a>. This tool is great, but when you are exporting your font, you already get some atlas that contains your font characters. Alongside, you get file with characters metadata saying where in atlas is character positioned, how big it is, ... </div>
<div style="text-align: justify;">
Export from Littera can look like this:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-mu49C8Sm1gM/VupvCv3UNiI/AAAAAAAACBM/C-qNzD6lf_8fCLIrpKe5EGyN9w5VlBZwQ/s1600/MapNormal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-mu49C8Sm1gM/VupvCv3UNiI/AAAAAAAACBM/C-qNzD6lf_8fCLIrpKe5EGyN9w5VlBZwQ/s1600/MapNormal.png" /></a></div>
<div style="text-align: justify;">
<br /></div>
With metadata like this:<br />
<br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #f92672;"><font></span>
<span style="color: #f92672;"><info</span> <span style="color: #a6e22e;">face=</span><span style="color: #e6db74;">"MapNormal"</span> <span style="color: #a6e22e;">size=</span><span style="color: #e6db74;">"40"</span> <span style="color: #a6e22e;">bold=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">italic=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">charset=</span><span style="color: #e6db74;">""</span> <span style="color: #a6e22e;">unicode=</span><span style="color: #e6db74;">""</span> <span style="color: #a6e22e;">stretchH=</span><span style="color: #e6db74;">"100"</span> <span style="color: #a6e22e;">smooth=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">aa=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">padding=</span><span style="color: #e6db74;">"2,2,2,2"</span> <span style="color: #a6e22e;">spacing=</span><span style="color: #e6db74;">"0,0"</span> <span style="color: #a6e22e;">outline=</span><span style="color: #e6db74;">"0"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><common</span> <span style="color: #a6e22e;">lineHeight=</span><span style="color: #e6db74;">"75"</span> <span style="color: #a6e22e;">base=</span><span style="color: #e6db74;">"24"</span> <span style="color: #a6e22e;">scaleW=</span><span style="color: #e6db74;">"42"</span> <span style="color: #a6e22e;">scaleH=</span><span style="color: #e6db74;">"252"</span> <span style="color: #a6e22e;">pages=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">packed=</span><span style="color: #e6db74;">"0"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><pages></span>
<span style="color: #f92672;"><page</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">file=</span><span style="color: #e6db74;">"MapNormal.png"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"></pages></span>
<span style="color: #f92672;"><chars</span> <span style="color: #a6e22e;">count=</span><span style="color: #e6db74;">"10"</span><span style="color: #f92672;">></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"48"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"18"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"24"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"3"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"19"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"49"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"28"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"15"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"24"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"3"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"13"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"50"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"54"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"21"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"25"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"19"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"51"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"22"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"18"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"26"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"17"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"52"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"81"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"20"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"25"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"3"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"18"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"53"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"108"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"18"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"25"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"16"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"54"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"135"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"20"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"27"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"18"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"55"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"164"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"19"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"26"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"12"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"56"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"192"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"19"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"28"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"16"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"57"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"2"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"222"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"19"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"28"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"3"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"18"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"><char</span> <span style="color: #a6e22e;">id=</span><span style="color: #e6db74;">"32"</span> <span style="color: #a6e22e;">x=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">y=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">width=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">height=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">xoffset=</span><span style="color: #e6db74;">"1"</span> <span style="color: #a6e22e;">yoffset=</span><span style="color: #e6db74;">"3"</span> <span style="color: #a6e22e;">xadvance=</span><span style="color: #e6db74;">"11"</span> <span style="color: #a6e22e;">page=</span><span style="color: #e6db74;">"0"</span> <span style="color: #a6e22e;">chnl=</span><span style="color: #e6db74;">"15"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"></chars></span>
<span style="color: #f92672;"><kernings</span> <span style="color: #a6e22e;">count=</span><span style="color: #e6db74;">"0"</span><span style="color: #f92672;">/></span>
<span style="color: #f92672;"></font></span>
</pre>
</div>
<br />
<br />
<h4>
</h4>
<h4>
Problem</h4>
<div style="text-align: justify;">
<br />
So, let's have some sprite atlas and above font created in Littera. Let's also imagine we have some object, that is made from sprites and text. This is exactly what map screen with map spots is in our upcoming game Pirates! - the match three game (graphics is made by <a href="http://www.littlecolor.com/portfolio/">Tomáš Kopecký</a>):</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-GmEBmtaNDds/Vupv_gtA0OI/AAAAAAAACBU/eB1d5LaxPOkr1y0YRj3INQcUetLb-qiyg/s1600/Pirates_map.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://4.bp.blogspot.com/-GmEBmtaNDds/Vupv_gtA0OI/AAAAAAAACBU/eB1d5LaxPOkr1y0YRj3INQcUetLb-qiyg/s640/Pirates_map.jpg" width="400" /></a></div>
<br />
<div style="text-align: justify;">
Every single map spot is object made from sprites and text (level number). Scene graph for it looks like this:</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-KpQRaAsvW6w/VupwZ2LnpNI/AAAAAAAACBY/sbGI3PIccVcJOiL3SPZdaYNgQsLZomepw/s1600/00_scene_tree.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-KpQRaAsvW6w/VupwZ2LnpNI/AAAAAAAACBY/sbGI3PIccVcJOiL3SPZdaYNgQsLZomepw/s1600/00_scene_tree.png" /></a></div>
<br />
<div style="text-align: justify;">
Map has 65 level spots and drawing it takes 136 draw calls. 130 (65 * 2) of them is for map spots. It is very bad, but it is impact of switching between atlas with sprites and atlas with fonts. On above picture it is clear, that every time renderer renders single map spot, it has to switch texture twice.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
What we need is somehow merge font into our sprite atlas and keep valid font metadata. Then we will get rid of that texture switching and we will be able to decrease draw calls.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<h4 style="text-align: justify;">
</h4>
<h4 style="text-align: justify;">
Solution</h4>
<div style="text-align: justify;">
<br />
Long time ago I made tool for creating sprite atlases. It is very old and it has messy code inside, not too good GUI and also name is messy - I call it sometimes PicOpt and more recently Spritor. Anyway, it has some nice features and I used it for all games I made. You can get it for free <a href="https://sites.google.com/site/sbcgamesdev/blogfiles/SBC_atlas_tool.zip">here</a>. One of these nice features is, that it can do what we need. So, download it and follow next steps:</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Open Spritor tool and pres Ctrl+N to create new project. Give it name (it is not saved, it only created new project):</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-dPSFPuiEgBA/VupymnYFG9I/AAAAAAAACBo/sX6rc1X-v580JEVZocMHMU4uSxYIdsEtA/s1600/01_new_project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-dPSFPuiEgBA/VupymnYFG9I/AAAAAAAACBo/sX6rc1X-v580JEVZocMHMU4uSxYIdsEtA/s1600/01_new_project.png" /></a></div>
<br />
Press Ctrl+A to add some sprites (individual .png images):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-zHCmP5nJihY/VupymzJoNiI/AAAAAAAACCI/Ih0fPSlnbPYpXj00fVwOKadfS1-0ugrRQ/s1600/02_add_sprites.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-zHCmP5nJihY/VupymzJoNiI/AAAAAAAACCI/Ih0fPSlnbPYpXj00fVwOKadfS1-0ugrRQ/s1600/02_add_sprites.png" /></a></div>
<br />
Your screen should look similar to this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-6yfVIRhv908/VupymzgUjiI/AAAAAAAACCI/hKUVT-C09WUhaHRvYDUa4w0lBnGd7Kyhg/s1600/03_sprites_added.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="275" src="https://4.bp.blogspot.com/-6yfVIRhv908/VupymzgUjiI/AAAAAAAACCI/hKUVT-C09WUhaHRvYDUa4w0lBnGd7Kyhg/s400/03_sprites_added.png" width="400" /></a></div>
<br />
<div style="text-align: justify;">
Now, pres Ctrl+A again and open you Littera font atlas. You need to have Littera .xml/.fnt file in the same directory. Also, do not forget to check "Is font" in bottom of dialog window:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-456pKmnmv1c/Vupym41FuiI/AAAAAAAACCI/NrjIBSU-2jMEXYAzQvjMmkJZMWi9plLTA/s1600/04_add_font.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-456pKmnmv1c/Vupym41FuiI/AAAAAAAACCI/NrjIBSU-2jMEXYAzQvjMmkJZMWi9plLTA/s1600/04_add_font.png" /></a></div>
<br />
<div style="text-align: justify;">
This will add Littera font atlas into your project. It will read through Littera metadata in .xml/.fnt and cut Littera font atlas into individual sprites. The role of metadata is not finished yet. It will play important role once again during export. You can now select type of export. To have one compatible with TexturePacker export, select format in top bar as this:</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-ZQ-RhYqr4sQ/VupynFB-5vI/AAAAAAAACCI/WbFBCF_DEqIYCO16GZEc3NaSDvF4Vdspg/s1600/05_export_type.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-ZQ-RhYqr4sQ/VupynFB-5vI/AAAAAAAACCI/WbFBCF_DEqIYCO16GZEc3NaSDvF4Vdspg/s1600/05_export_type.png" /></a></div>
<br />
<div style="text-align: justify;">
(Btw, export just one line below ("JSON - TP + Properties") is adding custom properties, that you can add to your sprites in Spritor tool, into final export). You can now save your project by pressing Ctrl+S.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
It's time to make atlas. Go to menu and select Optimize -> Best Place:</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-9eCPRAy2o8o/VupyxeX9kxI/AAAAAAAACCE/KHbVB_zoXAciPAp9y8CMB7FHgZAgD0bMA/s1600/06_optimization.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-9eCPRAy2o8o/VupyxeX9kxI/AAAAAAAACCE/KHbVB_zoXAciPAp9y8CMB7FHgZAgD0bMA/s1600/06_optimization.png" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After some short time for optimiaztion, there will be created folder with name "export" and you will find several files there:</div>
<ul>
<li>your atlas image,</li>
<li>your atlas metadata (in TexturePacker format),</li>
<li>one Littera metadata file (.xml or .fnt) for every font you merged into atlas. This file already has all character specs adjusted to positions in new atlas.</li>
</ul>
This is how atlas from our walkthrough looks like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-zg0VEFOj0NM/VupyneMRm5I/AAAAAAAACCI/a0z40l08DoQx0VCmp405YMVB72yfcxfEQ/s1600/07_Atlas.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-zg0VEFOj0NM/VupyneMRm5I/AAAAAAAACCI/a0z40l08DoQx0VCmp405YMVB72yfcxfEQ/s1600/07_Atlas.png" /></a></div>
<br />
<h4>
Not finished yet - Phaser part</h4>
<br />
As we have our assets ready, we can load it into Phaser and see what happes.<br />
<br />
Normally, you would load your font and atlas in preload method with code like:<br />
<br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">atlas</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Atlas"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Atlas.png"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Atlas.json"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">bitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Font.png"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Font.xml"</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
But in our case we already have fonts merged into atlas, so we do not need to load "Font.png" file. So, we will first change this to:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">atlas</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Atlas"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Atlas.png"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Atlas.json"</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">load</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">xml</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"assets/Font.xml"</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
Then, when assets are loaded, in create method we have to build our font from loaded atlas and xml metadata. At first, it looks like easy task:<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">addBitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"MyFont"</span><span style="color: #f8f8f2;">,</span> <span style="color: #66d9ef;">null</span><span style="color: #f8f8f2;">,</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getImage</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Atlas"</span><span style="color: #f8f8f2;">),</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getXML</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">),</span> <span style="color: #e6db74;">"xml"</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
If you do above and run your game, You will see, that you can use "MyFont" in your game. It is taking characters from atlas, that is common with other sprites, but number of draw calls did not decreased! Something went wrong.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Let's look into Phaser source. Method for addBitmapFont has this in the beginning:</div>
<div style="text-align: justify;">
<br /></div>
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #a6e22e;">addBitmapFont</span>: <span style="color: #66d9ef;">function</span> <span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">key</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">url</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">data</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">atlasData</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">atlasType</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">xSpacing</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">ySpacing</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">obj</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #a6e22e;">url</span>: <span style="color: #66d9ef;">url</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">data</span>: <span style="color: #66d9ef;">data</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">font</span>: <span style="color: #66d9ef;">null</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">base</span>: <span style="color: #66d9ef;">new</span> <span style="color: #a6e22e;">PIXI</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">BaseTexture</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">data</span><span style="color: #f8f8f2;">)</span>
<span style="color: #f8f8f2;">};</span>
<span style="color: #f92672;">:</span>
<span style="color: #f92672;">:</span>
<span style="color: #f92672;">:</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
And if we dive a little bit deeper into PIXI.WebGLSpriteBatch.prototype.flush() method we find this (shortened and lots of code omitted for clarity):</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #f92672;">:</span>
<span style="color: #f92672;">:</span>
<span style="color: #a6e22e;">nextTexture</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">sprite</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">texture</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">baseTexture</span><span style="color: #f8f8f2;">;</span>
<span style="color: #f92672;">:</span>
<span style="color: #f92672;">:</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">((</span><span style="color: #a6e22e;">currentBaseTexture</span> <span style="color: #f92672;">!==</span> <span style="color: #a6e22e;">nextTexture</span> <span style="color: #f92672;">&&</span> <span style="color: #f92672;">!</span><span style="color: #a6e22e;">nextTexture</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">skipRender</span><span style="color: #f8f8f2;">)</span> <span style="color: #f92672;">||</span> <span style="color: #a6e22e;">blendSwap</span> <span style="color: #f92672;">||</span> <span style="color: #a6e22e;">shaderSwap</span><span style="color: #f8f8f2;">)</span>
<span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">renderBatch</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">currentBaseTexture</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">batchSize</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">start</span><span style="color: #f8f8f2;">);</span>
<span style="color: #f92672;">:</span>
<span style="color: #f92672;">:</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
Batches are flushed based not on underlaying atlas image, but on baseTexture. As we have one atlas we have to achieve somehow to have the same baseTexture for atlas as well as for font. For this we will create our custom method that will add functionality to Phaser Cache class. Let's call it addBitmapFontFromImage. Code for it is mostly copy of original addBitmapFont:<br />
<br />
<b>* update for Phaser 2.7.3 and later *</b> - when using jsonBitmapFont and xmlBitmapFont in code below, you have to pass two additional parameters for frame (null) and resolution (1). </div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">module</span> <span style="color: #a6e22e;">Utils</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">export</span> <span style="color: #66d9ef;">class</span> <span style="color: #a6e22e;">PhaserUtils</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #75715e;">// -------------------------------------------------------------------------</span>
<span style="color: #66d9ef;">public</span> <span style="color: #66d9ef;">static</span> <span style="color: #a6e22e;">AddBitmapFontAddMethod</span><span style="color: #f8f8f2;">()</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #a6e22e;">Phaser</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">Cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">prototype</span><span style="color: #f8f8f2;">[</span><span style="color: #e6db74;">"addBitmapFontFromImage"</span><span style="color: #f8f8f2;">]</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">function</span> <span style="color: #a6e22e;">addBitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">key</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">url</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">imageName</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">atlasData</span>: <span style="color: #66d9ef;">any</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">atlasType</span>: <span style="color: #66d9ef;">string</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">xSpacing?</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">ySpacing?</span>: <span style="color: #66d9ef;">number</span><span style="color: #f8f8f2;">)</span><span style="color: #f92672;">:</span> <span style="color: #66d9ef;">void</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">img</span> <span style="color: #f92672;">=</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getImage</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">imageName</span><span style="color: #f8f8f2;">,</span> <span style="color: #66d9ef;">true</span><span style="color: #f8f8f2;">);</span>
<span style="color: #66d9ef;">var</span> <span style="color: #a6e22e;">obj</span> <span style="color: #f92672;">=</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #a6e22e;">url</span>: <span style="color: #66d9ef;">url</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">data</span>: <span style="color: #66d9ef;">img.data</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">font</span>: <span style="color: #66d9ef;">null</span><span style="color: #f8f8f2;">,</span>
<span style="color: #a6e22e;">base</span>: <span style="color: #66d9ef;">img.base</span>
<span style="color: #f8f8f2;">};</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">xSpacing</span> <span style="color: #f92672;">===</span> <span style="color: #66d9ef;">undefined</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span> <span style="color: #a6e22e;">xSpacing</span> <span style="color: #f92672;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span> <span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">ySpacing</span> <span style="color: #f92672;">===</span> <span style="color: #66d9ef;">undefined</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span> <span style="color: #a6e22e;">ySpacing</span> <span style="color: #f92672;">=</span> <span style="color: #ae81ff;">0</span><span style="color: #f8f8f2;">;</span> <span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">if</span> <span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">atlasType</span> <span style="color: #f92672;">===</span> <span style="color: #e6db74;">'json'</span><span style="color: #f8f8f2;">)</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #a6e22e;">obj</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">font</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">Phaser</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">LoaderParser</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">jsonBitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">atlasData</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">obj</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">base</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">xSpacing</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">ySpacing</span><span style="color: #f8f8f2;">,</span> <b><span style="color: #66d9ef;">null</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">1</span></b><span style="color: #f8f8f2;">);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">else</span> <span style="color: #f8f8f2;">{</span>
<span style="color: #a6e22e;">obj</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">font</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">Phaser</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">LoaderParser</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">xmlBitmapFont</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">atlasData</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">obj</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">base</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">xSpacing</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">ySpacing</span><span style="color: #f8f8f2;"><span style="color: #f8f8f2;">,</span> <b><span style="color: #66d9ef;">null</span><span style="color: #f8f8f2;">,</span> <span style="color: #ae81ff;">1</span></b>);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">_cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">bitmapFont</span><span style="color: #f8f8f2;">[</span><span style="color: #a6e22e;">key</span><span style="color: #f8f8f2;">]</span> <span style="color: #f92672;">=</span> <span style="color: #a6e22e;">obj</span><span style="color: #f8f8f2;">;</span>
<span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">_resolveURL</span><span style="color: #f8f8f2;">(</span><span style="color: #a6e22e;">url</span><span style="color: #f8f8f2;">,</span> <span style="color: #a6e22e;">obj</span><span style="color: #f8f8f2;">);</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
<span style="color: #f8f8f2;">}</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
Our new method is wrapped in special PhaserUtils class. Btw, I have this class filled with other small engine tweaks and in the very beginning of the game I call one or more static methods to apply these tweaks. You have to do the same - do it before you create game object!:</div>
<div style="text-align: justify;">
<br /></div>
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #a6e22e;">Utils</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">PhaserUtils</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">AddBitmapFontAddMethod</span><span style="color: #f8f8f2;">();</span>
</pre>
</div>
<br />
<div style="text-align: justify;">
Now, replace line for creating font in create method with call to our new method:</div>
<!-- HTML generated using hilite.me --><br />
<div style="background: #272822; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">[</span><span style="color: #e6db74;">"addBitmapFontFromImage"</span><span style="color: #f8f8f2;">](</span><span style="color: #e6db74;">"MyFont"</span><span style="color: #f8f8f2;">,</span> <span style="color: #66d9ef;">null</span><span style="color: #f8f8f2;">,</span> <span style="color: #e6db74;">"Atlas"</span><span style="color: #f8f8f2;">,</span> <span style="color: #66d9ef;">this</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">cache</span><span style="color: #f8f8f2;">.</span><span style="color: #a6e22e;">getXML</span><span style="color: #f8f8f2;">(</span><span style="color: #e6db74;">"Font"</span><span style="color: #f8f8f2;">),</span> <span style="color: #e6db74;">"xml"</span><span style="color: #f8f8f2;">);</span>
</pre>
</div>
<br />
Call is using square brackets as we did not add our method into phaser.d.ts file. If you used standard call, you would get Typescript complaints.<br />
<br />
<div style="text-align: justify;">
If you run your game now, you should see that number of draw calls decreased. In my case it went down from 136 to 6!!!</div>
<br />
<br />
<h4>
</h4>
<h4>
Conclusion</h4>
<div style="text-align: justify;">
<br />
In our game we have in fact three different fonts for map spots - depends on whether spot is normal, finished, special battle spot... All three fonts contain only numbers. Instead of having three font atlases and one for sprites, we have only one for everything.</div>
<div style="text-align: justify;">
This helps us to save resources, reduce draw calls and as the process of creating atlas is easy we do not get any overhead.</div>
<br />
<br />
<br />
<br />Tomashttp://www.blogger.com/profile/12889236280842281037noreply@blogger.com1