使用静态纹理2D';s在XNA的课堂上
本文关键字:XNA 课堂 静态 纹理 2D | 更新日期: 2023-09-27 18:29:48
在XNA中,加载内容是在init之后调用的,这很公平,但它给我加载纹理带来了一些问题。
在Init中,我将精灵的精灵纹理设置为静态纹理2D的精灵纹理。
在LoadContent中,我然后设置静态纹理2D的值。这是成功的。
但是,当使用Draw()方法时,spriteTexture值仍然为null,导致它失败。我该如何克服这一点?
有一种感觉,这与传递价值而不是参考有关。有什么帮助吗?
谢谢,Danny
代码:http://pastebin.com/C92ADY7s
在调用构造函数之前,必须调用LoadContent
方法。否则,不会加载纹理,并且spriteBatch被指定为null(spriteBatch=null;
),因此不会指定引用,以后的纹理loding也没有效果。
构造函数将在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
方法(为其特定的Texture2D
调用LoadContent
)。然后,当调用LoadContent时,它将加载Texture2D,而不会丢弃图标引用。
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);
...
}
}
如果你只是加载小/少的纹理(不耗时),jou可以在MenuButton构造函数中调用加载内容。
这是因为引用在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.Tructure=content.load("blah.png");),我们的绘图方法会起作用*:)
现在,当Icon.Texture属性被更改/覆盖时,MenuButton类不受影响,因为它只保存对Icon类实例的引用,而不会更改。
*
实际上我很想在Icon类中添加一个draw方法。或者甚至是SpriteBatch的扩展方法,直接绘制图标引用。。。这将更符合"告诉不要问"的原则:)