The AI is here, I wonder if I can start using it in my work

Categories AI, DeepLearning

I followed the research on Deep Learning from early on with huge hopes and excitement, I feel like I am discovering the computer for the second time in my life and I love it. I never quite imagine that by the time I will be 35, we will all have really powerful computers in our pockets, portable one that you can use for digital paintings (iPad Pro) and I certainly did not see the AI revolution and the accessibility of it coming so fast. Needless to say I am extremely happy to see all of this now, I thought this would come sometime after my 60’s birthday.

Now I will have to learn how to use them in my own work.

In 2017 I started a subscription to, so that I can improve the artwork in my games. In the many courses I have taken there, I have seen a lot of art production workflows, some familiar and some very new and extremely helpful. I will try to see what I can automate using AI.

A couple of ideas come to mind, that would speed up my production. Note that I am talking about 2D only.

1. Train a Deep Learning Network to output different variants of a character design based on a few styles. This would speed up in my exploration and discovery phase.

2. Use Deep Learning to generate environments. Even if is just a few elements automated, like trees in a certain style, mountains etc.

3. I would really love to see if I could generate simple melodies to use in the games, some midi generator. I would arrange everything else in Ableton.

4. Color schemes, based on Great Masters of paintings, maybe even some auto coloring.

5. Lines cleanup in my sketching, this would also save a lot of time.

6. Automating Inbetweeners in animation, now this right here I know other people would love it.

I see myself in 5-10 years just giving direction and curating things (ha, ha).

Now is time to hit the AI books, get some GTX cards, brew coffee, this will take a while.

Share this

OpenFL on screen JoyStick created in AnimateCC

Categories AnimateCC, game development, HTML5, OpenFL

I am hard at work on the next game for, and I need a screen JoyStick. After taking a look around, I found that you can use the Point.interpolate method to restrict the joystick to a certain radius.

Here is a quick look on the results:



And here is a quick view of the the setup inside AnimateCC:

The haxe code:


  1. package com.cosmindolha.recessmaster.controlls;
  2. import flash.display.MovieClip;
  3. import flash.display.Sprite;
  4. import openfl.display.Stage;
  5. import openfl.geom.Point;
  6. import openfl.utils.Assets;
  7. import openfl.display.Bitmap;
  8. import openfl.display.BitmapData;
  9. import com.cosmindolha.recessmaster.Disp;
  10. import;
  11. import;
  12. import motion.Actuate;
  13. /**
  14. * ...
  15. * @author Cosmin Dolha
  16. */
  17. class JoyStick
  18. {
  19. var joyStick:MovingJoystick;
  20. var _stage:Stage;
  22. public function new(mc:CpFlag)
  23. {
  25. joyStick = mc.joystick.joyButton;
  26. joyStick.mouseEnabled = true;
  27. joyStick.buttonMode = true;
  29. _stage = mc.stage;
  31. joyStick.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  34. }
  36. function onUp(e:MouseEvent):Void
  37. {
  39. joyStick.x = 0;
  40. joyStick.y = 0;
  42. _stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
  43. _stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
  44. }
  46. function onDown(e:MouseEvent):Void
  47. {
  49. doMove();
  51. _stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
  52. _stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  53. }
  55. function onMove(e:MouseEvent):Void
  56. {
  57. doMove();
  58. }
  59. function doMove():Void
  60. {
  61. var centerPoint:Point = new Point(0, 0);
  62. var newPoint:Point = new Point(joyStick.parent.mouseX, joyStick.parent.mouseY);
  64. var distance = Point.distance(centerPoint, newPoint);
  66. joyStick.x = newPoint.x;
  67. joyStick.y = newPoint.y;
  69. if (distance > 50)
  70. {
  71. var newI:Float = 50/distance ;
  73. var newP:Point = Point.interpolate(newPoint, centerPoint, newI);
  74. joyStick.x = newP.x;
  75. joyStick.y = newP.y;
  76. }
  78. }
  79. }

The next on my list is to fire events based on the joystick position.

Happy Coding 🙂

Share this

Aivazovski master study

Categories MyArtWork

Master study from Ivan Aivazovsky.

I find it a bit easier to study paintings from printed books, rather than online sources.

Here is  a side by side, the phone camera distorts the colors a bit.


I used Procreate for painting and Affinity Photo for color correction on an iPad Pro, total time around 3 hours with my 1.9 yrs old son swarming around, the best way to work (ha ha).

Share this

Steps for accessing your AnimateCC textfield in OpenFL

Categories AnimateCC, game development, games, HTML5, OpenFL
  1. I am using the OpenFL extension for AnimateCC (the one found here).
  2. I embedded the font in AnimateCC *
  3. In the project.xml file I have added “<assets path=”Assets/fonts” rename=”fonts” include=”*.ttf” /> “
  4. If the textfield is in another MovieClip, you need to export this one as a class for ActionScript too.
  5. In the Assets/fonts folder I have added the .ttf font file used in AnimateCC.

That’s it, you can now do the layout and animation in AnimateCC, including the dynamic textfield.

In case you need to know how to use you Layouts/Animation from AnimateCC, here is the other part:

Any MovieClip that you want to use in OpenFL, you need to export it as a class for ActionScript. For example in my setup, I have a main MovieClip with my game background, then I have multiple MC that contains the textfield I want to be able to change in Haxe. Each MC with the text is the same symbol, so I only copy what I need, arrange it around the stage area and give each one a different name.

For example my main MC, is exported as a class for actionscript with the name EqMc, to access it, I create a new instance in Haxe using var eq:EqMc = new EqMc();

Inside the main MC, there are smaller MCs with the text, that are named eq0, eq1 etc. Inside them is a the textfield I want to control, named tf. So to change the text in one I only have to do = “my text”;

You could do this in code, but having the AnimateCC for the visual design cuts the development time. Not to mention all the nice effects you can now do.

Happy OpenFL developing 🙂

*it appears to work even without this step.

Share this

Making things move – Vector animations in AnimateCC working in OpenFL using Bitmap draw

Categories games

The setup is like this, I make the running cycles in Poser, render the animation frame by frame to a png sequence, import it in AnimateCC where I have installed the OpenFL plugin and code the web game using  OpenFL (I am back using HaxeDevelop).

