"Drawn to Life", is a Nintendo DS game that lets you draw various objects in the game, such as the hero, platforms, etc. It's cute, but more importantly, it also demonstrates a key part of good framework design, which is what I'm writing about here.
In 'Drawn To Life", you get to draw various parts of the game. Your drawings don't change game play, they're just a cute gimmick to let you customize the game and get involved. Since the Nintendo DS has a stylus, drawing is also a very reasonably option (in contrast to other consoles). For example, you get to draw objects like:
- the main hero
- platforms that you jump on
- weapons you use
- various parts of the town (signs, plants, etc)
Here's a screen shot of the drawing mode, courtesy of GameSpot.com.
Again, so how is that related to a video game?
I see two comparisons...
First, good frameworks have nice extensibility points that require as little extra glue as possible. For example, deriving from classes with lots of intrinsically unnecessary virtuals is painful. (It's bad that creating your own XMLReader requires implementing 26 overloads). A nicer design is having a set of "essential" abstract virtuals, and then having the rest of the virtuals have reasonable default impls that intelligently build on abstracts.
In this case, each time you need to draw an object, you're conceptually implementing a virtual function. Normally, 2d animation requires many frames to show an object animating or doing something interesting. For example, to show a character walking, the game may have 10 frames of the character at various snapshots of walking. (See wikipedia's animation topic for more)
Just as when you derive from a class, you want to implement as few virtuals as possible; when you draw a 2d image, you don't want to have to draw a bunch of frames.
So the game here just requires you draw a single frame, and then the engine applies various transforms to achieve animation affects. For example:
- You draw the hero (as seen in the screenshot above), and then the game moves the arms and legs around to simulate the hero walking.
- You draw a spring, and the game applies a vertical stretching transform to make it look like it's compressing / expanding.
- You draw a gear in a single position, and the game applies a 2d-rotation transform to rotate the gear around to make it spin.
- The game applies color transformations to various objects so that you only need to draw 1 version, and then see it in 3 different colors.
It's true that some of these are crude. Eg, the shading on the spinning gear is wrong. But it works well enough.
Second, just as you want virtual methods that are reasonable to override, the game has painting support that is reasonable to use.
The game's drawing support makes it very reasonable to draw things. For example, it often presents the outlines of shapes that you can quickly just use a paint tool to fill in. You can paint per-pixel if you want to get really fancy. The fact that the Nintendo DS has a stylus is also essential here (which demonstrates another point: know your hardware).
This is similar to having virtual methods that are reasonable for a derived class to implement:
- well documented
- have sane contracts to implement .
- have sane parameters. (You don't have to construct some super complex object to hand back)