xna只绘制一次spograbatch

时间:2014-01-12 12:32:30

标签: c# xna

我是xna编程的新手我需要一点帮助...

我用静态背景构建了一个2D游戏 在我当前的屏幕上有背景图像,左边有4个大图像,我需要在右边绘制16个小图像(50x50或更少)

所以这是我更新左侧16幅图像位置的方法 它仅由Update

调用一次
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;
            }
        }
    }

这是我的更新方法

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();
            }


        }
    }

这是我的Draw方法

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个更小的方法? 或者因为我在这里的经验非常少,所以在这段代码中有什么必须改变,这使得当我绘制这些照片时游戏运行缓慢吗?

提前致谢

3 个答案:

答案 0 :(得分:2)

您正在Draw调用期间初始化Graphics Device,SpriteBatch,SpriteFont和Textures。这真的很糟糕。

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

答案 1 :(得分:1)

我刚刚从draw方法中移除了for循环,然后调用spriteBatch.Draw 16次,每个sprite一次。 是的,显然这不是最好的解决方案,但它有效并且速度再次恢复正常。 此外,我将所有初始化都移出了Draw或更新,就像Jon在提高代码速度之前所提到的那样。

答案 2 :(得分:0)

您的代码段中没有可以减慢应用程序速度的地方。尝试使用秒表测试绘图和更新方法。使用fps 60(默认情况下),总共不应超过1/60秒。尝试本地化你游戏的确切部分。

只有在图像不正确时才能绘制图像。 XNA不是WinForms,而Draw()会调用每一帧,你应该清除屏幕并重新绘制所有想要显示给玩家的内容。游戏循环很简单:一旦调用Initialize()和LoadContent,然后在'无限'的cicle中调用Update和Draw以及某些频率,最后一次调用UnloadContent。

如果您希望在点击之后更改图像,则需要有两个图像 - 单击和未单击,以及一些变量以保持每个图像的状态。您在Update方法中检查鼠标/键盘输入,更改变量状态,并在Draw方法中决定传递给spritebatch.Draw()调用的图像。此外,如果您有一些由很多精灵组成的复杂场景,您可以在每次更新后将其绘制为仅渲染目标一次,然后将其绘制为一个实体纹理('lot'表示100s,如Terraria,但不是16蓝色rects)