I observed that you can get a decent performance if you use only bitmaps on you timeline animation in AnimateCC. And I would have stooped there, but there will be quite a few animations. I want each character to be slightly different, and at 31 fps running cycle, and with a few cycles that will turn a few degrees, it adds up really really fast and the resulting game would take forever to load. I have also observed that the vector graphics, remained in vector format after you use them in OpenFL. This reduces the size of the game by a huge amount. Even in local testing this was quite obvious.  So I have redrawn the rendering in vector format, this would also allow me to make the small customization that I want for each character. Test it some more, and saw that it work well on my laptop (which is a bit powerful) and on my Android Phone (also a bit powerful). I consulted with Greg about this, and together we decided to go with the vector format so we can keep the size in check.

But then…

I have added another slightly different character (change only the color and the head design) and the performance took a bit hit. This was not good, I thought that the result from my previous test was solid and I could go ahead using this method. Well… nope.

Then I remember about this optimizations stuff we sometimes did in the flash environment by drawing a vector to bitmap at runtime, wich kept the size small but also improved the performance quite a bit. So after a look around the web to see what can be done about it I have found TileMap. Unfortunately I could not figure it out how to make it work with my problem, so after a couple of hours of trying to make  it work, I decided to switch course and just try to remake the vector animation using a rougher approach.

The idea is pretty simple, take the MovieClip frames, draw them into separate bitmaps, put the bitmaps into an array, and display one bitmap every other frame on an enter frame event.

Here is the code:


  1. package com.cosmindolha.recessmaster;
  2. import openfl.display.Sprite;
  3. import openfl.display.MovieClip;
  4. import openfl.display.Bitmap;
  5. import openfl.display.BitmapData;
  6. import;
  7. import openfl.Lib;
  8. /**
  9. * ...
  10. * @author Cosmin Dolha
  11. */
  12. class Runner extends Sprite
  13. {
  14. var mcFramesArray:Array;
  15. var allFrames:Int;
  16. var everyOtherFrame:Bool=false;
  17. var runnerType:Int;
  18. public function new(type:Int)
  19. {
  20. super();
  21. runnerType = type;
  22. init();
  23. }
  24. function init()
  25. {
  26. mcFramesArray = new Array();
  27. var dmc:MovieClip = new MovieClip();
  28. switch(runnerType)
  29. {
  30. case 0:
  31. dmc = new RunnerTemplate();
  32. case 1:
  33. dmc = new RunnerTemplateB();
  34. case 2:
  35. dmc = new RunnerTemplate();
  36. case 3:
  37. dmc = new RunnerTemplateB();
  38. case 4:
  39. dmc = new RunnerTemplate();
  41. }
  42. var nw:Int =;
  43. var nh:Int =;
  45. allFrames = dmc.totalFrames;
  46. var bitmapData:BitmapData;
  48. for (i in 0...allFrames)
  49. {
  51. dmc.gotoAndStop(i);
  53. bitmapData = null;
  55. bitmapData = new BitmapData(nw, nh+5, true, 0x000000);
  56. bitmapData.draw(dmc, true);
  58. var bmp:Bitmap = new Bitmap(bitmapData);
  60. bmp.smoothing = true;
  61. mcFramesArray.push(bmp);
  63. }
  65. addEventListener(Event.ENTER_FRAME, onEveryFrame);
  66. }
  67. function updateFrame():Void
  68. {
  69. removeChildren();
  71. addChild(mcFramesArray[currentFrame]);
  73. currentFrame++;
  74. if (currentFrame == allFrames)
  75. {
  76. currentFrame = 0;
  77. }
  78. }
  79. function onEveryFrame(e:Event):Void
  80. {
  81. if (everyOtherFrame)
  82. {
  83. updateFrame();
  84. }
  85. everyOtherFrame = !everyOtherFrame;
  87. }
  89. }

I am pretty sure the TileMap would work better, and I will probably give it another try at some point, but for now this solution works good and I can move on to the other parts of the game.

Christmas is almost here, hmm I wonder what I want for this Christmas. Books are always nice 🙂 especially those with “The Art Of” in the tittle.

Share this

Poser, the super useful tool for making animation/illustration for 2d games

Categories games, HTML5, MyArtWork

Everybody has a completely different way of learning things, when I started developing games and making animation (14 years ago), I jumped right into 3D, without any formal art training. While I was able to “cheat” my way around and use 3D tools to make the artwork required for the games I was working on, the lack of formal training was obvious and to some extent still is in my work today. Now that I am all “grown -up” I see the value in learning how to draw/sketch/light a scene, use color, shapes etc. to convey a message, instill a mood etc. This why I am committed to continuing to take the awesome art classes from I am barely scratching the surface, I am just beginning to see it now.

I have started a new browser educational game with @MrNussbaum and I needed a few different references for drawing the title page character. I could go over to Pinterest and search for some Character Design Reference, but that might take some significant amount of time, and there is a very small chance that I will be able to find exactly the pose I want. You can, if you managed to learn the necessary skill, to draw it from imagination, but I am not there yet.

Here comes Poser to the rescue.

After looking for a few things that might help, I remember the time I used to play with Poser, and how marvelous it was, almost magical. I quickly went to Smithmicro’s page, just to see how it had evolved since the last time I have opened it, which I think was version 5 or 6. Needless to say, I was not disappointed, the current version is 11, and it looked like the program evolved nicely over the years. With another happy accident, it was on sale, so I got it really cheap.

This week I am working on a few character running cycles and Poser walk designer will save me a lot of time. Despite the many years that have passed since my last encounter, I found it easy to get right back into it and do my job, the YouTube videos also helped :). I feel like those years of fulling around with 3D Tools were not a waste of time after all.

Here is the pose with the drawing side by side.

Thank you, Poser 🙂

Share this

Experimenting with OpenFL, DragonBones and Animate CC – simple Mobile browser game

Categories games, HTML5, OpenFL, Starling

This is what I ended up doing, and here it is on GiHub.

I am on a quest to find out how to build a mobile browser game as fast as I can, while also keeping the quality in check. For this I need an efficient production process, and if possible, I would like to keep using the tools and techniques that I am familiar with.

