Во-первых, вторая ошибка: "Для нестатического поля, метода или свойства требуется ссылка на объект".
В объектно-ориентированном программировании программы имеют преимущество структуры благодаря таким понятиям, как классы и наследование, в отличие от исторического императивного программирования, в котором «программы» состояли из серии основных инструкций, следующих одна за другой. В объектно-ориентированном программировании класс представляет некоторую абстрактную сущность. Такими сущностями могут быть животное, машина, телевизор. В таких случаях имеет смысл написать 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