Rendering Animation in Specific Spot

Oct 13, 2012 at 6:20 AM

So I've gotten the hang of everything. Now in my game, I want to define the players position based on an anchor point which will always be located at the bottom of my animation. How do I achieve this? Let's say I want to use the animation from the sample provided in the documentation and I want to render him in such a way that the bottom of the animation is located at exactly {X: 200, Y: 200}?

Coordinator
Oct 13, 2012 at 12:49 PM
Edited Oct 13, 2012 at 12:49 PM

There's nothing in Demina that will handle this automatically. I calculate my offsets by making a few measurements, and then testing experimentally until I'm happy.

Basically, I calculate a bounding box that would roughly contain my character. If his default anchor (based on the center of his root bone in Demina) isn't perfectly in the center, I set a DrawOffset property to account for that. It's pretty simple, I'll show you some code.

This is how I handle the characters in Hero in Training. (http://youtu.be/UuMObTFm9q4)

I have a base class called Actor which contains:

public Vector2 Position { get { return position; } }
public Vector2 Velocity { get { return velocity; } }
public Vector2 Scale { get { return scale; } }
public float Rotation { get { return rotation; } }
public Vector2 DrawOffset { get; protected set; }

public Vector2 Dimensions { get { return dimensions; } }

And in each derived constructor, I do something like this:

 

float scaleAmount = 0.5f;
scale = new Vector2(scaleAmount);
dimensions = new Vector2(110, 330) * scaleAmount;
DrawOffset = new Vector2(-20, 20) * scaleAmount;

 

After I calculate where I want to draw the character (anchored by their foot position), it goes like this:

 

footPosition.Y = landablePosition;
position.X += velocity.X * deltaSeconds;
position.Y = footPosition.Y - dimensions.Y / 2;

 

Then finally, to draw it (this is in the Actor base class method Draw)

 

Vector2 drawOffset = DrawOffset;

if (Direction != Direction.Right)
    drawOffset.X *= -1;
animationPlayer.Draw(spriteBatch, position + drawOffset, Direction != Direction.Right,
    false, Rotation, tintColor, scale, camera.Transform);
Oct 13, 2012 at 8:23 PM

Thanks you for the informative response. Your code sample was pretty interesting to read. I'll probably end up using a similar method. I was also wondering if it was possible to create a bone at the base of the animation that is completely unattached from the rest of the animation. I would be able to use that bones position to map the animation to the anchor point?

Coordinator
Oct 14, 2012 at 5:24 AM

Absolutely. You could have an invisible bone that's situated at the feet of the character, and use that for absolute control. I tend to make the torso the root bone, but there's no reason why the root couldn't have an invisible parent. (Hit H to hide a selected bone in Demina to make it invisible. You could also use a completely transparent png, but I think that would give you headaches.)

Oct 14, 2012 at 2:26 PM

Interesting, I'll probably just add rectangles to the keyframes to define the area of the animation. Really great tool, having a lot of fun with it.