Quick background and current stats: I have been using Flash (now Animate CC) since the Macromedia era and Flash 5, that is more or less 14 years of flash dev. I do the code and the artwork/animation and I am currently studding how to draw better (in self thought way) at, they are awesome, while also experimenting with Haxe (also in self thought way). But most of my time it is spent raising my son, which is the most amassing adventure ever 🙂.

Back to work. In order to keep game production costs as low as possible, in my pipeline I need to:

  1. Be able to create 2D Animations fast, visually.
  2. Build UI visually.
  3. When there is a need to make small adjustments in UI or in the Animation, the update process should be seamless and fast.
  4. Code in a similar ActionScript 3 way, using events, objects, etc..
  5. Be able to prepare the code in such a way that modifications during the production are relatively easy to do, because you will always need to accommodate something unexpected.
  6. The code should also be scalable, so new levels or functionality are possible without breaking the entire app.
  7. The browser game (or app) should run on a mobile device, in the browser obviously.

I found Haxe to be the perfect match for my needs, while building Mr Nussbaum Boardwalk Challenge. Unfortunately Flambe was hard to bend to my will, so I am now investing my (extremely limited) energy into OpenFL.

OpenFL has a lot in common with ActionScript 3, so at times it doesn’t feel like I switched to a new language at all.

For the IDE, I used HaxeDevelop for a while, even gave Visual Studio IDE a try, but now I am back to FlashDevelop, because during my coding in HaxeDevelop there were a lot of times when the code would not compile at the first try, and only after about 3 to 5 times, without me touching the code. This obviously makes the development process extremely difficult because you never know if the fault is in your code, or the IDE is misbehaving again. So now I have switched back to FlashDevelop, and I will see if I the issues persists.

Here are the tools I use:

  1. Haxe 3.4.3, with the libs dragonbones: 5.0.0, openfl: 6.2.0, starling: 1.8.11
  2. Animate CC 2017.5 with the OpenFL Plugin 1.0.0
  3. DragonBones Pro 5.5
  4. FlashDevelop

The idea was to build a fun crossbow toy, that shoots cute arrows into bubbles of soap. From this, I will probably expand and build some simple educational game, but for production pipeline and tech testing, the simple prototype is enough. The idea to start with a toy (something fun) and build on top of that, came from reading “The Art of Game Design” by Jesse Schell, an eye opening book on how to make games.


After I was happy with the crossbow design, I started to test different animation editors, and decided to remain with Dragon Pro, in part because it had support for OpenFL, but also because it worked with AS3 and Starling, so in the case I wanted to develop the project in AS3, I would be able to reuse the artwork.

After a bit of trial and error and some YouTube watching, I was able to accomplish exactly what I wanted with the corners of the crossbow turning inside when you pull it back. So this is how the crossbow armature looks like in DragonBones, and if you want to check it out even more, you can find all the DragonBones files on GitHub.

Now we move to integrating the animation with OpenFL, and unfortunately things started to break, one after another:

First attempt, render the animation with Startling 1.8, which didn’t work. After some digging around the web, I find that in Starling 1.8 the mesh animation is not supported.

Second attempt, using the OpenFL render, it only showed parts of the animation with the mesh deformation, also on Samsung Tab A (some old version), it crashed the Chrome browser. I tried different export data options from DragonBones, neither of them worked.

But, the examples seemed to work fine, so maybe they are made with an earlier version of DragonBones and there is something funny in the newer data format. Who knows?

Third attempt, build the animation în DragonBones, export it as frame sequence (alpha png). Create a new OpenFL project in Animate CC, import the image sequence inside an MovieClip (that you export it for ActionScript), and just like that, it all worked.

This way also lets me augment the animation inside Animate CC, and also lets me build the UI in a visual way. It is kind of the perfect combination.

Here is the catch, the performance is not great, it works fine on medium to higher end mobile devices using Chrome, but Firefox won’t play nice.

So I tested on some more browsers:

  • On Chrome it works fine, but no fullscreen from the compiled project (might have to check the html file).
  • Firefox – low fps, and breaks after a while.
  • Firefox Focus – won’t show the hole app.
  • Opera – works perfectly, even the full screen
  • Opera mini – works, no fullscreen
  • Dolphin – seems to work really well, but no fullscreen
  • Cm Browser – works, but no fullscreen
  • Via Browser – works, but no fullscreen

So it seems that only Firefox causes problems

Devices tested:

  • iPhone 6s, it works perfectly
  • iPad 2, not usable, it has very low fps
  • Samsung Tab A, not usable very low fps (CPU 1.2 GHz)
  • Huawei nova (CPU 2 GHz), works great (except Firefox)

Other issues and limitations:

Animation on the timeline that use masks, wont show the right way in OpenFL, so don’t use mask in animations. Another big issue will be memory footprint and file size when you use a lot of animations. Probably a better way would be to build UI, and simple animations in Animate CC, and use DragonBones animations without the mesh editor for characters. Hopefully Starling 2 will be ported to OpenFL soon, and we will be able to use DragonBones without a problem with OpenFL and Starling, while keeping Animate CC for UI and other simple animations.

In conclusion, if you (or the client) are OK with the limitations, you can build a browser game or app, quite fast when you use OpenFL in combination with Animate CC and DragonBones, and because the community is really getting into it, I am pretty sure the tools will evolve fast and the remaining obstacles will fall away soon enough.

If anyone else has tried different things on Animate CC, OpenFL Dragon Bones do share with links in the comments.



I am taking on new projects, (I will be opening new projects spots in March 2018) let’s talk


Share this

Source code for a very simple HTML5 Toddlers Game created using Haxe and OpenFL

Categories games, HTML5

Jump to source code.

You can see my son playing with it here, and the full game here, it’s in Romanian, it says the animal on click (I mean touch, but I am not used to this click/touch thing yet), or asks for the animal location when you press the upper right button (asking mode). It’s very basic without any UI effects, because my wife told me so, she is a Psychologist, so she knows better about this stuff, also after watching a lot of Grand Designs episodes, I have come to the conclusion that if you don’t listen to your wife you make dumb mistakes.

