Класс спрайтов XNA

Я работаю с XNA 3.0 и пытаюсь создать класс спрайтов, но не знаю, как к нему подойти. Выполнять ли анимацию внутри класса спрайтов? Я также продолжаю получать сообщение об ошибке с моим кодом

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


person Arminium    schedule 16.03.2012    source источник
comment
возможный дубликат Ссылка на объект требуется для не- статическое поле   -  person Alexei Levenkov    schedule 16.03.2012


Ответы (1)


Во-первых, вторая ошибка: "Для нестатического поля, метода или свойства требуется ссылка на объект".

В объектно-ориентированном программировании программы имеют преимущество структуры благодаря таким понятиям, как классы и наследование, в отличие от исторического императивного программирования, в котором «программы» состояли из серии основных инструкций, следующих одна за другой. В объектно-ориентированном программировании класс представляет некоторую абстрактную сущность. Такими сущностями могут быть животное, машина, телевизор. В таких случаях имеет смысл написать class Car и «создать» множество «экземпляров» объектов Car, один из которых может называться Honda, другой BMW и еще один Rolls-Royce. Но иногда нет смысла создавать экземпляры класса. Что, если твой урок не был машиной, а что, если это была «Математика». Вполне допустимо иметь класс «Математика» — фактически, .NET framework имеет класс Math. Но в таком случае не имеет смысла иметь «экземпляры» Math. Математика есть математика. Это исследование - и это только одно из них.

Таким образом, доступ к нестатическим методам осуществляется следующим образом:

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

Говорить Car.Drive() не имеет смысла, потому что какую машину вы имеете в виду? Автомобиль как класс — это всего лишь общий план — вы хотите вызвать new Car(), чтобы сделать некоторые конкретные объекты из этого плана класса.

С другой стороны, доступ к статическим методам осуществляется следующим образом:

Math.Add();

Говорить 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

Что мне действительно понравилось в этой статье, так это следующее определение: абстрактные классы определяют основные функции, а интерфейсы описывают периферийные атрибуты.

Ваш спрайт может не только анимироваться, но и двигаться. Это больше похоже на атрибуты, чем на основную функциональность. У него есть способность анимировать. У него есть способность двигаться. Некоторые люди считают, что интерфейсы имеют отношение "имеет", тогда как классы полагаются на отношение "является". Ваш класс не является по существу анимацией — это прежде всего спрайт. тогда он может анимироваться.

Поэтому я думаю, вам следует расширить свой класс 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;}
}

А в будущем у вас может быть даже:

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, но, по крайней мере, вы установили явный контракт между спрайтами, анимируемыми спрайтами и подвижными спрайтами. Позже будет намного проще редактировать и расширять.

person Jason    schedule 16.03.2012