Использование статических Texture2D в классах в XNA - PullRequest
0 голосов
/ 01 апреля 2012

В содержимом загрузки XNA вызывается после init, что достаточно справедливо, однако оно вызывает у меня некоторые проблемы с загрузкой текстур.

В Init я устанавливаю spriteTexture для спрайта равным статическому Texture2D.

В LoadContent я затем устанавливаю значение статической Texture2D.Это работает успешно.

Однако значение spriteTexture по-прежнему равно нулю, когда дело доходит до метода Draw (), что приводит к сбою.Как я могу преодолеть это?

чувствую, что это связано с передачей по значению, а не ссылкойЛюбая помощь?

Спасибо, Дэнни

Код: http://pastebin.com/C92ADY7s

Ответы [ 4 ]

0 голосов
/ 02 апреля 2012

Это происходит из-за того, как ссылки работают в C #.Вот простой пример использования строк вместо текстур:

String foo = null; // A null reference is assigned to the foo variable...

String bar = foo; // The null reference is *copied* to the bar variable. We now have 2 distinct references..

foo = "foo"; // The foo variable is *overwritten* with a new reference to the string...

bar != "foo"; // The bar variable is not affected at all, its own reference still points at null.

Теперь, если вы хотите ссылаться на текстуру до ее загрузки, вам нужно будет обеспечить уровень косвенности для фактического члена Texture2D, таким образомизбегая копирования нулевой ссылки для начала ...

static public Icon
{
    public Texture2D Texture; // starts with null...

    static public Icon PlayButton = new Icon(); // Not a null reference, even though the texture hasn't been loaded yet...
}


public class MenuButton
{
    public MenuButton()
    {
        this.Icon = Icon.PlayButton; // Again, not a null reference...
    }

    public Icon Icon { get; set; }

    public void Draw()
    {
        SpriteBatch.Draw(this.Icon.Texture); // etc...
    }
}

Теперь, пока мы вызываем загрузочный контент (Icon.MenuButton.Texture = Content.Load ("blah.png");), наша ничьяметод будет работать *:)

Теперь класс MenuButton не затрагивается, когда свойство Icon.Texture изменяется / перезаписывается / каким-либо другим образом, поскольку оно содержит только ссылку на экземпляр класса Icon, который не изменяется.

* Я действительно хотел бы добавить метод рисования в класс Icon.Или даже метод расширения для SpriteBatch для непосредственного рисования ссылки на Icon ... это будет более соответствовать принципу ' сказать не спрашивать ':)

0 голосов
/ 02 апреля 2012

Конструктор будет вызываться до LoadContent. В это время все строки в вашем операторе switch будут назначать null для spriteTexture.

Самым простым решением было бы сохранить значение requestedMenuButtonType и поместить оператор switch (или вызов метода, содержащего оператор switch) в LoadContent (в точке после загрузки значков). , Пример:

private static MenuButtonType savedMenuButtonType;

public MenuButton(int requestedX, int requestedY, int requestedWidth, int requestedHeight, MenuButtonType requestedMenuButtonType)
   : base(requestedX, requestedY, requestedWidth, requestedHeight)
   {
      ...
      savedMenuButtonType = requestedMenuButtonType;
      ...
   }

public static void LoadContent(ContentManager Content)
{
   ...
   //Main Menu Icons
   ...
   //About Menu Icons
   ...
   spriteTexture = GetRequestedSpriteTexture();
}

private static Texture2D GetRequestedSpriteTexture()
{
   switch (savedMenuButtonType)
   {
      case MenuButtonType.play:
         return playButtonIcon;
         break;

      ...
}

Лучшим решением может быть обтекание Texture2D в некотором классе Icon, который имеет собственный метод LoadContent (который вызывает LoadContent для своего конкретного Texture2D). Затем, когда вызывается LoadContent, он загружает Texture2D, не выбрасывая ссылки Icon.

public class Icon
{
   private string mTextureName;
   private Texture2D mTexture;

   public Icon(string pTextureName)
   {
      mTextureName = pTextureName;
   }
   ...
   public void LoadContent(ContentManager Content)
   {
      mTexture = Content.Load<Texture2D>(mTextureName);
   }
   ...
}

public class MenuButton : SpriteObject
{
   private Icon spriteIcon;

   //Different Icons, static for loading
   private static Icon playButtonIcon = new Icon("Menu Items/Menu Buttons/PlayButtonIcon");
   ...

   public MenuButton(int requestedX, int requestedY, int requestedWidth, int requestedHeight, MenuButtonType requestedMenuButtonType)
      : base(requestedX, requestedY, requestedWidth, requestedHeight)
   {
      ...
      spriteIcon = playButtonIcon;
      ...
   }

   public void LoadContent(ContentManager Content)
   {
      ...
      playButtonIcon.LoadContent(Content);
      ...
   }        
}
0 голосов
/ 02 апреля 2012

Если вы просто загружаете небольшие / несколько текстур (не отнимающих много времени), вы можете просто вызвать загрузку содержимого в конструкторе MenuButton.

0 голосов
/ 01 апреля 2012

Метод LoadContent должен быть вызван перед вызовом конструктора.В противном случае текстуры не загружаются, и spriteBatch присваивается значение null (spriteBatch=null;), поэтому ссылки не назначаются, и более поздняя кодировка текстур не оказывает влияния.

...