Tuesday, November 22, 2011

Skeletal animation with actual images

It took quite a while because I was busy with other things and because I tried to do too much at once. Once I broke the problem down into smaller pieces, things quickly fell into place. I had to rewrite most of the underlying bones and joints but I eventually got the skeletal animation to work with actual graphics. Here's a half-sized Galamoth from C:SOTN.

I completely got rid of bones and just use FlxSprites now. Each FlxSkeletonJoint is responsible for how the parent and child are positioned relative to each other. Joints do this by attaching the "ball" point of one sprite to the "socket" point of another at a given angle. Each joint can still have it's own set of animations. The FlxSkeleton itself just holds the bones and joints and helps assemble and detatch them.

Next is basic inverse kinematics - just enough to support things like "look at that" or "put your right hand here". That should be good enough for what I need.

Monday, November 14, 2011

Skeletal animation with basic physics

Skeletons are now FLxObjects and not FlxGroups. There's a few other minor changes but that's the big one. You can see the bounding box by toggling debug mode by pressing [~] then clicking the bounding box icon in the upper right.

Press [w] to jump, [a] or [d] to walk, hold [shift] to run, and [k] to kill yourself. There's not really anything to do here - just jump around and self-kill when bored.

Completed this time:
  • Make sure skeletons play well with Flixel physics (collisions, velocity, acceleration, etc.)
  • Detaching bones (exploding skeletons!)
  • More animations for HumanoidSkeleton
Next up:
  • Make sure regular sprites and animated sprites can be used as bones
  • Constraints for joints
  • Ragdoll physics

Friday, November 11, 2011

Skeletal animation with forward kinematics

I'm off to a good start with my little detour into skeletal animation: I've got bones and joints that can be animated. The joints use keyframes to hold the target angle of the joint and interpolate between the current angle and the target angle so switching animations should smoothly transition from one to the other. I had a bit of difficulty since rotating a FlxSprite rotates about the center and I need to rotate around the joint. I also wasted nearly an hour on a really stupid bug where animating a joint would sometimes make it freak out (hint: -45 as a Number and -45 as a uint are two very different values). Once I'm done, I plan on submitting a pull request to the original Flixel project so maybe the next version of Flixel will support skeletal animations....

Done so far:
  • FlxSkeletonBone - a FlxSprite with a start and end point
  • FlxSkeletonJoint - a class that connects bones at an angle
  • FlxSkeleton - a FlxGroup that wires everything together
  • HumanoidSkeleton - a pre-made human skeleton with some generic animations
  • Keyframe based animations per joint
  • Simple forward kinematics

To do:
  • Make sure regular sprites and animated sprites can be used as bones
  • Make sure skeletons play well with Flixel physics (collisions, velocity, acceleration, etc.)
  • Constraints for joints
  • Ragdoll physics
  • Detaching bones (exploding skeletons!)
  • Add inverse kinematics
  • More animations and helpers for HumanoidSkeleton
  • Walking velocity determined by feet positions?

Monday, November 7, 2011

Randomized metroidvania 09: slightly better architecture

It took a few days longer than I'd like but I was able to implement some new stuff:
    Slopes and stairs based off of https://github.com/krix/SlopesTest/blob/master/src/FlxTilemapExt.as
    Different background colors, patterns, and decorations (just columns for now)
    Different art and architecture preferences for each region

Each region gets a few architecture and art preferences. The architecture preferences are used to determine the room generation: what tiles are empty, solid, or stairs. The art preferences are used to determine the graphics: what do the background, stairs, walls, and floors look like. There's still not much content but I have a simple system set up and I can add more and better art or architecture styles later. Alpha content will suffice for now.

There's still a bug where moving into another room sometimes bumps you to a different space. I can't pinpoint where or why though. It seems to only bump you towards the bottom of the map and never the top. It also seems to bump to the left and never the right. So it bumps up the Y axis and down the X axis.... weird.

I think it's time to focus on player graphics for a while. Since I'm better at programming than art, I think I'll try my hand at skeletal animation. Flixel doesn't have anything like this as far as I can tell but forward and inverse kinematics should be fun and make a lot of the art stuff easier too. I estimate about a week until I have something useful.

