Adding async/await to CocosSharp actions

UPDATE: The CocosSharp team has decided to integrate my ideas directly into their source! 🙂

Are you a C# programmer? Using Xamarin? Are you interested in making great games that run…

  • cross platform,
  • from one code base
  • and are powered by Cocos2D and XNA?

If yes, then you should check out CocosSharp!

I used Cocos2D in the past (the “good” old days of ObjectiveC…) and liked it a lot. Seeing all this translated to C# just freaks me out! 🙂

However there has been one thing that bugged me: chaining actions and running actions simultaneously.

Say, you want your character to scale, then increase some score counter, afterwards make the character jump and then reset the animation phase to the default frame. You would use something like:

var scale = new CCScaleBy (1f, 1.5f);
var jump = new CCJumpBy (1f, new CCPoint (100, 100), 50, 2);

this.RunActions (scale, new CCCallFunc (() => this.UpdateScore ()), jump, new CCCallFunc(() => this.SpriteFrame = this.defaultFrame));

Works, but with the power of C# we can do better!

I do it this way:

await this.RunActionsAsync (scale);
this.UpdateScore ();
await this.RunActionsAsync (jump);
this.SpriteFrame = this.defaultFrame;

I think this is much cleaner and easier to read. Async/await are very powerful. You can also simplify more complex examples: want to start something if either action A or action B have completed? Just use Task.WhenAny().

What is RunActionsAsync() you might wonder? It’s just a small extension method I wrote:

public static Task<bool> RunActionsAsync(this CCNode node, params CCFiniteTimeAction[] actions)
	var tcs = new TaskCompletionSource<bool> ();
	var allActions = new List<CCFiniteTimeAction> ();
	allActions.AddRange (actions);
	allActions.Add (new CCCallFunc (() => tcs.TrySetResult (true)));
	node.RunActions (allActions.ToArray());
	return tcs.Task;

Go grab it from this Gist.

Happy coding!