Personal Projects

The Three Game Challenge – Part 3 – The Family Jewels

head

Well this is it! I have completed the third game in my three game prototype challenge. (first game, second game)

With this one I wanted to try my hand at a very popular game genre at the moment, match-three. Because this is a rather simple style of game I thought it would be really easy and fast to make. Wrong. I spent hours without touching a keyboard trying to come up with some novel twist on the genre.

I toyed around with a gem dropping mechanic but that didn’t work so well, then I thought about how someone interacts with match-three games on mobile, by dragging the icons around. So I decided to base my game play on dragging gems around until they make a match.

I originally wanted a “mindless” match-three game like Montezuma, one where you play it as fast as you can without thinking too much about the moves. As I started developing the game play for this one however it seemed to fit a puzzle like game better so that’s what I ended up with.

screenshot_01 screenshot_02

screenshot_03 screenshot_04

Anyways give it a go and let me know what you think:

Play The Family Jewels

This one took a little less time at the others at 31hours over 7 days, as per the other two I recorded my time spent:

17th April
11:00 – 12:00
15:00-18:00

20th April
10:00-12:00

21st April
13:00-17:00

22nd April
11:00-13:00
14:00-16:00
20:00-21:00

23rd April
11:00-16:00

24th April
11:00-16:00
18:00-21:00

25th April
11:00-12:00

Well that’s the end of my challenge! Im surprised I managed to do it. A little over a week per game seems like hardly any time at all but having that time restriction really is good as it helps to limit your scope, preventing the game from ballooning out into something that could otherwise have taken months and still not have been any fun to play.

As for the tools I used. I used Richard Lord’s excellent Ash Game Framework to develop them all alongside Starling with Feathers on top of Flash for the rendering. For rapidly prototyping games they have been excellent. Now im more familiar with Ash I may write a post or two about how to go about structuring certain parts of a game in an enitity-component like manner.

But for the next week or so I need to finish my packing before my mammoth trip to Central and South America.

 

All New Post To Tumblr Chrome Extension created with Haxe & Robotlegs

I have been working off and on for a while on an update to my popular Chrome Extension ‘Post To Tumblr’ and seeing as Tumblr have just changed thier API I thought it was time to accelerate its development and release it, finally.

First some screenshots to give you an idea of what it does:

You can right-click any thing on a page and “Post To Tumblr”.

A new tab opens where you can format it how you like.

You can change the post type very easily.

When done you just “Create Post”

This version is written totally from scratch using Haxe’s Javascript target. Although not strictly necessary for something as simple as this I thought it was a good opportunity to experiment around with Haxe’s JS capabilities. I must admit I was pleasantly surprised at how well it worked.

Most stuff just worked. There are also plenty of externs out there for the popular Javascript libraries on lib.haxe.org such as the “chrome-extension” library.

Having type-safe Javacript is great for for so many reasons that im not going to get into here. I must admit however there were times when I was lazy and didn’t want fancy creating a type-safe extern class for a library. Fortunately however Haxe has a mechanism for the lazy coder in the form of “untyped”.

An example of this is the way in which you access the “localStorage” object in chrome extensions. localStorage is basically a global object that you can set keys and values in and will persist for the life of your extension. To access it you use: “localStorage[myKey]” to return a value. If you tried to do that in Haxe it would throw an error because Haxe has no concept of global variables (quite rightly).

So to access the localStorage you can use untyped to quickly get access to a global variable, I then decided to wrap this little hack in a Model class to make it a little neater:

  1. package models;
  2. import js.Lib;
  3.  
  4. /**
  5.  * ...
  6.  * @author MikeC
  7.  */
  8.  
  9. class ChromeLocalStorageModel extends BaseModel
  10. {
  11.  
  12. public function get(key:String) : Dynamic
  13. {
  14. var val = untyped localStorage[key];
  15. trace('Getting from localStorage: '+key+" :: "+val);
  16. return val;
  17. }
  18.  
  19. public function set(key:String, val:Dynamic) : Void
  20. {
  21. trace('Saving in localStorage: '+key+" :: "+val);
  22. untyped localStorage[key] = val;
  23. }
  24.  
  25. }

This lets you just just mix and match the type-safe stuff when you need to and just do a little “hack” when you need to ;)

The above example also shows off another cool feature im using in Post To Tumblr, which is RobotLegs. Thanks to the fact that the RobotHaxe library is written in pure Haxe (has no platform specific bits) that means I am able to use it on a Javascript project.

The only problem is the issue with Views and Mediation. Because unlike Flash events don’t bubble up to a central source there is no way to do automatic mediation in the JS target. Instead what you do is implement “IViewContainer” on your context view, then whenever a child is added or removed you call viewAdded() or viewRemoved() that way the MediatorMap can try to make a mediator for that view.