Friday, November 4, 2011

Randomized metroidvania 08: initial architecture

I've got some initial architecture. It should now be possible to move from any room to any room. It certainly ain't pretty and is sometimes frustrating to get the jumps but it does allow you to get from one room to the next. I also added restricted regions to the world generation so the resulting map won't be as dense.

[it seems that transitioning from one room to the other sometimes "bumps" the player to a different spot... worked fine on my machine. I'll look a little closer into that code.]

Part of automating the process of creating room internals was changing the screen size to 32x21 tiles. Next up is adding sloped tiles for stairs, more variety, and more randomness to the architecture.

Wednesday, November 2, 2011

Randomized metroidvania 07: a brief study of C:SOTN and vertical movement

Next up is adding stairs, lifts, and all the architecture that should go in a room. It's already possible to move to rooms to the left and right, but moving up the map isn't possible yet. I decided to turn to maps of Castevania: Symphony Of The Night to see how they did it.

First of all, Alucard seems to be two tiles wide and three tall. When he jumps his feet are 4 tiles higher than they were when he started. This means that the shortest ceiling is 3 tiles from the floor and he can jump onto a tile that has a top that's 4 tiles off the floor.

Sometimes a flight of stairs or a hole in the floor is good enough to go up. The second image has three tiles from the top of the stairs to the bottom of the next floor - just short enough to jump up.

Sometimes you have to make a series of jumps between sides and center blocks.

Jumping back and forth between side platforms is the most common. These pictures show that sometimes it's more obvious than other times.

Here's a short series of jump-through blocks.

 This could be either a series of jump-through blocks or jumping from side to side depending on how you look at it. This pattern shows up in a few places.

There are also a few places with moving platforms to bring you up or down.
And this is my favorite example: a weird mix of side to side, stairs, and just jumping up through a hole in the floor. I don't remember if it's here or another place but I think you can't get to some of the non-essential side platforms until you have double-jump. The background graphics and variety make it much more interesting. 
A simple algorithm for this might be: evenly place floors, add a flight of stairs going up each third floor,  remove the floor from the top of the stairs to the opposite wall, remove the floor form the base of the stairs to the nearest wall, and add a gap in each remaining floor. The background shadows, floors, stairs, and banisters at the top of the staircases are good examples of the attention to details found in C:SOTN.

So it seems that sometimes you just walk up some stairs or do a single jump, at other times you have to jump from side to side, or sometimes from sides to center blocks, or even have to jump through one-way blocks. The best places (in my opinion) are a crazy mix of each. This is probably much easier to automate if your screen can be split into an even number of floors like the last image; that way you could place the floors and then pick random ways to move between them. It's also good to point out that each region has it's preferred method for going up. Don't forget to carefully plan the architecture to match the height and jump hight of the main character.

This may have been pretty obvious to most of you, but I learned a lot: you can use the same action (jump to the upper left then the upper right then the upper left....) but provide slight differences in art and layout and it will still provide interesting architecture and opportunities for fun. I've also got some working code to create rooms with layouts like the last image. And lastly; after 15 years, C:SOTN is still a beautiful and intricate game.

Tuesday, November 1, 2011

Randomized metroidvania 06: player in a room

I slept through my alarm this morning and woke up 4 hours after I should have been at work so I had a lot of time for this project today.

Time for the first steps to actual gameplay: a rectangle that can walk and jump around empty rooms. Press [m] to view the map.

Nothing exciting yet - just rooms with connections to the neighboring room. There's not even a way to go up stairs or anything so you eventually end up at a dead end. It was tricky getting the player to walk out one door and appear in the correct one in the correct room; it would have been easier to just create one huge map with the entire level but that would take a lot of memory and the camera would look into rooms you haven't been into yet. Next I'll add background graphics along with stairs and floors within each room; later the room sizes and shapes can be determined by the region. I'll also make sure the map only shows rooms you've been into and a few more tweaks. The really fun stuff will begin once I can generate some decent architecture. I should think of an overall theme I'd like to work with too.