首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >最佳实践: XNA中高效的sprite绘图

最佳实践: XNA中高效的sprite绘图
EN

Stack Overflow用户
提问于 2012-12-20 11:02:43
回答 3查看 4.8K关注 0票数 13

在我的2D XNA游戏中,什么是绘制精灵的有效方法?更确切地说,我把这个问题分成四个问题。

我过去常常声明Game1的spriteBatch 静态,并在每个IDrawable.Draw中调用SpriteBatch.Begin.Close。效果不太好。给每个可绘制的,它自己的SpriteBatch也不工作很好。

Q1:我认为最好有one SpriteBatch实例,并且只在一次调用begin/close 。这是正确的吗?

目前,我的Game1.Draw看起来是这样的:

代码语言:javascript
复制
spriteBatch.Begin();

base.Draw(gameTime); // draws elements of Game.Components

// ...

spriteBatch.End();

Q2:这样,Begin只被调用一次。这是该走的路吗?你们是怎么解决的?

Q3:每个组件都有自己的IGameComponent.LoadContent方法。我应该把我的内容放在那里吗?还是在父类(如Game1.LoadContent )中加载内容更好?

我意识到我不应该两次加载相同的内容,所以我给了我的可绘制组件一个静态的和一个非静态的Texture2D,并给了它们两个构造函数:

代码语言:javascript
复制
static Texture2D defaultTexture;
public Texture2D MyTexture;

public Enemy()
    : this(defaultTexture) { }

public Enemy(Texture2D texture)
{
    MyTexture = texture;
}

protected override void LoadContent()
{
    if (MyTexture == null)
    {
        if (defaultTexture == null)
        {
            defaultTexture = Content.Load<Texture2D>("enemy");
        }

        MyTexture = defaultTexture;
    }
}

这样,类的默认纹理只在类上第一次调用LoadContent时加载。但是,当参数texture在构造函数中指定时,我必须事先加载该纹理。

Q4:我认为应该有更好的方法来做到这一点。我正在考虑创建一个纹理字典,将它们的资产名作为字符串。你有什么建议?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-20 11:15:30

我曾经声明Game1的spriteBatch是静态的

你不需要让它静止下来。做个单身的。内Draw

代码语言:javascript
复制
SpriteBatch spriteBatch = ScreenManager.SpriteBatch; // singletion SpriteBatch
spriteBatch.Begin();
// Draw the background
spriteBatch.Draw(background, ...
foreach (var enemy in enemys)
{
     enemy.Draw(gameTime);
}
// etc.
spriteBatch.End(); // call here end 
base.Draw(gameTime); // and then call the base class

我认为最好有一个SpriteBatch实例,并且只调用begin/close一次。这是正确的吗?

我建议您在一个方法中打开和结束SpriteBatch。它将帮助您避免与开始绘图但未完成的SpriteBatch发生冲突。

是否将元素添加到组件的全局集合中?这是一个错误的想法添加可绘制到这个集合。无法控制绘图顺序,组件是全局的。见这个答案

在组件中实现IUpdatable和IDrawable,并在需要时在代码中调用它们。摆脱静态的东西,并使用依赖注入网站。

而且,每个组件都有自己的IGameComponent.LoadContent方法。我应该把我的内容放在那里吗?还是在父类(如Game1.LoadContent )中加载内容更好?

您应该在需要时加载资产,并对其负责。当用户刚开始游戏的时候,你不需要加载所有的30个级别,是吗?例如,当游戏开始时,您将加载开始屏幕和主菜单所需的所有资产。如果你只加载你需要的东西,玩家就会很高兴,游戏开始的很快。然后玩家想要开始游戏。在这里,您可以在一个单独的线程上加载资产,以保持应用程序响应。

我认为应该有更好的方法来做这件事。我正在考虑创建一个纹理字典,将它们的资产名作为字符串。你有什么建议?

Content.Load已经被缓存了,所以您不必这么做。

票数 3
EN

Stack Overflow用户

发布于 2012-12-20 11:12:33

教程 在周围收集到的资料

只调用一次begin和end是首选的方法。

票数 1
EN

Stack Overflow用户

发布于 2012-12-21 09:45:41

Q4:我认为应该有更好的方法来做到这一点。我正在考虑创建一个纹理字典,将它们的资产名作为字符串。你有什么建议?

A4:我通常在TextureLib类中创建一个Dictionary<string, Texture2D> NameTextureDic (它在运行时处理png图像的加载),因此我可以获得如下任何纹理:

代码语言:javascript
复制
var t2d = textureLib.NameTextureDic["tree-4"];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13970726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档