0
我正在嘗試爲XNA獲取一些原語,包括能夠旋轉的輪廓矩形。這非常有用,因爲您可以使用它創建一些可愛的動態內容以及用於調試目的。XNA原始矩形有旋轉問題
我遇到的問題可以看出here
本質上,發生了什麼事時,畫的輪廓矩形時,並轉動線的厚度可達過去的一,組成矩形的線條移動更遠並離得更遠。
這很奇怪,但我90%確定問題在於原點。 我希望有人可以看看我的錯誤。
我通過將線的原點設置爲矩形的中心來繪製旋轉線來渲染矩形。爲了實現矩形的底部和右側部分,我複製並旋轉180度的頂部和左側線。 (Pi,如果你正在使用弧度,我是)
最大的不可思議的是,當我調試Draw
方法時,我發現所有的值都完全符合預期!
這裏是矩形類,繼承類也在下面的情況下,如果你需要它們。
public class Rectangle : Primitive
{
public float X { get { return Body.X; } set { Body.X = value; } }
public float Y { get { return Body.Y; } set { Body.Y = value; } }
public float Width { get { return Body.Width; } set { Body.Width = value; } }
public float Height { get { return Body.Height; } set { Body.Height = value; } }
public float Angle { get { return Body.Angle; } set { Body.Angle = value; } }
public override Vector2 Bounds { get { return new Vector2((Width) * Scale.X, (Height) * Scale.Y);}}
public override Microsoft.Xna.Framework.Rectangle DrawRect
{
get
{
return new Microsoft.Xna.Framework.Rectangle((int) (X - Thickness/2), (int) (Y - Thickness/2),
(int) ((X + Width + Thickness) * Scale.X),
(int) ((Y + Height + Thickness)* Scale.Y));
}
}
public bool Fill;
public Rectangle(Entity parent, string name, float x, float y, float width, float height, bool fill = false)
: base(parent, name)
{
X = x;
Y = y;
Width = width;
Height = height;
Fill = fill;
Origin = new Vector2(.5f,.5f);
}
public Rectangle(IComponent parent, string name, Body body, bool fill) : base(parent, name, body)
{
Fill = fill;
Origin = new Vector2(.5f, .5f);
}
public override void Draw(SpriteBatch sb)
{
base.Draw(sb);
if (!Fill)
{
float minx = X + (Thickness/2) + Origin.X;
float miny = Y + (Thickness/2) +Origin.Y;
//TODO: Fix origin issue
//Draw our top line
sb.Draw(Assets.Pixel,
new Vector2(minx, miny), null, Color * Alpha, Angle, new Vector2(Origin.X, Origin.Y * Bounds.Y), new Vector2(Bounds.X, Thickness * Scale.Y), Flip, Layer);
//Left line
sb.Draw(Assets.Pixel,
new Vector2(minx, miny), null, Color * Alpha, Angle, new Vector2(Origin.X * Bounds.X, Origin.Y), new Vector2(Thickness * Scale.X, Bounds.Y), Flip, Layer);
//Essentially these are the same as the top and bottom just rotated 180 degrees
//I have to do it this way instead of setting the origin to a negative value because XNA
//seems to ignore origins when they are negative
//Right Line
sb.Draw(Assets.Pixel,
new Vector2(minx + 1, miny), null, Color * Alpha, Angle + MathHelper.Pi, new Vector2(Origin.X * Bounds.X, Origin.Y), new Vector2(Thickness * Scale.X, Bounds.Y), Flip, Layer);
//Bottom Line
sb.Draw(Assets.Pixel,
new Vector2(minx, miny + 1), null, Color * Alpha, Angle + MathHelper.Pi, new Vector2(Origin.X, Origin.Y * Bounds.Y), new Vector2(Bounds.X, Thickness * Scale.Y), Flip, Layer);
}
else
{
sb.Draw(Assets.Pixel, new Vector2(X + Origin.X*Width, Y + Origin.Y*Height), null, Color * Alpha, Angle, Origin, Bounds - new Vector2(Thickness), Flip, Layer);
}
}
Primitive
public abstract class Primitive : Render
{
public Body Body;
public float Thickness = 1;
protected Primitive(IComponent parent, string name) : base(parent, name)
{
Body = new Body(this, "Primitive.Body");
}
protected Primitive(IComponent parent, string name, Vector2 pos)
: base(parent, name)
{
Body = new Body(this, "Primitive.Body", pos);
}
protected Primitive(IComponent parent, string name, Body body) : base(parent, name)
{
Body = body;
}
public static void DrawLine(SpriteBatch sb, Vector2 p1, Vector2 p2, float thickness, float layer, Color color)
{
float angle = (float)System.Math.Atan2(p2.Y - p1.Y, p2.X - p1.X);
float length = Vector2.Distance(p1, p2);
sb.Draw(Assets.Pixel, p1, null, color,
angle, Vector2.Zero, new Vector2(length, thickness),
SpriteEffects.None, layer);
}
}
Render
類。這個並不像在那裏給任何渲染類賦予某種多態性那麼重要。
using EntityEngineV4.Engine;
using EntityEngineV4.PowerTools;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace EntityEngineV4.Components.Rendering
{
public abstract class Render : Component
{
public float Alpha = 1f;
public Color Color = Color.White;
public SpriteEffects Flip = SpriteEffects.None;
public float Layer;
public Vector2 Scale = Vector2.One;
public Vector2 Origin;
/// <summary>
/// Handy rectangle for getting the drawing position
/// </summary>
public virtual Rectangle DrawRect { get; set; }
/// <summary>
/// Source rectangle of the texture
/// </summary>
public virtual Rectangle SourceRect { get; set; }
/// <summary>
/// Bounds of the DrawRect
/// </summary>
public virtual Vector2 Bounds { get; set; }
protected Render(IComponent parent, string name)
: base(parent, name)
{
}
public override void Update(GameTime gt)
{
base.Update(gt);
}
public override void Draw(SpriteBatch sb = null)
{
base.Draw(sb);
}
}
}
如果您有任何問題,請不要害怕問!
謝謝你,讓我試試看。我會檢查矩陣的東西,我已經使用了一個用於我的相機,並且我在第一個'spritebatch.Draw'中使用它。我不知道你可以用矩陣旋轉單個物體,這肯定會讓我的生活更輕鬆。 :) – redcodefinal
我查了矩陣的東西,我認爲這會比它的價值更麻煩。此外,您的解決方案似乎沒有解決問題:( – redcodefinal
規模影響的起源...我雖然該部門將解決它...我已經添加了一個矩陣的代碼...我假設原點是矩形的中心......但是如果你想圍繞任意原點旋轉,很容易改變它 – Blau