【问题标题】:How to draw and move a square in XNA?如何在 XNA 中绘制和移动一个正方形?
【发布时间】:2012-06-18 23:21:55
【问题描述】:

我试图在 XNA 中绘制一个正方形,然后根据用户输入简单地用键盘移动它。不幸的是,我什至无法让正方形显示 - 我很肯定我在这里遗漏了一些东西,但我无法弄清楚它到底是什么。我计划创建一个可以在我的游戏中使用的原始形状的复杂层次结构。 Shape 类的主要组件被初始化,派生类(在本例中为 Rect)利用这些组件进一步使用并配置它们。

我在这里做错了什么?

代码

Shape.cs

public abstract class Shape
    {
        public Vector3 Center;
        public Color[] Colors;
        public bool SetColorsOnUpdate;

        public virtual Rectangle BoundingBox { get; set; }
        public float Radius { get { return mRadius; } }

        protected VertexBuffer mVertexBuf;
        protected IndexBuffer mIndexBuf;
        protected float mRadius;
        protected BasicEffect mShader;

        public Shape(Vector3 center, Color[] colors, int numVertices, float radius)
        {
            Colors = colors;
            Center = center;
            mVertexBuf = new VertexBuffer(Graphics.MainDevice, typeof(VertexPositionColor), numVertices, BufferUsage.WriteOnly);
            mIndexBuf = new IndexBuffer(Graphics.MainDevice, IndexElementSize.SixteenBits, numVertices, BufferUsage.WriteOnly);
            SetColorsOnUpdate = true;
            mShader = new BasicEffect(Graphics.MainDevice);
            mRadius = radius;
        }

        public abstract void Update();
        public abstract void Draw();
    }

Rect.cs

public class Rect : Shape
{
    public override Rectangle BoundingBox
    {
        get
        { 
            int x = (int)Center.X, y = (int)Center.Y;
            int diameter = (int)mRadius * 2;

            return new Rectangle(
                x, y,
                x + diameter, 
                y + diameter
            );
        }
    }

    const float TestRectZCoordinate = 0;
    const int NumVertices = 4;

    public Rect(Vector3 center, Color[] colors, float radius)
        : base(center, colors, NumVertices, radius)
    {
        if (colors.Length < NumVertices)
            throw new IndexOutOfRangeException(string.Format("Color array passed to Rect constructor MUST have an element index size of 4. Current length passed is {0}", colors.Length));

        mShader.VertexColorEnabled = true;

        mVertexBuf.SetData<VertexPositionColor>(
                new VertexPositionColor[]
                {
                    new VertexPositionColor(new Vector3(Center.X + mRadius, Center.Y + mRadius, TestRectZCoordinate), Colors[0]),
                    new VertexPositionColor(new Vector3(Center.X + mRadius, Center.Y - mRadius, TestRectZCoordinate), Colors[1]),
                    new VertexPositionColor(new Vector3(Center.X - mRadius, Center.Y - mRadius, TestRectZCoordinate), Colors[2]),
                    new VertexPositionColor(new Vector3(Center.X - mRadius, Center.Y + mRadius, TestRectZCoordinate), Colors[3])
                }
            );

        mIndexBuf.SetData<short>(new short[] { 0, 1, 2, 3 });
    }

    public override void Update()
    {
        //TODO
    }

    public override void Draw()
    {
        mShader.World = Matrix.CreateWorld(Center, Vector3.Forward, Vector3.Up);
        mShader.CurrentTechnique.Passes[0].Apply();

        Graphics.MainDevice.SetVertexBuffer(mVertexBuf);
        Graphics.MainDevice.Indices = mIndexBuf;

        Graphics.MainDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, NumVertices, 0, 1);
    }
}

更新

这是最新的 Rect.Draw() 实现。

public override void Draw()
    {
        Viewport viewport = Graphics.MainDevice.Viewport;

        mShader.World = Matrix.CreateWorld(Center, Vector3.Forward, Vector3.Up);
        mShader.View = Matrix.CreateLookAt(new Vector3(viewport.Width / 2, viewport.Height / 2, -5f), Center, Vector3.Up);
        mShader.CurrentTechnique.Passes[0].Apply();

        Graphics.MainDevice.SetVertexBuffer(mVertexBuf);
        Graphics.MainDevice.Indices = mIndexBuf;

        Graphics.MainDevice.DrawIndexedPrimitives(PrimitiveType.LineStrip, 0, 0, NumVertices, 0, 2);
    }

【问题讨论】:

  • 您是否正确设置了相机以使形状可见??
  • @PaulG,我相信是的。我不太确定我是否正确地这样做了,或者我是否需要这样做。这是一个 2D 游戏 - 因此我需要相机吗?
  • 是的,这是必要的。请发布您的投影矩阵/世界矩阵。
  • 我所有的 2D XNA 项目都是基于精灵的,所以我从来没有像你尝试过的那样真正尝试过它。但我确实知道只会绘制三角形的一个面,请确保您的可见面是相机指向的那一侧。尝试旋转三角形来查看。
  • 我的问题中有一小段代码可以让你开始:stackoverflow.com/questions/11091163/…

标签: c# graphics xna


【解决方案1】:

啊 - 我想我至少看到了您的一个问题。您正在绘制一个 TriangleList(请参阅 PrimitiveType)并且您需要 6 个索引,而不是 4 个。

知道了。看起来您的顶点/索引顺序错误。我也没有看到投影矩阵。

这是对我来说非常有用的代码 - 我所做的只是添加一个投影矩阵、重新排序顶点、更改索引并修复图元计数。

http://pastebin.com/tMKCxBLL

希望这会有所帮助!

【讨论】:

  • 另外,如果你正在绘制一个正方形,你需要 2 个基元而不是 1 个
  • ananthonline:这两个额外的索引到底是干什么用的?
  • 根据文档,TriangleList 的意思是“数据按三角形序列排序;每个三角形由三个新顶点描述。背面剔除受当前缠绕顺序渲染状态的影响” .因此,给定 4 个顶点,您的索引是 { 0, 1, 2, 0, 2, 3 } 或类似的东西。六个索引组成两个三角形(有 4 个顶点)。 XNA 不能像 OpenGL 那样渲染四边形。
猜你喜欢
  • 2022-12-09
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-27
相关资源
最近更新 更多