XNA精灵类

Arm*_*ium 2 c# xna animation sprite xna-3.0

我正在使用XNA 3.0并尝试创建一个精灵类,但我不确定如何处理它.我是否在精灵类中执行动画?我的代码也一直收到错误

Game1.cs

protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();
        Sprite.Draw(spriteBatch);
        base.Draw(gameTime);
    }
Run Code Online (Sandbox Code Playgroud)

Sprite.cs

private static Texture2D rings;

    Point rings_frameSize = new Point(75, 75);
    Point rings_currentFrame = new Point(0, 0);
    Point rings_sheetSize = new Point(6, 8);

    int ms_elapsedRings = 0;

    public static void setup_sprites(ContentManager Content)
    {
        rings = Content.Load<Texture2D>("Images/threerings");
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(rings,
                         new Vector2(0,0),
                         new Rectangle(rings_currentFrame.X * rings_frameSize.X, //X component of where to begin
                                       rings_currentFrame.Y * rings_frameSize.Y, //Y component of where to begin
                                       rings_frameSize.X,  //cell width
                                       rings_frameSize.Y), //cell height
                         Color.White,
                         0,
                         Vector2.Zero,
                         1,
                         SpriteEffects.None,
                         0);
    }
Run Code Online (Sandbox Code Playgroud)

返回

错误1非静态字段,方法或属性'WindowsGame1.Sprite.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch)'C:\ Users\XXXXXX\Documents\Visual Studio 2008\Projects需要对象引用\ WindowsGame1\WindowsGame1\Game1.cs 107 13 WindowsGame1

Jas*_*son 5

首先,您的第二个错误: " 非静态字段,方法或属性需要对象引用 ".

在面向对象的编程中,程序具有结构的好处,通过类和继承等概念,而不是历史命令式编程,其中"程序"由一系列基本指令组成,一个接一个.在面向对象的编程中,类表示一些抽象实体.这些实体可以是动物,汽车,电视.在这种情况下,你可以写一个class Car并"创造"许多Car物体的"实例"是有道理的,其中一个可能叫做本田,另一个叫宝马,另一个叫劳斯莱斯.但有时,创建类的实例没有意义.如果你的班级不是汽车怎么办 - 如果它是"数学"怎么办?拥有一个"Math"类是完全有效的 - 事实上,.NET框架有一个Math类.但在这种情况下,拥有数学的"实例"是没有意义的.数学是数学.这是一项研究 - 而且只有一项研究.

因此,非静态方法的访问方式如下:

Car honda = new Car();
honda.Drive();
Run Code Online (Sandbox Code Playgroud)

说Car.Drive()是没有意义的,因为你指的是辆车?Car,作为一个类,只是一个通用蓝图 - 你想调用new Car()从该类蓝图中制作一些具体的对象.

另一方面,访问静态方法,如下所示:

Math.Add();
Run Code Online (Sandbox Code Playgroud)

说这就没有意义Math myMath = new Math();,这就是为什么Math是它自己的静态类.

现在,你已经制定了方法setup_sprites() static.您可能认为此设置方法应该是静态的,因为无论创建了多少个精灵,每个创建的精灵都将在设置期间访问相同的纹理.如果你想以这种方式制作精灵类,那很好 - 但是你必须使你的整个精灵类静态,因为静态方法和变量不能访问非静态方法和变量.

通常,Sprite类不是静态的.您可以在此处阅读有关静态与非静态的更多信息:http://msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.80%29.aspx.

现在,你的第一个问题.如何将动画集成到代码中完全取决于您.看起来您在Draw()方法中嵌入了动画代码.这没有错,但可能有更好的解决方案.

面向对象编程有一些原则可以保持复杂性简单,其中之一就是单一责任原则,简单来说,它建议程序员只给一个班级一个职责.您的Sprite类应该只是加载其资源,绘制自己并卸载其资源.这都是精灵应该做的.

但是动画呢?这就是面向对象编程的用武之地 - 分担责任; 你不必把所有东西都粘在Sprite类中.你有两个选择:你可以扩展你Sprite在的表单功能AnimatedSprite从继承类Sprite类,也可以扩展你Sprite在的表单功能Animatable接口.这里的设计问题是:按类或接口扩展?

你可以在这里阅读更多有关辩论的内容:http://www.codeproject.com/Articles/11155/Abstract-Class-versus-Interface

我从该文章中真正喜欢的是以下定义:抽象类定义核心功能,而接口描述外围属性.

你的精灵不仅可以动画,还可以移动.这听起来更像是属性而不是核心功能.它具有动画的能力.它有移动的能力.有些人认为接口具有" has-a "关系,而类被认为具有" is-a "关系.你的类本质上不是动画 - 它首先是一个精灵.然后它具有动画的能力.

所以我认为你应该Sprite通过添加一个Animatable接口来扩展你的课程.您实际上想要调用它IAnimatable,以保留命名标准.

所以你最终会得到类似的东西(伪代码):

public class Sprite : IAnimatable
{
    private Texture2D rings;

    public void LoadContent(ContentManager Content)
    {
        // Call this method from Game.LoadContent()
        rings = Content.Load<Texture2D>("Images/threerings");
    }

public void Draw(SpriteBatch spriteBatch)
    {
        if (IsAnimating)
        {
            // Incorporate IAnimatable variables here to draw your animation
        }
    }

}

public interface IAnimatable
{
    public bool IsAnimating {get; set;}
    public int CurrentFrameIndex {get; set;}
    public Point FrameSize {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

在将来,您甚至可能拥有:

public interface IMovable
{
    public bool IsMoving {get; set;}
    public Point CurrentLocation {get; set;}
    public Point DestinationLocation {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

并将所有这些整合到:

public class NpcSprite : Sprite, IMovable, IAnimatable
{
}
Run Code Online (Sandbox Code Playgroud)

确实,即使使用接口,你仍然最终在Sprite类中编写接口代码,但至少你已经建立了精灵,可动画精灵和可移动精灵之间的明确契约.稍后编辑和扩展会更容易.