XNA Sprite Class - PullRequest
       37

XNA Sprite Class

2 голосов
/ 16 марта 2012

Я работаю с 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

1 Ответ

5 голосов
/ 16 марта 2012

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

В объектно-ориентированномпрограммирование, программы имеют преимущество структуры, благодаря таким понятиям, как классы и наследование, в отличие от исторического императивного программирования, в котором «программы» состояли из серии базовых инструкций, одна за другой.В объектно-ориентированном программировании класс представляет некоторую абстрактную сущность.Такими объектами могут быть животное, машина, телевизор.В таких случаях имеет смысл написать class Car и «создать» множество «экземпляров» из Car объектов, один из которых может называться Honda, другой BMW и другой Rolls-Royce.Но иногда не имеет смысла создавать экземпляры класса.Что, если ваш класс не был автомобилем - что, если это был "Математика".Вполне допустимо иметь класс "Math" - на самом деле, .NET Framework имеет класс 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

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

Ваш спрайт может не только анимировать, но и перемещать.Это больше похоже на атрибуты, чем на основные функции.Обладает способностью оживлять.У него есть способность двигаться.Некоторые люди считают, что интерфейсы имеют отношение " 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;}
}

И в будущем вы можете даже иметь:

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

...