Most of the hard work on this game were the drawings, once I had those done, coding everything was pretty straight forward. Prior to this game, I did the MrNussbaums’s Boardwalk Challenge, which was way more complex in scope. That game was done in Flambe., and my first project in Haxe. While I did like Flambe, once I got used with the architecture, I did find adapting the game to the various screen sizes to be quite hard (you only got “scale”, and not “width” proprieties of your game objects). So when I started this new game, some time have already passed and OpenFL seemed the better candidate. Also I didn’t need the swf output since, this was going to be used mostly on mobile devices.

Here is the game specs doc:

Game scope: Learning new words (animals, in this case) using images and sound association.

Target Device use: mobile phones, tablets, mostly Android, but must work on iOS too.

Screen Orientation: must work both in landscape and portrait mode.

Screen sizes: must adapt to various screen resolutions and aspect ratios.

Design considerations: Since the target audience is of such small age, only 3 animals are shown on a screen at a time. Animations, or sound effects are not useful in this case since they would create a big distraction on a very easy to distract user (have you seen how easy toddlers loose concentration, almost as easy as us grownups 🙂 )

The game interaction:

1. The player (a very small child) touches a card and the sound associated is played. She can change the screen animals using the left or right navigation buttons, which loops the cards on the screen.

2. There is a second mode to play the game, when the child or parent touches the upper right button, “the question” mode will start playing. In this mode, the game asks the child where a particular animal is located on the screen. If the child answer correctly, a congratulation sound is played, else the game says the card that was touched and then asks again for the animal, until the child answers correctly, reinforcing the right association and thus teaching the word.

The Source code, together with all the artwork are here.

Prerequisites. To compile the code you need Haxe, OpenFL and Actuate together with your favorite IDE, I use HaxeDevelop.

Reasons to use OpenFL:

  • You don’t like to code in JavaScript
  • You like a more structure  (and scalable) way of doing things.
  • Mostly you will use it because you are an ActionScript developer and want to code in a familiar way,
  • You hate JavaScript ( have no idea why anyone would choose to hate a certain technology, but some people do, so)
Here is the full source code:

This is the Main.hx file:




  1. package primelecuvinte;
  3. import openfl.display.Sprite;
  4. import openfl.display.BitmapData;
  5. import openfl.display.Bitmap;
  6. import openfl.display.StageDisplayState;
  7. import openfl.utils.Assets;
  8. import openfl.Lib;
  9. import;
  10. import;
  11. import motion.actuators.SimpleActuator;
  12. import motion.easing.Linear;
  13. import motion.Actuate;
  14. /**
  15. * ...
  16. * @author Cosmin Dolha
  17. */
  18. class Main extends Sprite
  19. {
  20. var bg:Bitmap;
  21. var gameStarted:Bool;
  22. var bgGameSp:Sprite;
  23. var scale:Float;
  24. var bgsp:Sprite;
  25. var title:Sprite;
  26. var intsrt:Sprite;
  28. public function new()
  29. {
  30. super();
  32. buildGameUI();
  34. onResize(null);
  35. stage.addEventListener(Event.RESIZE, onResize);
  37. }
  38. private function picSp(pic:String, sp:Sprite):Void
  39. {
  40. //empy sprite first
  41. if (sp.numChildren &gt; 0)
  42. {
  43. sp.removeChildren();
  44. }
  45. var bd:BitmapData = Assets.getBitmapData('img/$pic');
  46. var bmp = new Bitmap(bd);
  48. sp.addChild(bmp);
  50. }
  51. private function buildGameUI():Void
  52. {
  53. bgsp = new Sprite();
  54. title = new Sprite();
  55. intsrt = new Sprite();
  57. bgGameSp = new Sprite();
  59. bgGameSp.alpha = 0;
  61. addChild(bgGameSp);
  63. addChild(bgsp);
  64. addChild(title);
  65. addChild(intsrt);
  67. picSp("bg.png", bgGameSp);
  68. picSp("start_screen.jpg", bgsp);
  69. picSp("title.png", title);
  70. picSp("instr.png", intsrt);
  72. addEvents();
  73. }
  75. function addEvents():Void
  76. {
  77. stage.addEventListener(MouseEvent.CLICK, onStartGame);
  78. }
  80. private function onStartGame(e:MouseEvent):Void
  81. {
  83. Assets.getSound("img/sillent.mp3").play();
  85. stage.removeEventListener(MouseEvent.CLICK, onStartGame);
  87. stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
  89. Actuate.tween (bgGameSp, 1, { alpha: 1 }).ease (Linear.easeNone).onComplete(startMyGame);
  91. }
  93. private function startMyGame():Void
  94. {
  95. gameStarted = true;
  96. bgsp.visible = false;
  97. intsrt.visible = false;
  98. title.visible = false;
  100. bgsp.removeChildren();
  101. intsrt.removeChildren();
  102. title.removeChildren();
  104. removeChild(title);
  105. removeChild(intsrt);
  106. removeChild(bgsp);
  108. var gamePlay:GamePlay = new GamePlay();
  109. Lib.current.stage.addChild(gamePlay);
  110. }
  112. private function onResize(e):Void
  113. {
  114. var scaleX = stage.stageWidth / 1280;
  115. var scaleY = stage.stageHeight / 720;
  117. scale = Math.min(scaleX, scaleY);
  119. stage.scaleX = scale;
  120. stage.scaleY = scale;
  122. stage.x = (stage.stageWidth - 1280 * scale) / 2;
  123. stage.y = (stage.stageHeight - 720 * scale) / 2;
  125. var pmode:Bool = stage.stageWidth &gt; stage.stageHeight;
  127. if (!gameStarted)
  128. {
  130. if (pmode)
  131. {
  133. fitScreenP(bgsp);
  135. centerScreenP(title);
  136. centerScreenP(intsrt);
  138. intsrt.y = stage.stageHeight - intsrt.height*1.5;
  139. title.y = title.height*1.5;
  141. }
  142. if (!pmode)
  143. {
  144. fitScreenBgL(bgsp);
  146. fitScreenL(title);
  147. centerScreenL(intsrt);
  149. intsrt.y = stage.stageHeight - intsrt.height*4;
  150. title.y = title.height;
  152. }
  154. }
  156. fitScreenStretch(bgGameSp);
  158. }
  159. private function fitScreenStretch(sp:Sprite):Void
  160. {
  161. sp.width = stage.stageWidth;
  162. sp.height = stage.stageHeight;
  163. }
  164. private function fitScreenP(sp:Sprite):Void
  165. {
  166. sp.width = stage.stageWidth;
  168. sp.scaleY = sp.scaleX;
  169. sp.x = Math.floor(stage.stageWidth / 2) - sp.width / 2;
  170. sp.y = Math.floor(stage.stageHeight / 2) - sp.height / 2;
  171. }
  173. private function centerScreenP(sp:Sprite):Void
  174. {
  175. sp.scaleX = (stage.stageHeight / 720)*1.5;
  176. sp.scaleY = (stage.stageHeight / 720)*1.5;
  177. sp.x = Math.floor(stage.stageWidth / 2) - sp.width / 2;
  178. sp.y = Math.floor(stage.stageHeight / 2) - sp.height / 2;
  179. }
  181. private function fitScreenL(sp:Sprite):Void
  182. {
  183. sp.scaleX = (stage.stageHeight / 720 );
  184. sp.scaleY = (stage.stageHeight / 720);
  185. sp.x = Math.floor(stage.stageWidth / 2) - sp.width / 2;
  186. sp.y = Math.floor(stage.stageHeight / 2) - sp.height / 2;
  187. }
  189. private function fitScreenBgL(sp:Sprite):Void
  190. {
  191. sp.scaleX = (stage.stageHeight / 720);
  192. sp.scaleY = (stage.stageHeight / 720);
  193. sp.x = Math.floor(stage.stageWidth / 2) - sp.width / 2;
  194. sp.y = Math.floor(stage.stageHeight / 2) - sp.height / 2;
  195. }
  197. private function centerScreenL(sp:Sprite):Void
  198. {
  199. sp.scaleX = (stage.stageHeight / 720 );
  200. sp.scaleY = (stage.stageHeight / 720);
  201. sp.x = Math.floor(stage.stageWidth / 2) - sp.width / 2;
  202. sp.y = Math.floor(stage.stageHeight / 2) - sp.height / 2;
  203. }
  205. }

