Hammer Time

Details:
  • A 2D game inspired by Ikaruga.
  • 8-week development (20h/week) with a team of 5 programmers, 3 level designers and 4 3D artists. Game project 3 at The Game Assembly.
  • Made in the school's in-house C++ game engine.
My contributions:
  • Player movement.
  • Xbox and keyboard input manager.
  • Sprite sheet-based animations.
Sprite sheet-based animations:

I had to develop a pipeline for importing sprite sheets into the school's game engine during the project. I came up with a solution where the artist used TexturePacker to export the sprite sheet image and a JSON file that described the coordinates of each sprite. I also developed an animation system capable of switching between different animations.

Here is an example of how to sprite sheet JSON file was structured:

{"frames": {
"enemy_beam_blue.png":
{
    "frame": {"x":3882,"y":414,"w":176,"h":117},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":176,"h":117},
    "sourceSize": {"w":176,"h":117}
},
"enemy_beam_blue1.png":
{
    "frame": {"x":2,"y":533,"w":176,"h":117},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":176,"h":117},
    "sourceSize": {"w":176,"h":117}
},

One of the most difficult tasks I faced was creating smooth transitions between animations. For animations like player flip, which could not be cancelled mid-animation, I had to ensure that the new animation request only switched to a new animation at the last frame of the previous animation. To do this, I had to set "overrideable": false in the animation JSON file.

...
"flip_blue_to_orange":
        {
            "frames":
            [
                "player_blueToOrange1.png",
                "player_blueToOrange2.png",
                "player_blueToOrange3.png",
                "player_blueToOrange4.png",
                "player_blueToOrange5.png",
                "player_blueToOrange6.png",
                "player_blueToOrange7.png"
            ],
            "frames per second": 30,
            "overrideable": false
        },
...