0
\$\begingroup\$

I have a Rectangle and a Vector2 position, my sprite is being drawn at this position. The rectangle is meant to be a collision system with the cursor, when I rotate my sprite around the origin and stuff in a draw call

public virtual void Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Draw(texture, position, null, Color.White, rot, Origin, SCALEFACTOR, SpriteEffects.None, 0f);         
}

It works fine, my object is rotated, at it's centre, by Pi/2, or whatever I put in. However, rotating the rectangle isn't as easy, I read almost every stack overflow question on this problem and still haven't found a fix. I then followed a youtube guide, this is the resulting code for rotating a rectangle.

private void RotateItem(float rotation)
{
    rot += rotation;
    UpdateRectangle();
}

private void UpdateRectangle()
{
    Vector2 tl = Vector2.Transform(Vector2.Zero, transform);
    Vector2 tr = Vector2.Transform(new Vector2(scaledWidth, 0), transform);
    Vector2 bl = Vector2.Transform(new Vector2(0, scaledHeight), transform);
    Vector2 br = Vector2.Transform(new Vector2(scaledWidth, scaledHeight), transform);

    Vector2 min = new Vector2(FindSmallest(tl.X, tr.X, bl.X, br.X), FindSmallest(tl.Y, tr.Y, bl.Y, br.Y));
    Vector2 max = new Vector2(FindBiggest(tl.X, tr.X, bl.X, br.X), FindBiggest(tl.Y, tr.Y, bl.Y, br.Y));

    rectangle = new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y));
}

private void UpdateTransformMatrix()
{
    transform = Matrix.CreateTranslation(new Vector3(-Origin, 0))
                * Matrix.CreateRotationZ(rot)
                * Matrix.CreateTranslation(new Vector3(position, 0));
}

The width + height don't seem to change until I click on the box (which isn't even drawn properly over the sprite because Origin + and doesn't seem to rotate at all tbh)... I'll show you an example https://gyazo.com/c045b844f306a0ea25f48a0d45127f21

And this is my full draw code + including the rectangle's rectTex

public virtual void Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Draw(texture, position, null, Color.White, rot, Origin, SCALEFACTOR, SpriteEffects.None, 0f);
    if (ShowRectangle)
        spriteBatch.Draw(rectTex, rectangle, null, Color.White, rot, Vector2.Zero, SpriteEffects.None, 0f);          
}
\$\endgroup\$
0
\$\begingroup\$

Okay, after a few more hours of fiddling around and referencing, I somehow managed to fix it. It was a matter of order in which I Update the transform matrix and update the rectangle and where I did so. Now it kind of works, however, after X amount of rotates, the height gets set to 0 and the rectangle ceases to exist... I'll post my new Updates and stuff so people who look at this in the future can see

public virtual void Update(GameTime gameTime, MouseState _currState, MouseState _prevState, ref Item controlItem)
{
    ClickCheck(_currState, _prevState, ref controlItem);
    if (controlItem == this)
    {
        int diffX = _currState.X - _prevState.X;
        int diffY = _currState.Y - _prevState.Y;
        position.X += diffX;
        position.Y += diffY;
        UpdateTransformMatrix();
        UpdateRectangle();
    }
}
public Item(Texture2D inTex)
{
    texture = inTex;
    position = new Vector2(400,400);
    scaledWidth = (int)(texture.Width * SCALEFACTOR);
    scaledHeight = (int)(texture.Height * SCALEFACTOR);
    rectangle = new Rectangle((int)position.X,(int)position.Y,scaledWidth, scaledHeight);
    Origin = new Vector2(scaledWidth / 2, scaledHeight / 2);
    UpdateTransformMatrix();
}
protected void ClickCheck(MouseState _currentState, MouseState _prevState, ref Item controlItem)
{
    Rectangle mouseRect = new Rectangle(_currentState.X, _currentState.Y, 1, 1);
    if (rectangle.Intersects(mouseRect) &&
        _currentState.LeftButton == ButtonState.Pressed)
        {
            controlItem = this;
            return;
        }
     if (rectangle.Intersects(mouseRect) &&
                _currentState.RightButton == ButtonState.Released && _prevState.RightButton == ButtonState.Pressed)
        {
             RotateItem((float)Math.PI / 2);
             UpdateTransformMatrix();
             UpdateRectangle();
        }

        controlItem = null;
}
private void RotateItem(float rotation)
{
    rot += rotation;
    UpdateRectangle();
}
private void UpdateRectangle()
{
    Vector2 tl = Vector2.Transform(Vector2.Zero, transform);
    Vector2 tr = Vector2.Transform(new Vector2(scaledWidth, 0), transform);
    Vector2 bl = Vector2.Transform(new Vector2(0, scaledHeight), transform);
    Vector2 br = Vector2.Transform(new Vector2(scaledWidth, scaledHeight), transform);

    Vector2 min = new Vector2(FindSmallest(tl.X, tr.X, bl.X, br.X), FindSmallest(tl.Y, tr.Y, bl.Y, br.Y));
    Vector2 max = new Vector2(FindBiggest(tl.X, tr.X, bl.X, br.X), FindBiggest(tl.Y, tr.Y, bl.Y, br.Y));

    rectangle = new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y));
}

private void UpdateTransformMatrix()
{
    transform = Matrix.CreateTranslation(new Vector3(-Origin / 1.7f, 0))
                * Matrix.CreateRotationZ(rot)
                * Matrix.CreateTranslation(new Vector3(position, 0));
}

| improve this answer | |
\$\endgroup\$
-1
\$\begingroup\$

i've seen that you rotate the image and the collision, in fact you Don't need to do it with the collision box;

Simply switch width and height of it will work because all you do is 90° rotations.

c# function that could work in this case:

// assuming your collision rectangle is called colRect
public void rotateCollisionRectangle()
{
    // here i Simply switch height and width
    colRect = new Rectangle(colRect.height, colRect.width);
    rot += Math.Pi / 2;
}

also your rectangle when drawn appear a bit Strange, i experienced similare thing when the width was negative. If it's the case, offset the rectangle x and y and say that height and width are positive

| improve this answer | |
\$\endgroup\$

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.