Thursday, 16 December 2010
To get an idea of what’s possible in terms of 2D games on Windows Phone 7, I have ported my BunnyMark benchmark from AS3/Flash to C#/XNA. The results were very decent for a small device. I could render 3500 bunnies without any slowdown, which is equivalent to what I could do with Bitmaps in Flash on my dual core PC laptop, and about 10 times as many bunnies as Flash on Android could handle. The reason for this great performance, of course is that XNA is hardware accelerated while Flash is not... until next year at least. Here is the source code - watch the video below to see it in action (shot on non-HD camera, so not great quality I'm afraid).
XNA splits game updates (equivalent to ENTER_FRAME event in Flash) into 2 separate functions which you override. There is “Update” (confusingly, functions in C# start with capital letters) where you put all the update logic for your game, and there is “Draw”, where you put all the rendering logic. Like copyPixels blitting in AS3, nothing is drawn to the stage automatically; you must manually call spriteBatch.Draw for each of your game entities.
Ok, now for the slightly weird caveat that I found with the frame rate. XNA by default uses a “fix your timestep” style approach to updates and rendering, where “Update” is called at as close to your target framerate as possible, while calls to “Draw” are dropped if performance is a problem. So when I put my frame rate counter in Update it always shows 30fps, even if actual stage updates are slowing to a jerky crawl. Moving my fps counter to Draw, I expected to see 30fps with a few bunnies, slowing as I add more waves of bunnies. However, what I found was that Draw is never called more than 15 times per second in my tests. So even though the update logic runs at 30fps, the game only really renders at 15fps. Is this something to do with limitations of a mobile device, or just something I don't fully understand? I don’t know. It doesn’t visually look noticeable, although perhaps the movement has a slightly blurry look to it on my device. At 10000 bunnies Draw slowed to about 4fps while update happily skipped along at 30fps.
My overall impressions of the platform from creating the demo are that this is definitely something a reasonably experienced Flash developer can easily turn their hand to. C# and AS3 have only superficial syntax differences, the core of the 2 languages are essentially very similar. The biggest difference comes when you move beyond the standard programming constructs and start requiring utilities like “getTimer”. At these times, Google and StackOverflow.com are definitely your friends – I didn’t get stuck on anything for more than about 5 minutes.
Just to give some examples, here’s a quick comparison of some terms and equivalent features:
Flash >> XNA
AS3 >> C#
int >> int
Number >> float (or double)
Vector.<Bunny> >> Bunny or List<Bunny> depending on what features you need.
Math.random() >>random = new Random(); random.NextDouble();
TextField >> SpriteFont
Point >> Vector2
bitmapData.copyPixels or bitmapData.draw >> spriteBatch.Draw
And when casting types the brackets go around the type for some reason:
Number(value) >> (float) value
Other things to look out for are that XNA API methods have “multiple overloads” rather than the optional parameters in AS3. Once you get comfortable with all these things, you stop noticing them and you just get on with it. Here is the source code to the demo – it’s very simple. Next I’m going to port the more advanced BunnyLandMark with a scrolling level and depth sorting. Bai!