Monthly Archive for March, 2010

Taking a break from game programming…

… and starting on application programming! :D With all the research and core systems tested and proven in project warpy, it’s time to start creating the toolset for the designers to use. I’ll be developing these tools in C#.NET and despite my lack of experience in application programming for C#, it wasn’t hard to adapt (mostly due to my experience in VB.NET).

Been pretty busy with work lately (and collecting loot in world of warcraft). Going down to the creative company for tips on web design on a daily basis and frankly I’m quite sick of it here. The internet is slow, the place is in the middle of nowhere and I’m bumming around not doing much most of the time.

DockPanel Suite in action

Ah well, at least I got a chance to check DockPanel Suite out. It’s frigging awesome, with a couple of drag and dropping with the form designer in C# you can have an application looking like VS.NET’s docking system. Take a look on top!

Finishing up a couple of stuff in the office and heading off.. damn looks like I’m stuck here for the rest of the week. :(

Skeletal Animation in 2D (Part 2: Construction)

Okay so here’s an update on my implementation on skeletal animation in 2D… Basically… it works! :D

Above are some screenshots showing skeletal animation working hand in hand with the scenegraph I programmed for Project Warpy. These are some of the first development screenshots I’ve actually posted and although I’m not supposed to reveal game-play, I should be able to release screenshots as long as they do not reveal game-play (such as these).

Okay so first things first, how does the skeletal animation actually work:

  1. Create skeletal animation in maya
  2. Export to .X format
  3. Parse .X format with XNA’s X importer
  4. Custom processor to serialize bones and animations
  5. Parse bone transformations and convert to scenegraph
  6. Animation controller updates the bone nodes
  7. Interpolate between keyframes
  8. Attach sprites to bone nodes

Voila! This technique closely mimicks rigid binding and requires some knowledge of matrices and hierarchical transformation.

So before you can get any bone animation working in 2D you’ll need some kind of hierarchical system (in my case, a scenegraph). I create “nodes” that contain position, scale and rotation and use the following formula to obtain a transformation (in world space).

transform = Matrix.Identity;
transform *= Matrix.CreateScale(new Vector3(scale.X, scale.Y, 1));
transform *= Matrix.CreateRotationZ(rotation);
transform *= Matrix.CreateTranslation(new Vector3(position.X, position.Y, 0));
transform *= parent.transform;

transform represents the transformation matrix of the current node in world space. It is created by multiplying the local scale, rotation and translation followed by its parent’s transformation. This is done down the hierarchical chain (with parent first multiplying its transformation, followed by its children) just prior to rendering. The result is nodes that translate, scale and rotates according to its parent’s transformation, in layman terms, when the parent moves the child node moves in accordance.

Because bones are usually stored with transformations relative to its parent bone its easy to adapt it to such a system and therefore the only thing I do in the model processor is read in bones and animations and decompose the matrix into translation, rotation and scale (as used later in the application described above).

// process the bindpose matrices..
for (int i = 0; i < bindPose.Count; i ++ )
{
    Vector3 trans, scal;
    Quaternion rot;

    bindPose[i].Decompose(out scal, out rot, out trans);

    float rs = (float)Math.Sqrt(rot.X * rot.X + rot.Y * rot.Y + rot.Z * rot.Z);

    // make sure we dont get a divisable by 0 error.
    if (rs == 0)
        rs = 1;

    float z = rot.Z / rs;
    float angle = 2.0f * (float)Math.Acos((double)rot.W) * z;

    this.bindPose.Add(new Transform(new Vector2(trans.X, trans.Y), new Vector2(scal.X, scal.Y), angle));
}

I also store a list of parents for each bone, so I know how to parent them after they are loaded:

IList<BoneContent> bones = MeshHelper.FlattenSkeleton(skeleton);

foreach (BoneContent bone in bones)
    hierarchy.Add(bones.IndexOf(bone.Parent as BoneContent));

Once these values are stored the skeleton simply has to be reconstructed using the nodes in the scenegraph.

// contains a list of attached joints.
joints = new List<SkeletonJoint>();

// constructs the bones straight away!
for (int i = 0; i < data.bindPose.Count; i++)
{
    SkeletonJoint joint = new SkeletonJoint();
    joint.position = data.bindPose[i].translation;
    joint.rotation = data.bindPose[i].rotation;
    joint.scale = data.bindPose[i].scale;
    joints.Add(joint);
}

// go through that list again to parent joints..
for (int i = 0; i < data.hierarchy.Count; i++)
{
    // check if this is the root joint..
    if (data.hierarchy[i] == -1)
    {
        addChild(joints[i]);
    }
    else
        joints[data.hierarchy[i]].addChild(joints[i]);
}

Now that the skeleton is built (in your scenegraph), the only thing left to do is animation! I will be releasing an article describing keyframe animation and interpolation in part 3 of the article. Hope you enjoyed reading this.

p.s. This article has been left intentionally vague, sorry for not publishing complete code samples but there shouldn’t be a problem implementing this if you get the theory! :P

Input Action Mapping

One interesting way to generalize input in games is known as action mapping. Basically instead of keys (or buttons) being pressed or released, objects react to when actions are “pressed” and “released”. The largest benefit of using this method when programming input for games is when your project requires input from multiple devices (or support for multiple devices in the future).

Actions are generated from device handlers and propagated to game objects for evaluation. Device handlers handle input device events (such as key press/release) and create the corresponding action.

This worked especially well when developing Project Warpy for the XBOX/PC as debugging on the PC requires keyboard input, while the XBOX only accepts controller input.

Here’s a quick snippet on how you can implement this into your own games:

enum Action
{
    MOVE_LEFT,
    MOVE_RIGHT,
    JUMP
};

class KeyboardHandler
{
public:
    void onPress(char key)
    {
        if (key == LEFT_ARROW)
            gameWorld.propagateKeyPress(MOVE_LEFT);
        if (key == RIGHT_ARROW)
            gameWorld.propagateKeyPress(MOVE_RIGHT);
    }

    void onRelease(char key)
    {
        if (key == LEFT_ARROW)
            gameWorld.propagateKeyRelease(MOVE_LEFT);
        if (key == RIGHT_ARROW)
            gameWorld.propagateKeyRelease(MOVE_RIGHT);
    }
};

Of course, this is not very useful if you only need support for 1 type of input device. But… say I wanted support for the XBOX 360 controller.

class ControllerHandler
{
public:
    void onPress(Button button)
    {
        if (button == DPAD_LEFT)
            gameWorld.propagateKeyPress(MOVE_LEFT);
        if (button == DPAD_RIGHT)
            gameWorld.propagateKeyPress(MOVE_RIGHT);
    }

    void onRelease(Button button)
    {
        if (button == DPAD_LEFT)
            gameWorld.propagateKeyRelease(MOVE_LEFT);
        if (button == DPAD_RIGHT)
            gameWorld.propagateKeyRelease(MOVE_RIGHT);
    }
};

This works for any device (or device library for that matter) as long as propagateKeyPress and propagateKeyRelease are called in the right place and because the game objects react to the Action enum, no extra coding on the game object side is required.

XBOX frustrations

I just got premium membership for the xna creator club to test project warpy. Although I was initially excited, I found out (to my horror) that project warpy doesn’t run on the XBOX due to the fact that I’m using unmanaged code! Curse you LuaInterface, curse you to heck!

So.. I have a project meeting in a couple of hours and a whole new level editing system to implement. Hopefully it isn’t too much of a hassle to get XML working on the XBOX (shouldn’t be too hard based on the articles I’ve read). Basically, note to self, never use scripting languages with XBOX… reason being that it runs on the .NET compact framework, which doesn’t support System.Reflection.Emit, which from what I read is important in .NET script interpreters.

Time to rush up a quick level editing system for the meeting!

Update: Whoo hoo! I’ve finished implementing the new XML system and even support for XBOX 360 controllers.

Bone System Update: I’ve managed to get bone animations reading into xna via a custom content processor.. Now to fit it into my scenegraph.

Blog update: I’ve added a video of my portfolio and a couple of screenshots of past projects in the Games section.