对象处置要抛出的异常

发布于 2024-10-10 09:22:53 字数 3058 浏览 0 评论 0原文

我最近将 HUD 方法集成到我的 XNA 游戏项目中,当主 Draw 方法调用该方法时,它会抛出一个对象处置异常,这与程序中使用的两个 Drawstring 有关。

spriteBatch.End() 处抛出异常,并显示无法访问已释放的对象。 对象名称:“Texture2D”。

      //initiation of the spritebatch 
     private SpriteBatch spriteBatch;

    //game draw method
    public override void Draw(GameTime gameTime)
            {
                ScreenManager.GraphicsDevice.Clear(Color.CornflowerBlue);

                // Our player and enemy are both actually just text strings.
                spriteBatch = ScreenManager.SpriteBatch;

                tileMap.Draw(spriteBatch, camera);

                spriteBatch.Begin(SpriteSortMode.Deferred,
                     BlendState.AlphaBlend,
                     null, null, null, null,
                     camera.TransformMatrix);

                DrawHud();

                level.Draw(gameTime, spriteBatch);

                spriteBatch.End();

                // If the game is transitioning on or off, fade it out to black.
                if (TransitionPosition > 0 || pauseAlpha > 0)
                {
                    float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                    ScreenManager.FadeBackBufferToBlack(alpha);
                }

                base.Draw(gameTime);
            }

the HUD method
 private void DrawHud()
        {
            Rectangle titleSafeArea = ScreenManager.GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X + camera.Position.X, titleSafeArea.Y + camera.Position.Y);
            Vector2 center = new Vector2(titleSafeArea.Width + camera.Position.X  / 2.0f,
                                         titleSafeArea.Height + camera.Position.Y / 2.0f);

            // Draw time remaining. Uses modulo division to cause blinking when the
            // player is running out of time.
            string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00");
            Color timeColor;
            if (level.TimeRemaining > WarningTime ||
                level.ReachedExit ||
                (int)level.TimeRemaining.TotalSeconds % 2 == 0)
            {
                timeColor = Color.Yellow;
            }
            else
            {
                timeColor = Color.Red;
            }
            DrawShadowedString(hudFont, timeString, hudLocation, timeColor);

            // Draw score
            float timeHeight = hudFont.MeasureString(timeString).Y;
            DrawShadowedString(hudFont, "SCORE: " + level.Score.ToString(), hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);

        }
        //method which draws the score and the time (and is causing the problem)
        private void DrawShadowedString(SpriteFont font, string value, Vector2 position, Color color)
        {
            spriteBatch.DrawString(font, value, position + new Vector2(1.0f, 1.0f), Color.Black);
            spriteBatch.DrawString(font, value, position, color);
        }

I have recently integrated in a HUD method into my XNA game project and when the method is called by the main Draw method it throws out a object disposed exception this has something to do with the two Drawstring used in the program.

The exception is thrown at spriteBatch.End() and says Cannot access a disposed object.
Object name: 'Texture2D'.

      //initiation of the spritebatch 
     private SpriteBatch spriteBatch;

    //game draw method
    public override void Draw(GameTime gameTime)
            {
                ScreenManager.GraphicsDevice.Clear(Color.CornflowerBlue);

                // Our player and enemy are both actually just text strings.
                spriteBatch = ScreenManager.SpriteBatch;

                tileMap.Draw(spriteBatch, camera);

                spriteBatch.Begin(SpriteSortMode.Deferred,
                     BlendState.AlphaBlend,
                     null, null, null, null,
                     camera.TransformMatrix);

                DrawHud();

                level.Draw(gameTime, spriteBatch);

                spriteBatch.End();

                // If the game is transitioning on or off, fade it out to black.
                if (TransitionPosition > 0 || pauseAlpha > 0)
                {
                    float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                    ScreenManager.FadeBackBufferToBlack(alpha);
                }

                base.Draw(gameTime);
            }