This is the GamePlay.hx file


  1. package primelecuvinte;
  3. /**
  4.  * ...
  5.  * @author Cosmin Dolha
  6.  */
  7. import openfl.display.Sprite;
  8. import openfl.display.BitmapData;
  9. import openfl.display.Bitmap;
  10. import openfl.display.Stage;
  11. import openfl.display.StageDisplayState;
  12. import;
  13. import openfl.utils.Assets;
  14. import openfl.Lib;
  15. import;
  16. import;
  17. import motion.actuators.SimpleActuator;
  18. import motion.easing.Linear;
  19. import motion.Actuate;
  20. import Random;
  21. import haxe.Timer;
  22. class GamePlay extends Sprite
  23. {
  24.     var cardsHolderSp:Sprite;
  25.     var cardLeft:Sprite;
  26.     var cardMiddle:Sprite;
  27.     var cardRight:Sprite;
  28.     var navRight:Sprite;
  29.     var navLeft:Sprite;
  30.     var autoPlayOff:Sprite;
  31.     var autoPlayOn:Sprite;
  32.     var scale:Float;
  33.     var myStage:Stage;
  34.     var soundChannel:SoundChannel;
  35.     var playingSound:Bool;
  36.     var picsArray:Array<string>;
  37.     var totalPages:Int = 3;//starts at 0
  38.     var currentPage:Int = 0;
  39.     var autoPlayPickedCard:Int;
  40.     var cardClicked:Int;
  41.     var autoPlayMode:Bool;
  42.     var id:Int;
  45.     public function new()
  46.     {
  48.         super();
  50.         //the name of the picture and the mp3 sound associated with each
  51.         picsArray = ["albina", "vaca", "bufnita", "gasca", "caine", "oaie", "lup", "lama", "lebada", "papagal", "peste", "magar"];
  53.         soundChannel = new SoundChannel();
  55.         cardsHolderSp = new Sprite();
  57.         cardLeft = new Sprite();
  58.         cardMiddle = new Sprite();
  59.         cardRight = new Sprite();
  61.         navRight = new Sprite();
  62.         navLeft = new Sprite();
  65.         autoPlayOn = new Sprite();
  66.         autoPlayOff = new Sprite();
  69.         addChild(cardsHolderSp);
  71.         addChild(navRight);
  72.         addChild(navLeft);
  73.         addChild(autoPlayOn);
  74.         addChild(autoPlayOff);
  78.         cardsHolderSp.addChild(cardLeft);
  79.         cardsHolderSp.addChild(cardMiddle);
  80.         cardsHolderSp.addChild(cardRight);
  84.         gotoPage(0);
  86.         picSp("navarrow.png", navRight);
  87.         picSp("navarrowl.png", navLeft);
  90.         picSp("autooff.png", autoPlayOff);
  91.         picSp("autoon.png", autoPlayOn);
  95.         cardLeft.addEventListener(MouseEvent.CLICK, leftClick);
  96.         cardMiddle.addEventListener(MouseEvent.CLICK, middleClick);
  97.         cardRight.addEventListener(MouseEvent.CLICK, rightClick);
  100.         navRight.addEventListener(MouseEvent.CLICK, navRightClick);
  101.         navLeft.addEventListener(MouseEvent.CLICK, navLeftClick);
  103.         autoPlayOn.addEventListener(MouseEvent.CLICK, autoPlayOnClick);
  104.         autoPlayOff.addEventListener(MouseEvent.CLICK, autoPlayOffClick);
  106.         addEventListener(Event.ADDED_TO_STAGE, onAdded);
  108.         autoPlayOn.visible = false;
  109.         Lib.current.stage.addEventListener(MouseEvent.CLICK, goFullScreen);
  111.     }
  112.     private function goFullScreen(e:Event):Void
  113.     {
  115.         Lib.current.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
  116.     }
  117.     private function anotherQuestionDelayed(e:Event):Void  
  118.     {
  119.         Timer.delay(anotherQuestion, 1500);
  120.     }
  122.     private function anotherQuestion():Void
  123.     {
  125.         autoPlayPickedCard =, 2);
  127.         askQuestion();
  128.     }
  130.     private function startAutoPlayGame():Void
  131.     {
  132.         autoPlayMode = true;
  133.         anotherQuestion();
  134.     }
  136.     function askQuestion():Void  
  137.     {
  138.         soundChannel.stop();
  140.         soundChannel = Assets.getSound("img/unde_este.mp3").play();
  141.         soundChannel.addEventListener(Event.SOUND_COMPLETE, askingFinished );
  145.     }  
  147.     function telTheCardClicked(e:Event):Void  
  148.     {
  149.         soundChannel.stop();
  151.         Assets.getSound("img/"+picsArray[id*3+cardClicked]+".mp3").play();
  152.         soundChannel.addEventListener(Event.SOUND_COMPLETE, repeatQuestionDelayed );
  153.     }  
  156.     function repeatQuestionDelayed(e:Event):Void  
  157.     {
  158.         Timer.delay(repeatQuestionD, 1500);
  159.     }
  161.     function repeatQuestionD():Void
  162.     {
  163.         soundChannel.stop();
  165.         soundChannel = Assets.getSound("img/unde_este.mp3").play();
  166.         soundChannel.addEventListener(Event.SOUND_COMPLETE, askingFinished );
  167.     }
  169.     function repeatQuestion(e:Event):Void
  170.     {
  171.         repeatQuestionD();
  172.     }
  174.     function checkAnswer():Void  
  175.     {
  176.         if (autoPlayPickedCard == cardClicked)
  177.         {
  178.             soundChannel.stop();
  180.             soundChannel = Assets.getSound("img/bravo.mp3").play();
  181.             soundChannel.addEventListener(Event.SOUND_COMPLETE, anotherQuestionDelayed );
  183.         }else{
  185.             soundChannel.stop();
  187.             soundChannel = Assets.getSound("img/acolo_este.mp3").play();
  188.             soundChannel.addEventListener(Event.SOUND_COMPLETE, telTheCardClicked );
  190.         }
  192.     }
  193.     function playPickedCardSound():Void  
  194.     {
  195.         soundChannel.stop();
  197.         soundChannel = Assets.getSound("img/"+picsArray[id*3+autoPlayPickedCard]+".mp3").play();
  200.     }
  202.     private function askingFinished(e:Event):Void
  203.     {
  204.         soundChannel.removeEventListener(Event.SOUND_COMPLETE, askingFinished );
  205.         playingSound = false;
  207.         playPickedCardSound();
  208.     }
  211.     private function autoPlayOffClick(e:MouseEvent):Void
  212.     {
  213.         autoPlayOff.visible = false;
  214.         autoPlayOn.visible = true;
  215.         startAutoPlayGame();
  217.     }
  219.     private function autoPlayOnClick(e:MouseEvent):Void
  220.     {
  221.         autoPlayOff.visible = true;
  222.         autoPlayOn.visible = false;
  223.         autoPlayMode = false;
  225.     }
  227.     function gotoPage(ids:Int) :Void
  228.     {
  229.         id = ids;
  231.         picSp(picsArray[id*3]+".jpeg", cardLeft);
  232.         picSp(picsArray[id*3+1]+".jpeg", cardMiddle);
  233.         picSp(picsArray[id * 3 + 2] + ".jpeg", cardRight);
  235.         if (autoPlayMode)
  236.         {
  237.              anotherQuestion();
  238.         }
  240.     }
  242.     private function navRightClick(e:MouseEvent):Void
  243.     {
  244.         currentPage++;
  245.         if (currentPage > totalPages)
  246.         {
  247.             currentPage = 0;
  248.         }
  250.         gotoPage(currentPage);
  251.     }  
  253.     private function navLeftClick(e:MouseEvent):Void
  254.     {
  255.         currentPage--;
  256.         if (currentPage < 0)
  257.         {
  258.             currentPage = totalPages;
  259.         }
  260.         gotoPage(currentPage);
  261.     }
  264.     private function cardsClicked(cardID:Int):Void
  265.     {
  266.         cardClicked = cardID;
  268.         if (!playingSound && !autoPlayMode)
  269.         {
  270.             playingSound = true;
  271.             soundChannel.stop();
  272.             soundChannel = Assets.getSound("img/"+picsArray&#91;id*3+cardID]+".mp3").play();
  273.             soundChannel.addEventListener(Event.SOUND_COMPLETE, onSoundFinished );
  275.         }
  278.         if (autoPlayMode)
  279.         {
  280.             checkAnswer();
  282.         }
  283.     }
  284.     private function onSoundFinished(e:Event):Void
  285.     {
  286.         soundChannel.removeEventListener(Event.SOUND_COMPLETE, onSoundFinished );
  287.         playingSound = false;
  288.     }
  290.     private function leftClick(e:MouseEvent):Void
  291.     {
  292.         cardsClicked(0);   
  293.     }
  295.     private function middleClick(e:MouseEvent):Void
  296.     {
  297.         cardsClicked(1);
  299.     }  
  301.     private function rightClick(e:MouseEvent):Void
  302.     {
  303.         cardsClicked(2);
  304.     }
  306.     private function onAdded(e:Event):Void
  307.     {
  308.         removeEventListener(Event.ADDED_TO_STAGE, onAdded);
  310.         onResize(null);
  311.         stage.addEventListener(Event.RESIZE, onResize);
  315.     }
  318.     private function onResize(e):Void
  319.     {
  320.         var scaleX = stage.stageWidth / 1280;
  321.         var scaleY = stage.stageHeight / 720;
  323.         scale = Math.min(scaleX, scaleY);
  324.         var buttonScale = scaleY;
  326.         var pmode:Bool = stage.stageWidth > stage.stageHeight;
  328.         if (pmode)
  329.         {
  331.             cardLeft.x = 0;
  332.             cardMiddle.x = 420;
  333.             cardRight.x = 840;     
  335.             cardLeft.y = 0;
  336.             cardMiddle.y = 0;
  337.             cardRight.y = 0;
  338.             fitScreenL(cardsHolderSp);
  340.             var buttonScale = scaleY;
  342.         }  
  344.         if (!pmode)
  345.         {
  347.             cardLeft.y = 0;
  348.             cardMiddle.y = 420;
  349.             cardRight.y = 840;
  351.             cardLeft.x = 0;
  352.             cardMiddle.x = 0;
  353.             cardRight.x = 0;   
  355.             fitScreenP(cardsHolderSp);
  357.             buttonScale = scaleY*0.75;
  358.         }
  359.         navRight.scaleX = buttonScale;
  360.         navRight.scaleY = buttonScale; 
  362.         navLeft.scaleX = buttonScale;
  363.         navLeft.scaleY = buttonScale;
  366.         autoPlayOff.scaleX = buttonScale;
  367.         autoPlayOff.scaleY = buttonScale;      
  369.         autoPlayOn.scaleX = buttonScale;
  370.         autoPlayOn.scaleY = buttonScale;
  373.         autoPlayOn.x = stage.stageWidth - autoPlayOn.width;
  374.         autoPlayOff.x = stage.stageWidth - autoPlayOff.width;
  376.         navRight.x = stage.stageWidth - navRight.width;
  378.         if (pmode)
  379.         {  
  381.             navRight.y = stage.stageHeight - navRight.height;
  382.             navLeft.y = stage.stageHeight - navRight.height;
  384.         }
  385.         if (!pmode)
  386.         {
  388.             navRight.y = stage.stageHeight/2 - navRight.height/2;
  389.             navLeft.y = stage.stageHeight / 2 - navRight.height / 2;
  390.         }
  391.     }
  393.     private function fitScreenL(sp:Sprite):Void
  394.     {
  395.         sp.scaleX = stage.stageWidth / 1280;
  396.         sp.scaleY = stage.stageWidth / 1280;
  397.         sp.x = Math.floor(stage.stageWidth / 2) - sp.width / 2;
  398.         sp.y = Math.floor(stage.stageHeight / 2) - sp.height / 2;
  399.     }
  401.     private function fitScreenP(sp:Sprite):Void
  402.     {
  403.         sp.scaleX = stage.stageHeight / 1280;
  404.         sp.scaleY = stage.stageHeight / 1280;
  406.         sp.x = Math.floor(stage.stageWidth / 2) - sp.width / 2;
  407.         sp.y = Math.floor(stage.stageHeight / 2) - sp.height / 2;
  408.     }
  410.     private function picSp(pic:String, sp:Sprite):Void
  411.     {
  412.         //empy sprite first
  413.         if (sp.numChildren > 0)
  414.         {
  415.             sp.removeChildren();
  416.         }
  417.         var bd:BitmapData = Assets.getBitmapData('img/$pic');
  418.         var bmp = new Bitmap(bd);
  419.         bmp.smoothing = true;
  420.         sp.addChild(bmp);
  422.     }
  423. }

