2012-03-31 54 views
0

在XNA中,加载内容在初始化后调用,这足够公平,但是它导致加载纹理时出现一些问题。在XNA的类中使用静态Texture2D

在Init中,我将sprite的spriteTexture设置为Static Texture2D的spriteTexture。

在LoadContent我然后设置静态的Texture2D的值。这工作成功。

但是,当涉及到Draw()方法时,spriteTexture值仍为null,导致它失败。我该如何克服这一点?

有一种感觉,它的价值,而不是参考做过客。任何帮助?

感谢, 丹尼

代码: http://pastebin.com/C92ADY7s

回答

0

LoadContent方法调用constuctor之前,必须调用。否则,纹理未加载,spriteBatch被分配为空(spriteBatch=null;),因此未分配引用,并且稍后纹理编录无效。

0

构造函数将在LoadContent之前调用。那时,您switch声明中的行将全部分配给spriteTexture null

最简单的解决将是节省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; 

     ... 
} 

一个更好的解决方案可能是在某些Icon类,它有自己的LoadContent方法(这对于其特定Texture2D调用LoadContent)来包装Texture2D秒。然后当调用LoadContent时,它会加载Texture2Ds而不会丢弃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

如果你只是加载小/很少的纹理(不费时),你可以在MenuButton构造函数中调用加载内容。

+0

-1这是一个坏主意。永远不要在类实例构造函数中调用加载内容。 – MattDavey 2012-04-02 09:00:00

0

这是因为引用在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 pr操作被改变/覆盖/不管,因为它只保存对Icon类实例的引用,它不会改变。

*我实际上会试图给Icon类添加一个绘制方法。或者甚至是SpriteBatch直接绘制图标引用的扩展方法......这将更符合'tell don't ask'原则:)