2014-01-12 52 views
2

我是新来的XNA编程我在这里需要一些帮助......XNA绘制spritebatch只有一次

我建立一个2D游戏,与静态背景 在我目前的屏幕有背景图片,4张大图片在左边,我需要画16幅小图像(50x50的更多或更少)右侧

所以这是我的方法来更新左边 的16个图像的位置,它是由更新

调用一次
private void letterLblsLocation() 
    { 
     if (letterLbls.Count != 0) 
     { 
      letterlblposition = new Vector2(0f, 0f); 
      lblvector = new Vector2(0f, 0f); 
      int col = 1; 
      int lblsize = ScreenManager.GraphicsDevice.Viewport.Height/15; 
      for (int lbl = 0; lbl < letterLbls.Count; lbl++) 
      { 
       letterlblposition.X = ScreenManager.GraphicsDevice.Viewport.Width - (col * lblsize); 
       letterlblposition.Y += 5 + lblsize; 
       if (letterlblposition.Y > ScreenManager.GraphicsDevice.Viewport.Height - lblsize) 
       { 

        col = col + 3; 
        letterlblposition.Y = 5 + lblsize; 
       } 
       recsOnRight.Add(new Rectangle((int)letterlblposition.X, (int)letterlblposition.Y, lblsize, lblsize)); 

       lblvector.X = recsOnRight[lbl].X + 5; 
       lblvector.Y = recsOnRight[lbl].Y; 
       letterLbls[lbl].Position = lblvector; 
      } 
     } 
    } 

Th是我更新方法

public override void Update(GameTime gameTime, bool otherScreenHasFocus,bool coveredByOtherScreen) 
    { 
     base.Update(gameTime, otherScreenHasFocus, false); 



     // Gradually fade in or out depending on whether we are covered by the pause screen. 
     if (coveredByOtherScreen) 
      pauseAlpha = Math.Min(pauseAlpha + 1f/32, 1); 
     else 
      pauseAlpha = Math.Max(pauseAlpha - 1f/32, 0); 

     if (IsActive) 
     { 
      if(questionNeeded) 
      { 
       ChooseWord(); 
       ChooseLettersOnRight(); 
       LabelsWithLetters(); 
       letterLblsLocation(); 
      } 


     } 
    } 

这是我的绘制方法

public override void Draw(GameTime gameTime) 
    { 

     spriteBatch.Begin(); 
     spriteBatch.Draw(background, new Rectangle(0, 0, ScreenManager.GraphicsDevice.Viewport.Width, ScreenManager.GraphicsDevice.Viewport.Height), Color.White); 
     if (!questionNeeded) 
     { 
      for (int i = 0; i < 16; i++) 
      { 
       if (i < 4) 
       { 
        Texture2D helpTexture = questionToDisplay.pic[i]; 
        Rectangle helpRect = questionToDisplay.picRecs[i]; 
        spriteBatch.Draw(helpTexture, helpRect, Color.White); 
       } 
       spriteBatch.Draw(labelSquare, recsOnRight[i], Color.White); 
       } 
      } 

     spriteBatch.End(); 

现在我的问题是,当我尝试借鉴权的比赛中16 spritebatch变慢 有没有一种办法只有当玩家点击其中的一张时才画出16张图片并重新绘制它们? 或合并它们以绘制一个大图像而不是16个较小的方法? 或者因为我在这里的经验很少,这个代码中有什么必须改变,这让我画这个图片时游戏运行缓慢?

在此先感谢

+0

16个精灵甚至不应该有明显的性能影响。除非他们的分辨率非常高。你确定问题是由绘制代码造成的吗? –

+0

尼科如果我删除此循环,然后速度又恢复正常...所以这就是为什么认为问题出现在Draw中,至于图片我试图加载的分辨率是一个简单的蓝色方块100x100像素 – nansyg21

回答

2

要初始化图形设备,SpriteBatch,SpriteFont类和纹理绘制的通话过程中。这真的很糟糕。

将这些初始化移动到Draw函数之外的LoadContent()函数中,并且只初始化一次。

+0

好吧,我将它们移动到LoadContent()...事实是,那里是一个小改进(谢谢),但速度仍然缓慢 – nansyg21

0

您的代码片段中没有可以减慢应用程序速度的地方。尝试使用秒表测试绘图和更新方法。 fps 60(默认)应该不超过1/60秒。尝试本地化游戏的速度。

只有在绘制图像不正确时才如此。 XNA不是WinForms,而Draw()调用每一帧,你应该清除屏幕并重新绘制所有你想要展示给玩家。游戏循环很简单:一旦调用Initialize()和LoadContent,那么在'无尽的'cicle中调用Update和Draw以一定的频率和一次UnloadContent的调用结束。

如果你想要改变图像点击后,你需要有两个图像 - 点击和不点击,以及一些变量来保持每个人的状态。您在Update方法中检查鼠标/键区输入,更改变量状态并在Draw方法中决定将图像传递给spritebatch.Draw()调用。同样,如果你有一些复杂的场景,包含很多精灵,你可以在每次更新之后将其绘制为渲染目标一次,然后将其绘制为一个实体纹理(“很多”意味着像Terraria中的100s,但不是16个蓝色纹理) 。

+0

问题是我试图本地化缓慢的部分。这就是我提到for循环的原因。我仍然不知道为什么用for循环的程序很慢,如果我写同样的方法调用16次,它工作正常。但是我在回答中采用了我在下面描述的方式。 – nansyg21

1

嗯,我刚刚从draw方法中删除了for循环,然后调用spriteBatch.Draw 16次,每个sprite一个。 显然这不是最好的解决方案,但它的工作和速度再次恢复正常。 另外我把所有的初始化从Draw或Update中移出,正如Jon在提到代码更快之前提到的那样。