Tony Polinelli
Tarwin Stroh-Spijer

contact [at]
touchmypixel.com

6/25 Easey Street
Collingwood, 3066
Vic, Australia

+61 3 8060 5321

December 14th, 2009

I've just had the pleasure of spending 3 days rebuilding and battling with a box2d game i'm adding some features to, to realize that the main issue was that i didnt understand corretly how the box2d ContactListeners work.

When you create a custom Contact Listner, you extend b2ContactListener. this then recieved events Add, Persist, and Remove. these functions are called and a b2ContactPoint is sent as an argument. You are advised to store contact information and act on it AFTER the simulation step is completed. I foolishly thought that i could simply store the b2ContactPoint objects. WRONG!

you cannot store the b2ContactPoint sent to the b2Contactlistener functions. I've modified this page on the box2d site to stress this point. You must copy the contact information and store it in your own custom object as box2d reuses its b2ContactPoint object (storing it in a static var i believe). Not knowing this has cost me a lot of pain as my collisions were alwas *half* working, so i hope you can avoid it.

Contact Manager Class

To act on the collision events i wanted to store them in a useful way than simply in an array. It is useful to group them by their Bodies. I can get a list of collisions like:

Actionscript:
  1. contactManager.getContactPoints(ContactManager.TYPE_ADD, myBody1, myBody2);
  2. // returns an Array of ContactPoint objects

Actionscript:
  1. contactManager.getContacts(ContactManager.TYPE_ADD, myRigidBody);
  2. // returns a Dictionary with colliding bodies as the keys and Arrays holding
  3. // the custom ContactPoint objects as values. Very useful to get all bodies
  4. // colliding with a single object, such as your player.

If you set userData on the b2Bodies it can use useful to check this to see the type of the body (type of enemy for example) and call differnt code on your player to react to collisions.

Actionscript:
  1. package com.touchmypixel.box2D
  2. {
  3.     import Box2D.Collision.b2ContactPoint;
  4.     import Box2D.Dynamics.b2Body;
  5.     import Box2D.Dynamics.b2ContactListener;
  6.     import flash.utils.Dictionary;
  7.  
  8.     public class ContactManager extends b2ContactListener
  9.     {
  10.         public static const TYPE_ADD:String = "ADD";
  11.         public static const TYPE_PERSIST:String = "PERSIST";
  12.         public static const TYPE_REMOVE:String = "REMOVE";
  13.        
  14.         public var contactAdd:Dictionary = new Dictionary();
  15.         public var contactPersist:Dictionary = new Dictionary();
  16.         public var contactRemove:Dictionary = new Dictionary();
  17.        
  18.         public function ContactManager()
  19.         {
  20.             clear();
  21.         }
  22.        
  23.         override public function Add(point:b2ContactPoint):void
  24.         {
  25.             registerContact(contactAdd, point);
  26.         }
  27.        
  28.         override public function Persist(point:b2ContactPoint):void
  29.         {
  30.             registerContact(contactPersist, point);
  31.         }
  32.        
  33.         override public function Remove(point:b2ContactPoint):void
  34.         {
  35.             registerContact(contactRemove,point);
  36.         }
  37.        
  38.         public function registerContact(dic:Dictionary, point:b2ContactPoint)
  39.         {
  40.             var b1:b2Body = point.shape1.GetBody();
  41.             var b2:b2Body = point.shape2.GetBody();
  42.             if (dic[b1] == null) dic[b1] = new Dictionary();
  43.             if (dic[b2] == null) dic[b2] = new Dictionary();
  44.             if (dic[b1][b2] == null) dic[b1][b2] = [];
  45.             if (dic[b2][b1] == null) dic[b2][b1] = [];
  46.            
  47.             var cp:ContactPoint = new ContactPoint(b1, b2, point.shape1, point.shape2);
  48.             dic[b1][b2].push(cp);
  49.             dic[b2][b1].push(cp);
  50.         }
  51.        
  52.         public function getContacts(type:String, body1:b2Body) :D ictionary
  53.         {
  54.             var dic;
  55.             switch(type)
  56.             {
  57.                 case TYPE_ADD: dic = contactAdd; break;
  58.                 case TYPE_PERSIST: dic = contactPersist; break;
  59.                 case TYPE_REMOVE: dic = contactRemove; break;
  60.             }
  61.             return dic[body1] != null ? dic[body1] : new Dictionary();
  62.         }
  63.        
  64.         public function getContactPoints(type:String, b1:b2Body, b2:b2Body):Array
  65.         {
  66.             var contacts = getContacts(type, b1);
  67.             return contacts[b2] != null ? contacts[b2] : [];
  68.         }
  69.        
  70.         public function clear()
  71.         {
  72.             contactAdd = new Dictionary();
  73.             contactPersist = new Dictionary();
  74.             contactRemove = new Dictionary();
  75.         }
  76.     }
  77. }

