HTML5

Conway’s Game of Life in haXe [NME & MassiveUnit]

The second day of try{harder} was dedicated to a single topic; test driven development (TDD).

The group was split into pairs and given the task of using TDD to write a solver for the game of life in AS3. After an hour we then threw away everything we had done, swapped partners and repeated the process.

This was extremely valuable for me as I had never written a unit test before. Seeing how different people tackled the same problem was fascinating and informative.

After repeating the process three times Stray asked if I was interested in teaming up with another attendee of the conference Alec McEachran to investigate unit testing in haXe. It was a great idea as it meant we both could investigate how unit testing worked in haXe and it would give me another code example for my talk the following day.

After a brief search we decided on Mike Stead’s MassiveUnit for testing as the testing syntax looked similar to FlexUnit and it contained a toolchain for running the tests on multiple platforms.

An example of a test we wrote is:

  1. package ;
  2. import massive.munit.Assert;
  3. import Grid;
  4.  
  5. /**
  6.  * ...
  7.  * @author MikeC & Alec McEachran
  8.  */
  9.  
  10. class GridTest
  11. {
  12. public var grid : Grid;
  13.  
  14. @Before
  15. public function before():Void
  16. {
  17. grid = new Grid(3, 3);
  18. }
  19.  
  20. @After
  21. public function after():Void
  22. {
  23. grid = null;
  24. }
  25.  
  26. @Test
  27. public function initiallyThereAreNoLiveNeighbors():Void
  28. {
  29. var liveNeighbors = grid.getLiveNeighbors(1, 1);
  30. Assert.isTrue(liveNeighbors == 0);
  31. }
  32.  
  33. @Test
  34. public function liveNeighborCountIsAccurate():Void
  35. {
  36. grid.set(0, 0, true);
  37. grid.set(1, 0, true);
  38. grid.set(2, 1, true);
  39.  
  40. var liveNeighbors = grid.getLiveNeighbors(1, 1);
  41. Assert.isTrue(liveNeighbors == 3);
  42. }
  43.  
  44. }

It should look fairly familiar to anyone who has used FlexUnit before. The metatags @Before @After and @Test perform in exactly the same way as they do in FlexUnit. Another benefit of using munit over the built in testing framework in haXe is that you are given a tool to run tests on all platforms simultaneously:

haxelib run munit test test.hxml

When executed you get something that looks like the following:

Which presents a nice graphical representation of the tests run and which failed (if any).

Once built and tested we decided to give the code a simple visual representation. We wanted to show off the ability for haXe to target multiple platforms. To do this we decided to go with NME which I had been experimenting around with recently.

NME is a library and tool chain for haXe designed to allow the developer to use the flash API on multiple platforms. They achieve this by writing platform targeted version of the flash API. So what this means is code such as the following:

package ;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.geom.Rectangle;
 
/**
 * ...
 * @author MikeC & Alec McEachran
 */
 
class Render
{
 
	private var _cellSize : Int;
	private var _renderTarget : BitmapData;
	private var _rect:Rectangle;
 
	public function new(container:MovieClip, cols:Int, rows:Int, cellSize:Int)
	{
		_cellSize = cellSize;
		_renderTarget = new BitmapData(cols * cellSize, rows * cellSize, false);
		container.addChild(new Bitmap(_renderTarget));
 
		_rect = new Rectangle(0, 0, _cellSize, _cellSize);
	}
 
	public inline function lock():Void
	{
		_renderTarget.lock();
		_renderTarget.fillRect(_renderTarget.rect, 0xff0000);
	}
 
	public inline function renderCell(x:Int, y:Int, isLive:Bool):Void
	{
		if (isLive)
		{
			_rect.x = x * _cellSize;
			_rect.y = y * _cellSize;
			_renderTarget.fillRect(_rect, 0);
		}
	}
 
	public inline function unlock():Void
	{
		_renderTarget.unlock();
	}
 
}

Will compile down to flash, c++ and Javascript! NME also includes packaging abilities for webos, android and ios. So with a few scripted command lines you can target most app marketplaces:

haxelib run nme test YourProject.nmml flash
haxelib run nme update YourProject.nmml ios
haxelib run nme test YourProject.nmml webos
haxelib run nme test YourProject.nmml android
haxelib run nme test YourProject.nmml cpp
haxelib run nme test YourProject.nmml cpp -64

What it means for this project is we could very quickly get a view for our game of life running in flash, JS and native desktop.

To show just how easy it is I made the following video:

You can see the HTML5 build here: http://mikecann.co.uk/projects/gameoflife/Export/html5/bin/

And the flash build here: http://mikecann.co.uk/projects/gameoflife/Export/flash/bin/MyApplication.swf

I have uploaded the source for the project here: http://mikecann.co.uk/projects/gameoflife/gameoflife.zip

More HTML5 & HaXe Speed Tests

Ive spent a little more time this weekend looking at some more  HTML5 with HaXe. Following on from my previous experiments with WebGL I decided to give HTML5′s Canvas a a look as it was supposed to be designed specifically for the purpose of doing 2D.

I had heard from the HaXe mailing list that the Jeash project was a common way of interacting with the canvas in HaXe. Jeash is a remapping of the Flash API into JS so in effect I should beable to take any of my usual flash code, Sprite’s,  BitmapData’s, etc and it should run on the canvas no problems. Nice!

So I coded up a quick blitting example to see what sort of performance I would get:

http://mikecann.co.uk/projects/HTML5SpeedTests/HaXeJeash/bin/

The results were okay (I get about 11FPS with 5,000 crawlers) however I was interested to know what sort of cost HaXe adds. So I decided to code up a second example, this time using pure JS:

http://mikecann.co.uk/projects/HTML5SpeedTests/JSCanvas/

The results this time were better (14FPS with 5,000 crawlers) so I now wondered what happens if I do without Jeash and just code up the example using pure HaXe. I was expecting to see the same sort of performance hit as Jeash:

http://mikecann.co.uk/projects/HTML5SpeedTests/HaXeCanvas/bin/

Surprisingly it actually runs faster (17FPS with 5,000 crawlers) ! This is quite a surprise and totally contradicts my notion that going from HaXe -> JS would incur a cost. I was expecting some cost, but a performance increase?! I can only speculate that behind the scenes the JS engine in the browser is able to JIT compile the HaXe JS much better than the hand-crafted JS and hence more speed.

If you are interested in the source then I have uploaded it here: http://mikecann.co.uk/projects/HTML5SpeedTests/HTML5SpeedTests_1.zip

P.S. All the test were run on Windows 7 x64 in Chrome 14 (dev)

Harmony, HTML5 Procedural Drawing

Wow! Although this is doable in flash I must say im pretty impressed with this little HTML5 app by MrDoob called Harmony.

Basically its just a little drawing app. I bet there are some people out there that could do some amazing things with this! As it is, im a programmer and no artist, but there is definately a certain beauty to some of the doodles that can be easily made in this thing:

I call this one rainbow circles:

(click for full-size)

And this one maze:

(click for full-size)

Anyways, I would love to see some creations from proper artists. Make your own here -> http://mrdoob.com/projects/harmony and drop me a comment with yours!

 Scroll to top