XNA Sprite Class



我正在使用XNA 3.0并试图创建一个sprite类,但不确定如何处理它。我在sprite类中执行动画吗?我的代码也一直收到错误

Game1.cs

protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        Sprite.Draw(spriteBatch);
        base.Draw(gameTime);
    }

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);
    }

返回

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

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

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

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

Car honda = new Car();
honda.Drive();

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

另一方面,静态方法是可以访问的,比如:

Math.Add();

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

现在,您已经制作了方法setup_sprites() static。您可能会认为这种设置方法应该是静态的,因为无论创建了多少个精灵,每个创建的精灵都将在设置过程中访问相同的纹理。如果你想用这种方式创建你的sprite类,那没关系,但你必须让你的整个sprite类都是静态的,因为静态方法和变量不能访问非静态方法和参数

不过,一般来说,Sprite类并不是静态的。你可以在这里阅读更多关于静态与非静态的信息:http://msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.80%29.aspx.

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

面向对象编程有几个原则来保持复杂性的优雅简洁,其中之一就是单一责任原则,简单地说,它建议程序员只给一个类一个责任。Sprite类应该简单地加载它的资源、绘制它自己并卸载它的资源。这就是精灵应该做的。

但是动画呢?这就是面向对象编程的用武之地——分担这一职责;您不必将所有内容都粘贴到Sprite类中。您有两种选择:您可以以继承自Sprite类的AnimatedSprite类的形式扩展Sprite功能,也可以以Animatable接口的形式扩展您的Sprite功能。这里的设计问题是:通过类还是接口进行扩展?

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

我从那篇文章中真正喜欢的是以下定义:抽象类定义核心函数,而接口描述外围属性。

精灵不仅可以设置动画,还可以移动。这些听起来更像是属性,而不是核心功能。它具有设置动画的能力。它有移动的能力。有些人认为接口具有"has-a"关系,而类则被认为具有"is-a就可以设置动画。

所以我认为您应该通过添加Animatable接口来扩展Sprite类。实际上,您希望将其称为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;}
}

在未来,你甚至可能有:

public interface IMovable
{
    public bool IsMoving {get; set;}
    public Point CurrentLocation {get; set;}
    public Point DestinationLocation {get; set;}
}

并将所有这些集成到:

public class NpcSprite : Sprite, IMovable, IAnimatable
{
}

的确,即使使用接口,您最终还是会在Sprite类中编写接口代码,但至少您已经在精灵、可设置动画的精灵和可移动的精灵之间建立了明确的契约。以后编辑和扩展会容易得多。

相关内容

  • 没有找到相关文章

最新更新