I'm having some minor problems with working with rotated hitboxes on projectiles.
Let me give some information on how my hitboxes generally work:
- All projectiles have a hitbox of either of the two:
- A custom hitbox decided by custom width and height (used for projectiles that use sprites that have some glow or other effects that shouldn't be included in the actual hitbox).
OR
- A hitbox that is identical to the sprite the projectile uses.
For the second type of hitbox, there are no particular issues, but for the first type, it causes some weird problems - the reason why I consider it to be weird is because of my lack of math understanding.
Here's the code I'm using for the hitboxes and the actual visible sprites (noted as Animation):
Hitbox Property (will always be an empty rectangle if not set as the second type of hitbox)
The actual hitbox. As shown, this will be set to the sprite's hitbox if the above hitbox returns empty.
The GetOffset() method. I reckon this is where I am doing something wrong (since, you know, math..).
To explain, the "Position" vector is the center point of the projectile.
However, when the sprite rotates, the actual width and height of the sprite changes, and the hitbox seems to incorrectly function when its smaller than the sprite itself.
The code for this works relatively well, but has some slight inaccuracy which I don't really want to have there.
If anyone sees any obvious mistakes in the code, I'd appreciate any pointers.
Thanks!
Let me give some information on how my hitboxes generally work:
- All projectiles have a hitbox of either of the two:
- A custom hitbox decided by custom width and height (used for projectiles that use sprites that have some glow or other effects that shouldn't be included in the actual hitbox).
OR
- A hitbox that is identical to the sprite the projectile uses.
For the second type of hitbox, there are no particular issues, but for the first type, it causes some weird problems - the reason why I consider it to be weird is because of my lack of math understanding.
Here's the code I'm using for the hitboxes and the actual visible sprites (noted as Animation):
Hitbox Property (will always be an empty rectangle if not set as the second type of hitbox)
Code:
/// <summary>
/// The hitbox rectangle. Can be null.
/// </summary>
public Rectangle Hitbox
{
get {
Rectangle rect = _hitbox;
Vector2 offset = GetOffset(rect.Width, rect.Height);
rect.X = (int)Position.X - (int)offset.X;
rect.Y = (int)Position.Y - (int)offset.Y;
return rect;
}
set
{
_hitbox = value;
}
}
Rectangle _hitbox = new Rectangle();
The actual hitbox. As shown, this will be set to the sprite's hitbox if the above hitbox returns empty.
Code:
public Rectangle HitboxFinal
{
get
{
// If a hitbox is provided: check if intersecting
if (_hitbox != new Rectangle())
return Hitbox;
else if (Animation != null)
return new Rectangle((int)Position.X - (int)GetOffset(Animation.Width, Animation.Height).X,
(int)Position.Y - (int)GetOffset(Animation.Width, Animation.Height).Y, Animation.Width,
Animation.Height);
else
return new Rectangle((int)Position.X - 16,
(int)Position.Y - 16, 32, 32);
}
}
The GetOffset() method. I reckon this is where I am doing something wrong (since, you know, math..).
Code:
public Vector2 GetOffset(int width, int height)
{
// If not rotation: return vector
if (Effect.Properties.ContainsKey("rotate"))
{
if (Effect.Properties["rotate"].Value == "false")
return new Vector2(width / 2, height / 2);
}else
return new Vector2(width / 2, height / 2);
// Set up the rotated rectangle
RotatedRectangle rect = new RotatedRectangle(
new Rectangle((int)Position.X, (int)Position.Y, width, height), Angle);
rect.Origin = new Vector2(width / 2, height);
// Set up the offset
Vector2 offset = new Vector2();
// Set the X-offset
offset.X = (float)Math.Sqrt(Math.Pow(rect.UpperLeftCorner().X - rect.UpperRightCorner().X, 2) +
Math.Pow(rect.UpperLeftCorner().Y - rect.UpperLeftCorner().Y, 2)) / 2f;
offset.Y = (float)Math.Sqrt(Math.Pow(rect.UpperLeftCorner().X - rect.LowerLeftCorner().X, 2) +
Math.Pow(rect.UpperLeftCorner().Y - rect.LowerLeftCorner().Y, 2)) / 2f;
// Return the offset
return offset;
}
To explain, the "Position" vector is the center point of the projectile.
However, when the sprite rotates, the actual width and height of the sprite changes, and the hitbox seems to incorrectly function when its smaller than the sprite itself.
The code for this works relatively well, but has some slight inaccuracy which I don't really want to have there.
If anyone sees any obvious mistakes in the code, I'd appreciate any pointers.
Thanks!