3
\$\begingroup\$

In my topdown 2d game you have a player with a sword, like an old Zelda game.

The sword is a seperate entity, and its collision box "rotates" around the player like an orbit, but always follows the player wherever he goes.

The player and sword both have a vector2 heading. The sword is a weapon object that is attached to the character.

In order to allow swinging in a direction, I have the following property inside sword (RotateCopy returns a copy of the mHeading after rotation)

public Vector2 Heading
{
    get { return mHeading.RotateCopy(mOwner.Rotation); }
}

This seems a bit messy to me, and slower than it could be. Is there a better way to "translate" the base/owner component rotations through to whatever component I am using, like this sword?

Would using a rotation MATRIX be better? (Curretnly rotates by sin/cos) If so, how can I "add" up the matrices?

Thank you.

\$\endgroup\$

2 Answers 2

5
\$\begingroup\$

I like using transformation matrices for this, because it allows me to have all sorts of complex father-child relationship between sprites such has having different relative positions, rotations, scales and origins relative to the parent, but in the end the only thing I need to do is multiply all of their matrices together and render.

I could repeat everything again but I've already written about this before on the two following questions, so look into them for more detail:

Is there a simple way to group two or more sprites, so all of them will be dependent on each other?

How to "swing" bounding box and update collision for sprite swinging a weapon?


I'll briefly describe the concept here though. The basic idea behind everything is that for each sprite in your game you'll have a single matrix encapsulating all of its transformations relative to the parent. In the case that there is no parent, then the transformation is simply treated as being in world space already.

Here's the basic interface for your sprite:

class Sprite
{
    Matrix RelativeTransform;
    Sprite Parent;
    List<Sprite> Children;
}

Then for any sprite, you can find the actual absolute transform with the following (somewhat recursive) expression:

public Matrix AbsoluteTransform
{
    get 
    { 
        if (Parent == null) 
            return RelativeTransform;
        else return 
            RelativeTransform * Parent.AbsoluteTransform;
    }
}

In other words, multiply your matrices together, starting from the current sprite and going all the way up to the root. This will get the absolute transform of that sprite in world space, which you can use to draw it.

As for drawing it, the first question I linked above has a method called DecomposeMatrix which you can use to take a Matrix and get some values back from it that you can use with SpriteBatch.

\$\endgroup\$
2
  • \$\begingroup\$ it's "Parent-Child relationships"... you sexist!... just kiddin' ;-) \$\endgroup\$
    – Steve H
    Mar 25, 2012 at 0:25
  • \$\begingroup\$ @SteveH Haha, oops. Sorry to all mothers out there, no discrimination intended. \$\endgroup\$ Mar 25, 2012 at 1:25
0
\$\begingroup\$

When I need children to be rotated based on whatever parent they're in, I instead have a set up where the children have offsets for translation, rotation, etc. from a central point, and that a parents origin is each child's central point as so. This way each child still has it's own central point, and the parents origin can be accessed privately in the child, because it's offset is from it's parents origin. Upon drawing, or physics or whatever, access the child through the parent, and if you don't need the child's data (it's static/purely graphical) then skip whatever step that you access the child at all.

This way you don't have to change your children's data other than is actually required, rather than updating the children every time you update the parent even when not needed.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .