-1

我正在尝试创建一个可以一次打开和关闭多个屏幕的 screenManager。我已绑定 P 键以在按下时打开一个名为 Pause 的屏幕。但是,在调试语句中,我可以看到屏幕正在创建并通过按 P 键多次打开。我可以通过在创建/将其添加到屏幕列表之前检查屏幕变量是否为空来停止此操作。但是,当我试图处理它时,我得到了一个 StackOverflow 异常。她是我的代码:

Pause.cs- 如果我不在这里调用 Dispose(),我将无法在 MainMenu 中重新打开屏幕,因为 Pause 不再为空。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace RoomGame
{
    public class Screen : IDisposable
    {
        public ScreenController screenController;
        public bool isUpdating=true;
        public bool isDrawn=true;
        public GraphicsDeviceManager graphics;

        /*public Screen(ScreenController sc)
        {
            this.screenController = sc;
            this.isActive = true;
        }*/

        public virtual void Initialize()
        { }

        public virtual void LoadContent(ContentManager c)
        { }


        public virtual void Update(GameTime gameTime)
        { }

        public virtual void Draw(GameTime gameTime,SpriteBatch sb)
        { }

        public void Dispose()
        {
            this.Dispose();
        }
    }
}

Screen.cs - StackOverflow 异常发生在 Dispose here

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace RoomGame
{
    public class Screen : IDisposable
    {
        public ScreenController screenController;
        public bool isUpdating=true;
        public bool isDrawn=true;
        public GraphicsDeviceManager graphics;

        /*public Screen(ScreenController sc)
        {
            this.screenController = sc;
            this.isActive = true;
        }*/

        public virtual void Initialize()
        { }

        public virtual void LoadContent(ContentManager c)
        { }


        public virtual void Update(GameTime gameTime)
        { }

        public virtual void Draw(GameTime gameTime,SpriteBatch sb)
        { }

        public void Dispose()
        {
            this.Dispose();
        }
    }
}

MainMenu.cs - 这是创建暂停屏幕的类

using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

namespace RoomGame
{
    public class MainMenu : Screen
    {
        GameController gameController;
        ScreenController screenController;
        MyTexture start;
        Rectangle area;
        Vector2 position;
        ContentManager content;
        Screen pause = null;
        //public GraphicsDeviceManager graphics;

        public MainMenu(GameController gc)
        {
            this.gameController = gc;
            gameController.Game.IsMouseVisible = true;
            //this.content = c;
            this.isUpdating = true;
            this.isDrawn = true;

            //this.graphics = this.gameController.game.graphics;
        }

        public override void LoadContent(ContentManager c)
        {

            position = new Vector2(100, 100);
            start = new MyTexture("Textures/Start",position,c);


            //texture = this.gameController.game.Content.Load<Texture2D>("Textures/Start");
            //texture=this.gameController.content.Load<Texture2D>("Textures/Start");
            //texture = this.gameController.Game.Content.Load<Texture2D>("Textures/Start");
        }


        public override void Update(GameTime gameTime)
        {
            //texture = this.gameController.content.Load<Texture2D>("Textures/Start");

            area = start.getBounds();

            MouseState mouse = Mouse.GetState();
            if ((mouse.LeftButton == ButtonState.Pressed) &&
            (area.Contains(mouse.X, mouse.Y)))
            {
                gameController.Game.Exit();
            }

            KeyboardState key = Keyboard.GetState();
            if (key.IsKeyDown(Keys.P))
            {
                if (pause == null)
                {
                    pause = new Pause(this.gameController);
                    gameController.screenController.AddScreen(pause);
                }
            }

        }

        public override void Draw(GameTime gameTime,SpriteBatch sb)
        {
            start.Draw(sb);
        }
    }
}

编辑:我的错误。调试状态位于错误的位置,因此当它显示多个添加时,List.Contains 语句阻止它实际发生。

4

1 回答 1

1

为确保与按键相关的代码只执行一次,请存储上一帧的 KeyboardState 并像这样检查它:

public override void Update(GameTime gameTime)
{
    //everything else goes here

    if (key.IsKeyDown(Keys.P) && oldState.IsKeyUp(Keys.P))
    {
        //create a screen
    }

    oldState = key;
}
于 2013-11-15T11:59:02.740 回答