You will need to make a custom ContactPoint class. I've only stored shape and body information, but you can store position, etc. - remember to use .Copy() on b2Vec's as to copy the value however.

Actionscript:
  1. package com.touchmypixel.box2D
  2. {
  3.     import Box2D.Collision.Shapes.b2Shape;
  4.     import Box2D.Dynamics.b2Body;
  5.  
  6.     public class ContactPoint
  7.     {
  8.         public var body1:b2Body;
  9.         public var body2:b2Body;
  10.         public var shape1:b2Shape;
  11.         public var shape2:b2Shape;
  12.        
  13.         public function ContactPoint(body1:b2Body, body2:b2Body, shape1:b2Shape, s2:b2Shape)
  14.         {
  15.             this.body1 = body1;
  16.             this.body2 = body2;
  17.             this.shape1 = shape1;
  18.             this.shape2 = shape2;
  19.         }
  20.     }
  21. }

It would be good to put the ContactPoint objects in a pool - to save instantiation.

cheers!
tonypee

November 26th, 2009

So, mouse scroll wheel events still dont work [edit] In browser [/edit] on osx! its hard to believe, but true. Luckily i found a great SWFObject plugin + as3 class from PixelBreaker in his blogpost :

AS3.0 MouseWheel on Mac OS X

It didnt take too long to port the code across to haxe in order to add the finishing touch to our latest haxe/flash website City on a Hill.
NOTE: You should run the test through a server (eg. apache) to avoid annoying security issues.

Download the Source and Demo here

cheers,

Tony

November 6th, 2009

gorillaz

I've been having a little play with creating multiplayer games in flash. Its kinda like that basic game - Gorilla, or was that Bannanas? hmm... not as chunky gfx yet tho ;P

It sounds pretty easy at first - but is getting a little complicated - even with my small test. The haxe mailinglist has been helpful in getting me started with some good advice.

One approach is to use an authoritative server - where the server runs a simulation of the game. Clients then connect & post their user input to the server. The server will make changes to the simulation and then post back updates to the client(s) about what has changed/is relevant to the user. This is a solid way to ensure that each client is getting the same experience. A major downside to this approach is the greater server load associated with running a game simulation. Especially if the game is planned to run a physics simulation (eg box2d), then the processing would be far too great - especially if a game only supports 2 players, and therefore the number of simulations/players will be extreme.  A great upside of using haxe is that the game logic required to run the simulation on the clientside, can easily be compiled to the serverside target (neko, c++) to run the server. This will prove a MASSIVE bonus for creating authoritative multiplayer flash games.

The approach i've taken is to only run updates on the client side. There are 3 different systems running in the test:

Rotating a cannon

The keypress event is sent to the server with the new roataion, this new roataion is broadcast to all clients (including yourself) then the rotation is applied. This means that you should experience similar latency to the opposition. Which isnt great - but it is very simple. As it is linked to the 'cannon' update loop - events are fired to the server at the tick rate (60fps) which isnt great either - a 'rate' should be capped for updates.

Creating CannonBalls

The event to create a CannonBall is send to the server. This is so that the server can increment a 'count' of cannonballs. It is important the each client can identify each cannonball - for later destruction. This is the only authoritative part of the simulation. Each cannonball is also 'owned' by a certain player - meaning that that players simulation controls its motion. This is fine for the simple test, but i can see that if cannonballs 'owned' by one player needed to interact with balls owned by the other, then problems could arise.

Updating CannonBalls

So, each client updates the motion of 'its' balls, and boardcasts this to the other clients (via the server). This means that you have smooth motion of your own objects.