Thats it, pretty simple code, nothing fancy in here. I hope you can take chunks from it and use it in you HTML5 game/app.


Share this

Drawing an Owl for my new upcoming small children’s game

Categories game art, games, MyArtWork


This will be my first game in collaboration with my dear wife. She came up with the idea, and I am trilled to finally draw her in game development, little by little. I won’t reveal too much about it for now, it will be available first in Romanian and then translated to English. The game will be for really small children, our son inspired my wife and most likely will be the beta tester :).

I will have to draw a lot for this game. To get my drawing in a better shape I have subscribed to I am taking the Environment Design with Nathan Fowkes and Gesture Drawing with Alex Woo, and last week I went trough Drawing Fundamentals with Thomas Fluharty. I will be staying on Schoolism for sometime, since I have probably discovered the quickest way to improve my art skills. They are awesome!

Here is me, drawing the owl from above.

I hope you liked it 🙂



Share this

Creating Mr. Nussbaum’s Boardwalk Challenge

Categories games

From time to time, when the stars align just the right way, Greg and I make awesome educational games. He is a fantastic Game Designer, and his games are truly unique.

I usually take the opportunity and push it a bit beyond my own capabilities. This obviously stretches the development time and leaves me drained of all energy. But I enjoy every second, and I am always extremely proud with the end result.