Im not sure if the way I have used RobotLegs is the correct or best way, it was more of an experiment as I went along. The way I have done it is to wrap many of the main HTML elements in my own view classes. So for example I have a “DivView” that represents a “div” and extends BaseView:

  1. class DivView extends BaseView
  2. {
  3.  
  4. public function new(elementId:String=null)
  5. {
  6. super(Lib.document.createElement('div'));
  7. if (elementId != null) element.id = elementId;
  8. }
  9.  
  10. }

BaseView implements the IViewContainer interface:

  1. class BaseView implements IViewContainer
  2. {
  3. public var viewAdded:Dynamic -> Void;
  4. public var viewRemoved:Dynamic -> Void;
  5.  
  6. public var element : HtmlDom;
  7. public var parent : BaseView;
  8. public var children : Array;
  9.  
  10. ....
  11.  
  12. public function new(element:HtmlDom)
  13. {
  14. this.element = element;
  15. this.children = [];
  16. isLayoutInvalid = true;
  17. }
  18.  
  19. ...
  20.  
  21. public function add(child:BaseView) : BaseView
  22. {
  23. children.push(child);
  24. child.parent = this;
  25. child.viewAdded = viewAdded;
  26. child.viewRemoved = viewRemoved;
  27. if(viewAdded!=null) child.addChildren();
  28. element.appendChild(child.element);
  29. if (viewAdded != null) viewAdded(child);
  30. return child;
  31. }
  32.  
  33. public function remove(child:BaseView) : Void
  34. {
  35. if (viewRemoved != null) child.removeChildren();
  36. children.remove(child);
  37. child.parent = null;
  38. child.viewAdded = null;
  39. child.viewRemoved = null;
  40. element.removeChild(child.element);
  41. if (viewRemoved != null) viewRemoved(child);
  42. }
  43.  
  44. ...
  45.  
  46. }

Then say I want to construct the following html:

<div id="container">
	<div id="inner">Hello World!</div>
</div>

I would do something like this:

  1. class MainPopupContainer extends DivView
  2. {
  3. private var inner : DivView;
  4.  
  5. public function new()
  6. {
  7. super("container");
  8.  
  9. inner = new DivView("inner");
  10. inner.element.innerHTML = "Hello World!";
  11. add(inner);
  12. }
  13. }

Then perhaps I want to turn the “Hello World!” red when clicked I would do something like this:

  1. class MainPopupContainer extends DivView
  2. {
  3. private var inner : DivView;
  4.  
  5. public function new()
  6. {
  7. super("container");
  8.  
  9. inner = new DivView("inner");
  10. inner.element.innerHTML = "Hello World!";
  11. add(inner);
  12.  
  13. new JQuery(inner.element).click(onInnerClicked);
  14. }
  15.  
  16. private function onInnerClicked()
  17. {
  18. inner.element.style.color = "#FF0000";
  19. }
  20. }

What this means is you have a RobotLegs-familiar looking View with a Mediator behind it (thanks to the mediation happening when you call add()) which is nice. What it does mean however is I have quite abit of boiler plate wrapping the HTML nodes, which definitely slowed down my development.

Another thing im not sure about is my mixing of in-line styles and stylesheets. Sometimes I would use the styles in my css and other times I would just set them on the element directly. To be honest, because I was using classes and inheritance and all that good stuff I usually found it easier and more expedient to set the styles inline in my View class rather than go digging through several hundred lines of css to find the selector I was looking for

For example I may have a “HeaderOptionButton” that defines some inline styles then whenever I wanted a button that looked and acted like a header button I would just make and add a HeaderOptionButton. I know im probably going to get flamed to hell and back for that!

As I said, im not sure if im doing it the “right” or “best” way, its just the way that seemed to work at the time ;)

Well that’s a quick overview of where im at. Once I have cleaned the project up a little and added some missing features ill be sticking the source up on GitHub for anyone interested.

The Final Development Update for Mr Nibbles Mobile Game

Well it may have taken two weeks longer than my original plan but I can say that after five weeks of development the game is pretty much complete.

All 30 levels have been finished, all the menus are in, all the game play elements and artwork are in. The only thing outstanding really is some better sound effects which I plan to put together tomorrow.

So unlike in my previous development posts where I have provided a playable version of the game in the post I have decided instead to hold off till the game is 100% complete before uploading it. I have also grabbed www.mr-nibbles.com as a place for the web version of the game to live.

So a short post this one, this week will be about packaging the game together and submitting to the various stores.

Before I go tho here are the three stages in the game, showing off the awesome artwork of my colleague Moh:

1 2 3 27  Scroll to top