the HUD method
 private void DrawHud()
        {
            Rectangle titleSafeArea = ScreenManager.GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X + camera.Position.X, titleSafeArea.Y + camera.Position.Y);
            Vector2 center = new Vector2(titleSafeArea.Width + camera.Position.X  / 2.0f,
                                         titleSafeArea.Height + camera.Position.Y / 2.0f);

            // Draw time remaining. Uses modulo division to cause blinking when the
            // player is running out of time.
            string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") + ":" + level.TimeRemaining.Seconds.ToString("00");
            Color timeColor;
            if (level.TimeRemaining > WarningTime ||
                level.ReachedExit ||
                (int)level.TimeRemaining.TotalSeconds % 2 == 0)
            {
                timeColor = Color.Yellow;
            }
            else
            {
                timeColor = Color.Red;
            }
            DrawShadowedString(hudFont, timeString, hudLocation, timeColor);

            // Draw score
            float timeHeight = hudFont.MeasureString(timeString).Y;
            DrawShadowedString(hudFont, "SCORE: " + level.Score.ToString(), hudLocation + new Vector2(0.0f, timeHeight * 1.2f), Color.Yellow);

        }
        //method which draws the score and the time (and is causing the problem)
        private void DrawShadowedString(SpriteFont font, string value, Vector2 position, Color color)
        {
            spriteBatch.DrawString(font, value, position + new Vector2(1.0f, 1.0f), Color.Black);
            spriteBatch.DrawString(font, value, position, color);
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

饭团 2024-10-17 09:22:53

正如例外情况所示,问题的存在是因为您正在使用的其中一个 Texture2D 在使用之前已被释放。

XNA API 中有两件事(我想到的)将处理 Texture2D:用于该内容管理器加载的任何纹理的 ContentManager.Unload() 方法,以及 Texture2D .Dispose() 方法。因此,请检查您自己的代码是否在任何时候调用这两个函数之一。

仅当“使用”Texture2D 实例时才会引发异常。因为 SpriteBatch 将纹理绘制一起批处理,所以在结束 SpriteBatch 之前,纹理实际上不会被使用(此时它会一次性绘制所有内容)。如果您更改为 SpriteSortMode.Immediate SpriteBatch 将停止批处理精灵,而是根据您的要求“立​​即”绘制它们。这将导致使用纹理并在 Draw 调用而不是 End 调用中引发异常,这应该可以更轻松地识别正在处置的纹理仍在使用期间。

您发布的代码似乎没问题,我怀疑问题存在于您的代码的其他地方。上述信息应该可以帮助您确定问题出在哪里。

As the exception says, the problem exists because one of the Texture2Ds you are using is being disposed before you are using it.

There are two things in the XNA API (that come to mind) that will dispose of a Texture2D: The ContentManager.Unload() method for any textures loaded by that content manager, and the Texture2D.Dispose() method. So check if your own code is calling one of these two functions at any point.

The exception will only be thrown when the Texture2D instance is "used". Because SpriteBatch batches together texture draws, the texture doesn't actually get used until you end the SpriteBatch (at which point it draws everything in one go). If you change to SpriteSortMode.Immediate SpriteBatch will stop batching sprites and will instead draw them "immediately" you ask it to. This will cause the texture to be used and the exception to be thrown at a Draw call instead of an End call, which should make it easier to identify which texture is being disposed of while still in use.

The code you have posted seems to be fine, I suspect the problem exists elsewhere in your code. The above information should help you identify where the problem is.

瞎闹 2024-10-17 09:22:53

我的猜测是 level.Draw 中正在发生一些事情,正在某处处理纹理。它看起来不像drawhud方法特别负责

你提到虽然你确定它是由drawstring方法引起的......如果你特别注释掉这两个方法,错误会消失吗?

My guess is that something is happening in level.Draw that is disposing of a texture somewhere. It doesn't look like the drawhud method in particular is responsible

You mention though that you are sure it's caused by the drawstring methods ... if you comment those two out in particular does the error go away?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文