In March 2016 my beautiful son arrives into this wonderful world. Never before I felt so happy in my life. I took a couple of months off, so I can help the new mommy and also adjust to the new parent role.

After 4 months, exhausted, thrilled, still adjusting to this new role and the huge responsibility of being a parent, I slowly go back to my own game development. About this time, Greg reaches out to me with a new game. I said OK, we will do it,  but have to start in October. That’s when the baby will be 6 months, and mommy goes back to work, and in my naivety I thought my own game will be finished. But I set a date, and said the work on the new game will start then no matter what.

So it id.

I have received the detailed description from Greg, so the development is officially on the way. Let me take this time to tell you something, Greg’s descriptions document is so good and well planned that it doesn’t change throughout the development. This is extremely rare, and one of the many reasons I enjoy working with him. The majority of software failures are due to a bad or incomplete plan.

With a good plan in hand, it’s time to decide, flash or HTML5. We decide it is a good idea to publish it in HTM5, so that it can run on iPad, or Android tablets and will more or less future proof. It took a couple of days to investigate what’s out there, and what tools we can use to reach our goals. I knew I wanted some sort of OOP programming that will be then converted (transpiled) to JavaScript and HTML5. I also wanted the game to work the same on iPad, Android and PC with all the various browsers out there.

I remembered something about HAXE from somewhere, so I started looking into it. After trying out different engines, I found that Flambe was working well across different browsers and OS, and also was able to publish the code to swf. So flambe it is.

Moving from FlashDevelop to HaxeDevelop was easy, making Flambe work, was not. It needed some patch in the source code, nothing too hard, and after some good googling around I find exactly what needs to be done, but I am afraid that for beginners, this might be off-putting.

We are up and running, so actual coding will start soon, but first I need to structure the work ahead, I break down all the major tasks into smaller ones. The game is made up by 5 games. You play the first, game to earn points that you use in order to gain access to other 4 fun games, and you play those games in order to gain points that you can exchange for items in the store. These items, get “printed” on certificates that kids can save to their devices.

The first game requires you to arrange the numbers on the screen in the right order, I named it “Earn Tokens”. Nothing too complicated to do in here, the prototype was up and running in no time.

