0
\$\begingroup\$

I have two objects. The head and tail of a future "grapple". The head and tail always point in the same direction. However, when I tried using scaled rectangles (that were bigger/smaller than the source rectangles) the rotations no longer worked, as in, the drawn head was no longer "attached" to the tail. (Without scaling them, this worked fine.)

The red sprites are without any rotation (Code below). The others are rotated about their respective "lower" origins (bottom center) (Rotation = 0)

So, the non-red sprites should be touching head to tail (the same way the red sprites are).

I have been fiddling with the code for a while... here is what I think you will need to see to help:

Initialization()
{
    Rectangle headSize = new Rectangle(0,0, 29, 100); 
        Rectangle linkSize = new Rectangle(0,0, 29, 67);
        Rectangle tailSize = new Rectangle(0,0, 29, 53);

        Rectangle headSource = new Rectangle(0, 0, 29, 53); 
        Rectangle linkSource = new Rectangle(0, 53, 29, 67);
        Rectangle tailSource = new Rectangle(0, 120, 29, 53);

        this.headSize = headSize;
        this.linkSize = linkSize;
        this.tailSize = tailSize;

        headSource = headsource; 
        linkSource = linksource;
        tailSource = tailsource;


        chainHandle = new Link(new Rectangle((int)position.X, 
                (int)position.Y, 
                tailSize.Width, 
                tailSize.Height), 
                tailSource, 
                0);   

        chainHead = new Link(new Rectangle((int)position.X + tailSize.Width / 2 - headSize.Width / 2, 
            (int)position.Y - headSize.Height, 
            headSize.Width, 
            headSize.Height), 
            headSource,
            0);

}

    public Link(Rectangle rectangle, Rectangle sourceRect, float rotation)
    {
        TruePosition.X = rectangle.X;
        TruePosition.Y = rectangle.Y;

        Position = TruePosition;
        Rotation = rotation;

        scaledUpperOrigin = new Vector2(rectangle.Width / 2, 0);
        scaledLowerOrigin = new Vector2(rectangle.Width / 2, rectangle.Height);
        scaledCenterOrigin = new Vector2(rectangle.Width / 2, rectangle.Height / 2);

        upperOrigin = new Vector2(sourceRect.Width / 2, 0);
        lowerOrigin = new Vector2(sourceRect.Width / 2, sourceRect.Height);
        centerOrigin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);

        dims = new Vector2(rectangle.Width, rectangle.Height);
    }

    public void Draw(SpriteBatch sb)
    {
        //debug purposes
        sb.Draw(chainAtlas, chainHead.GetRect(), headSource, Color.Red);
        sb.Draw(chainAtlas, chainHandle.GetRect(), tailSource, Color.Red); 

        sb.Draw(
            chainAtlas, 
            chainHead.GetRect(), 
            headSource, 
            Color.White, 
            MathHelper.ToRadians(chainHead.Rotation), 
            chainHandle.scaledLowerOrigin, 
            SpriteEffects.None, 1);


        sb.Draw(
    chainAtlas, 
        chainHandle.GetRect(), 
            tailSource, 
            Color.White,
            MathHelper.ToRadians(chainHandle.Rotation), 
            chainHandle.scaledLowerOrigin, 
            SpriteEffects.None, 
            1);
}

Any ideas on how to fix this? I have tried using both original sized origins and scaled origins to no avail, as well as different points of origins.

If you have read this far, thank you for your time! Let me know if you see a fix.

\$\endgroup\$
1
\$\begingroup\$

I'll be honest, I don't fully understand what's happening here, but I'll focus on what I think the problem is.

It appears as though you are scaling objects separately, when you want to be scaling them as one. More to the point, you need to be scaling from a common origin.

scaledLowerOrigin = new Vector2(rectangle.Width / 2, rectangle.Height);

Each object passed in will have an origin equal to the bottom of itself. What I think you need to do, is specify a point that all objects (in the 'Grappling Hook') are scaled and rotated about.

I'm sorry I can't give you code, I'm sure google can help, but as far as I'm concerned, you need a common point to scale/rotate multiple objects.

EDIT

I belive, even if you used the code as is, there should be somewhere in there that you scale the position, which I don't see. If you scale two objects to be %50 (0.5) smaller, it would follow that they need to be %50 closer to each other to maintain their original distance (touching in this case). So while a common point might be needed for rotation, a common 'scale factor' would be needed for scaling, and all values (width,height,position) would be multiplied by that factor.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Alright that makes sense for the most part. I will let you know how it turns out. I think I'll have to calculate the origin for each part depending on its current position. So the origin for ALL objects should be the same point on the screen... \$\endgroup\$ – Colton Oct 8 '13 at 22:09
  • \$\begingroup\$ Pertaining to your edit: I don't believe I would need a scale factor, since the rectangles are already exactly the size and position that appear on the screen. But for the rest, I am still working on getting a common origin, my math is not correct yet, almost there I think. \$\endgroup\$ – Colton Oct 8 '13 at 23:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.