In a turn based game (what i'm looking at making) this switching of 'ownership' of the simulated objects should work reasonably well - the non dominant client will have a more latent, jittery simulation (as inaccuracies are fixed). Another option would be to run one of the clients as the 'dominant' or 'server' client all of the time. This would be similar to how quake runs when you run it on a local network (atleast how use used to run quakeworld - hah memories).

So now i'm loking at ways to reduce/account for latency - as i think that over the internet the test would run a little jumpy.

Running the test

compile the hxml file (install haxe/neko from www.haxe.org)

run the server.bat

open 2 instances of the bin/Gorillaz.swf

Download the game test

cheers Tony

October 6th, 2009

Since Scarygirl's release we've had a lot of feedback, both good and bad, from the Internet at large. Happily it seems to make more people smile than it does rip their hair out and has been nominated for multiple awards, even winning a few of them! Here's a quick run-down. [Just a quick note, the Scaryigrl game not just our work - so kudos to everyone else who worked on it including Nathan and Suren!]

Nominations and awards

Scarygirl was nominated in four separate categories in the GDAA Game Developer Awards 2009 including Best downloadable title, Best Audio, Best Graphics and Best Game.

The first one, and probably the biggest in terms of being nominated, is the AFI award for "Screen Content Innovation". This was a new award this year and war announced earlier than the main awards for general film. The other people nominated included two produced by ABC TV and another by the Channel 9 Network, so we were in good company. Alas in the end we were beaten by the Gallipoli interactive; I guess you just can't fight war. Congratulations to them though as they created quite an amazing peace [sic].

Scarygirl also got nominated for "best of online games" by a UK/Ireland TV station called E4 (Scarygirl review). We didn't win that one either but people seemed to enjoy it at least and we were up against such amazing games as Mirror's Edge 2D and Closure.

The UK seems to love Scarygirl. Channel 5's Gadget Show put it in the top 5 browser games!

Scarygirl's first award was an FWA (Flash Website Award) on the 7th August. This might not seem like such an amazing thing to the general public but to Tony and myself this was one of the most exciting as we'd been looking at the site for years wondering when something we did got up there.

We also won the "Desktop Create: Digital Media" award. Yay! [Ed: Pics coming soon]

The 2009 HOW Interactive Competition just gave the Scarygirl game a merit award, thanks guys, and it's currently sitting as a finalist it got a bronze award in the 2009 London International Awards in the games category!

It's currently sitting as a finalist in the Games category of the 2010 SXSW Web Awards - here's hoping!

Scarygirl just won the Communication Arts Interactive Annual 16: Entertainment award.

For best graphics it was a runner up at the Flash Gaming Summit.

Finalist in Winner of the 2010 FITC Awards in the game category.

Honourable mentions

Adobe featured Scarygirl on their Adobe Developer Connection as an inspiration Flash game. We got featured along-side our friend's game Bunni - so congradulations!

.net Magazine, a UK based web and design magazine, featured the Scarygirl game along with an interview with Nathan, Sophie and ourselves. In it they call Scarygirl "the best Flash game ever" - thanks! We also wrote a tutorial for the magazine explaining how to use bitmap caching to speed up animations. The same month Scarygirl was also featured in the Australian Desktop magazine.

As well as awards, and "we nearly got it" awards, there's been a whole lot of media coverage. Being in print is great to show your grandma, "Hey, Gran, see we do real stuff" so we were very happy to have a review in The Age Greenguide as well as in the Sydney Morning Herald. There was even an interview on one of The Age's blogs. There was also a lot of different

Online's been a little bit of a different story. With great responses to previews we got onto places such as TIGSource and IndieGames (thanks guys) we were super happy when we released it and managed to get it onto JayIsGames - only problem is that people just seemed to hate it there! This spurned us on to make the game even better with easier controls (especially under water). We even got featured on Gamasutra (thrice) and so did the music/sound designer Luke, even on their best game pick list! Kotaku (both AU and US) seemed to like us too with a headline "Go Play Scarygirl".

Gamertell put Scarygirl in the best 101 free games, calling it "one of the coolest games of 2010".

There are also a whole lot of other places (too numerous to mention / find) that mentioned the work so just a big shout out to all those people I forgot to thank for the promotion!

And the rest ...

It's pretty awesome, people are talking about it everywhere it seems. I'll post more links to articles as I see them.

guttersnipenews review - Top of the list of the reviewers favourite games.  A list that includes such greats as Samorost, The Path and Little Wheel.

If you're German (or live in Germany I guess), then you can vote for Scarygirl on the MTV Game Awards. Not sure what the "working class hero" award means, but we're up there will a very well deserving crowd I must say!

There is an amazingly in-depth review at 1UP by Carlito Cabada Jr available in 5 parts! (Part 1, Part 2, Part 3, Part 4, Part 5)

- Tarwin

July 30th, 2009

Its exciting to see that the haxe C++ target is coming together, Hugh Sanderson who's the brains of the operation must be going grey early with all of the attention he's been getting on the lists. Today I've been looking at getting testing the iphone target, and due to my lack of skills in most things related to it, working on a mac, compiling on a mac, hating a mac, apologizing to the mac once it started doing its job, xcode, c++, etc, etc. Its taken me quite a while to have the penny drop, but in short IT WORKS!

sorry for the terrible video quality, its my old ericsson phone (maybe i should get an iPhone!??)

July 27th, 2009

Finally we've got the 2.04 realease of haxe! Its pretty momentus, as i've been waiting for it for about 2 months!

One big thing:  the compiler now officially supports the C++ platform. This includes Linux, Mac, Windows, iPhoneos, iPhonesim support. According to Hugh, there will probably be a few teething issues, but as of now i'd better get out of bed and see what we can make!

Here's what Nicolas has to say about 2.04

The full list of 2.04 changes

Cheers,

Tony

July 22nd, 2009

We might start throwing up some tests of games we're working on. I hope it will be good to get some feedback - but keep in mind, this IS in development, so go easy ;P

So - whats deadsun? Thats the codename (hah how mysterious!) for my latest game, Tarwin is working on a few other things. It will hopefully be release on the iphone too (hence the format).

The sun is dead, and post apocolyptic radiation is pouring out of the sky. You need to gather it to your cities to power them. In this test, you can play with the mechanic of collecting energy from the black-holes which expel it. There will be more advanced levels to come, which involve protecting the cities, tba.

Use Keys 1-8 to flick between the levels.

NOTE: please view this on its own page (not with all other blog posts) as it probably will run slow otherwise - we are working on fixing this weakness of our blog.

UPDATE - I HAVE TAKEN THIS TEST DOWN UNTIL WE DEVELOP THE GAME.

July 22nd, 2009

After realising we have a few people following us on RSS we decided to start publishing it in a way we could see how many people that actually is. So we're now publishing through FeedBurner. If you're already following us it would be great if you could change the address to:

http://feeds.feedburner.com/TouchMyPixel

Thanks!

And lots more coming very soon ...

July 22nd, 2009

So after installing windows 7 i've had to reinstall all of my goods, the probem (ithink) is that installed flashplayer BEFORE Flash. This meant that installed its old flashPlayers over the top of the newer ones, so that i installed some of the newer ones AGAIN, and in the mess of many installs, i found that my FlashDevelop wasnt using the debug player anymore! gah!

Problem: FlashDevelop wont use the dubug version of flashPlayer when in popup mode (you need this to have trace's come back to flash via ExternalInterface)

So, in reinstalled the debugplayer standalone about 5 times, in various varieties, before realizing that: FlashDevelop uses Ie's ActiveX version of the player for popup mode

Solution: Install debug player for IE

since i dont really use IE, this was slightly overlooked, but now it all works fine. Just a little bit of knowledge that people might want to know :P

Tony

June 21st, 2009

For a new game I'm designing, I've been learning a little about particles. Its actually really simple to get some great effects. I found a good as3 lib http://flintparticles.org - but in the aim of learning, and due to the fact that i need to use haxe not as3 (planning to target iphone) i've started from scratch. Ive only implemented a Gravity Well, and Gravity - but plan to add some magnets, simple collisions, brownian motion and maybe particle to particle attraction.

A few important things are:

  • Rendering direct to bitmap- not using MovieClip or Sprite - as they kill performance
  • Using copyPixels over draw - again for performance
  • Using an Object Pool, for less memory and garbage collection issues in the future
  • Created an 'effectors' interface for applying multiple effects to particles
  • Frame independant (time based) motion for more predictable performance

so lets see a test:

Update: Here's another example - not in the source, but just adding a colorTransform- fun fun!

heres the haxe code: download

cheers,

Tony

Our Friends:

Powered by haXe / poko cms | Copyright 2008-09 TouchMyPixel