The second game, is “Whack the Pirates”. By this time, I was already making the layouts, establishing the main themes, but didn’t settled for a look yet. First code and layout, then later when everything pretty much works the way it supposed to, I’ll move on to the artwork.

So far everything works pretty good, there is an annoying thing in Whack the pirates, where because of Flambe limitation, I can’t use masks properly, so that the characters hide when going back into their holes. But things move well and it seems that this new Haxe/Flambe thing is not bad at all, and I am very happy with the progress being made.

At this time it’s worth mentioning that development was being done under some tight schedule, in the time when the baby was sleeping, and, when mommy got back from work. Leaving me with almost zero personal downtime, before going to sleep.

Moving forward to Air Hockey, I realized it’s going to be a bit more challenging, but nothing that I can’t handle. For Air Hockey I just used some simple trigonometry, and simple point/distance collision detection, nothing too fancy, it worked.

Next one will be Ski-ball. After looking at all the SkeeBall games on YouTube that I can find, I realized, I won’t be able to get away with some simple tricks, I actually started to build it using the same tricks in Air Hokey, but it didn’t cut it this time. It needed a physics engine. After some research, I found Nape. It was an excellent choice, it did what I wanted and I will soon discover It did even more stuff that I didn’t even know I needed.

In order to edit the physics shapes you need a physics editor that can export the shapes back to Haxe, for this I bought PhysicsEditor. It does a good job at editing the shapes, but you need to trim the generated output code, so that you can use it effectively inside your game.

Soon after the Ski-ball game prototype was done, we hit a problem. The game won’t scale nicely. There is now way to scale things inside in a similar way to the flash based display list, so to make it work, you need to apply a scale calculation to everything, from math calculations inside the Air hockey game, to individual graphics. At this point I was afraid that I will need to apply the same scale calculations to each and every single node in the data provided by the physics editor, a task that would be extremely time consuming, not to mention every time that you would need to make an adjustment you would redo the whole process. Nightmare! Luckily, the shapes have a scale property, and the task to adjust for the scale is not that bad.

Finally I move to the final game Roll the Ball, and I soon discover the sensors inside Nape and I am in awe. They are awesome! Nape is Awesome!

Prototyping done.

Without getting too much into details, Flambe is really cool, but beware of the limitations, no sound on some iOS devices, no easy system for adjusting to different screen resolutions, no masking, no printing, no easy way to combine multiple image into a single one, for say download or other uses (like in character customization), and the entity/component system might be a bit awkward in the beginning. But if you don’t need printing, mask, downloading generated images, it’s a pretty solid engine, that works well on different devices, inside the different browsers. The sound issue is a problem not exactly with flambe, rather with Apple’s way of doing things, so much for “promoting” HTML5 on their devices.

After the coding part was mostly done I moved to the Art Work, based on the already made layouts and the place holders characters.

Some of the Art Work was inspired by the works of

After the Art Work was done, I added background music from and sound that I recorded with my phone, making noise using the toys my son plays with.

After some more testing, and bug fixing, the game is completed:

I hope kids will enjoy it for many years to come, and if you like it do share it!

Thank you for reading 🙂




Share this

Abstract #1

Categories abstract paintings, MyArtWork

Today I have installed a brand new program, which I absolutely adore, it’s called ArtRage.

I am starting (hopefully) a new habit of making abstract paintings.

The rule is simple, pick an abstract piece by some of the great abstract artists, and paint something similar, in about 1 to 2 hours, when I get a bit of time-off from my regular work. The scope is to learn how to paint abstract original artwork, but until then, copy FTW!

The #1 is inspired by Alberto Burri Sacco.abstract1

Share this

Background FX live session

Categories Actionscript, game art, Starling

Using my Open Source Particle Designer tool, Angulex to design the background effects in the MathSumRun Trophy Room.

After exploring a bit with the different designs, I settle for a simple colored background particles with some nice starlight textures. This is typical with my design process, I usually start and explore different and more complicated designs, then subtract elements that I find they have too much of a distraction characteristic. It’s a fine line from just enough decorum to over doing it.

The tool lets me explore different options with ease, but it does have some quirks and UI bugs (layering order mishaps). I (obviously) know how to bypass them and until I am releasing MathSumRun, I don’t think I will have the time to fix the bugs.

Also the different textures and backgrounds needed have to be hard-coded, which is probably the first thing I will need to change in the future (after bug-fixing).

For now, it does it’s job perfectly and I can focus on the development of my game 🙂

Share this

Sharing Achievement Badges for MathSumRun

Categories game art

The final set of badges in MathSumRun, this ones rewards you for sharing your achievements on Twitter or Facebook.

Math Fan, for your first share.

mathsumrun fan

Math Preacher, for your first 10 shares on Twitter or Facebook.

mathsumrun preacher

Math Evangelist, for the ultimate player, 30 shares will get you this badge.

mathsumrun evangelist

With this set, I have completed all the achievements badges for the game. Time to setup the remaining screens and implement (code) them in the game. Just in time since Friday is here, so time to relax and enjoy the weekend!

To get the latest updates on the game, subscribe to the MathSumRun Facebook page.

Share this

Time Achievement Badges for MathSumRun

Categories game art, games

Today I am following the previous set, with the new Time Badges you will be able to earn in MathSumRun.

Math Pioneer, you will earn this one after 30 min spent in the game.

mathsumrun pioneer

Math Enthusiast, to get this one you will have to spend 1 hour in the game.

mathsumrun Enthusiast

Math Devotee, to collect this one you will need to accumulate 2 hours in the game.

mathsumrun devotee

To get the latest updates on the game, subscribe to the MathSumRun Facebook page.

Share this

Achievement Badges for MathSumRun

Categories game art, games

MathSumRun is almost complete and now I am in the process of designing different achievement badges, here are the first ones.

Addition Scholar Badge. You will earn this one after answering correctly 30 addition problems in a perfect sequence.

addition scholar badge

Addition Master, you will have to solve, 100 addition problems to earn this one. You will need some concentration to achieve this awesome feat.


The hardest one, Addition Tycoon. You will have to answer without any mistake all 945 problems in the game, making a perfect game.


A few others will follow shortly.

To get the latest updates on the game, subscribe to the MathSumRun Facebook page.


Share this