我独自开发一款视频游戏是出于业余爱好,并决定尝试一下 MonoGame。我是一个初学者,所以我的知识不是很丰富。目前一切工作正常,除了游戏在启动主菜单场景时创建了一个完全无用的窗口,并将死掉的介绍窗口留作剩余。这是不好的,尤其是当我的游戏不断发展并且我将拥有“数十个”场景时。我猜这个问题是由于 Run() 指令在调用时为 MainMenu 创建一个新实例引起的。我尝试了一些代码片段,但它们似乎根本不适用于我的代码/特定情况。我想要的只是游戏在切换到不同场景时保持单个窗口/实例。目前,我的游戏有 3 个文件:scenes.cs、intro.cs 和 mainmenu.cs。我将在这里上传它们的结构,以帮助您更好地理解我在说什么。 我非常感谢您的帮助,谢谢!
场景.CS:使用Microsoft.Xna.Framework; 使用 Microsoft.Xna.Framework.Graphics; 命名空间 MyGame
{
public class Scene : Game
{
protected GraphicsDeviceManager _graphics;
protected SpriteBatch _spriteBatch;
public Scene()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
_graphics.IsFullScreen = true;
_graphics.PreferredBackBufferWidth = 1366;
_graphics.PreferredBackBufferHeight = 768;
_graphics.PreferMultiSampling = false;
_graphics.ApplyChanges();
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
}
public void Switch(Scene scene)
{
Content.Unload();
Exit();
scene.Run();
}
}
}介绍.CS
: 使用 Microsoft.Xna.Framework;
使用 Microsoft.Xna.Framework.Graphics;
使用 Microsoft.Xna.Framework.Input;
命名空间 MyGame
{
public class Intro : Scene
{
// Constructor
public Intro()
{
}
protected override void Initialize()
{
// Initialization
}
protected override void LoadContent()
{
// Content load
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// Logo displaying logic
else if (_fadingComplete && _logoDisplayed)
{
Switch(new MainMenu()); // Here I call Switch to switch to the MainMenu scene
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
// Drawing logic
base.Draw(gameTime);
}
} }主菜单.CS
: 使用系统;
使用 System.Collections.Generic;
使用 Microsoft.Xna.Framework;
使用 Microsoft.Xna.Framework.Graphics;
使用 Microsoft.Xna.Framework.Input;
命名空间 MyGame
{
public class MainMenu : Scene
{
// Constructor and Initialization
protected override void LoadContent()
{
// Content loading
}
protected override void Update(GameTime gameTime)
{
// Update logic
}
protected override void Draw(GameTime gameTime)
{
// Draw logic
}
}
}
Game
作为应用程序本身以外的任何内容的基础。
Game
是一个提供给您继承的类,用于制作游戏本身,而不是游戏的各个部分。其中所有其他系统(渲染、输入、音频等)均已实现供您使用。因此,最好创建自己的场景系统并在派生的 Game 类中管理这些场景。 首先,定义基类来继承场景
public abstract class Scene
{
public abstract void Initialize();
public abstract void Update(GameTime gameTime);
public abstract void Draw(GameTime gameTime);
public abstract void Deinitialize();
}
然后实现你的场景
public class Intro : Scene
{
public override void Initialize() { /* Your stuff */ }
public override void Update(GameTime gameTime) { /* Your stuff */ }
public override void Draw(GameTime gameTime) { /* Your stuff */ }
public override void Deinitialize() { /* Your stuff */ }
}
public class MainMenu : Scene { /* Implement Stuff */ }
最后在中心位置管理场景。通常,我喜欢在
Game
和
Scene
之间再开一个类,但为了简单起见,我将它们直接放入 Game
中,以便给您一个想法。另外,为了演示,我将 MyGame 设为 Singleton,这在这里应该没问题,但不要仅仅因为它看起来方便而在任何地方使用它。
public class MyGame : Game
{
public static MyGame MyInstance { get; private set; }
private Scene currentScene;
private Dictionary<Type, Scene> scenes;
public MyGame()
{
Instance = this;
// And the other stuff happening here
}
protected override void Initialize()
{
scenes.Add(typeof(Intro), new Intro);
scenes.Add(typeof(MainMenu), new MainMenu);
SwitchScene<Intro>();
base.Initialize();
}
public void SwitchScene<T>() where T : Scene
{
currentScene?.Deinitialize();
scenes.TryGet(typeof(T), out currentScene);
currentScene?.Initialize();
}
protected override void Update(GameTime gameTime)
{
base.Update(gameTime);
currentScene?.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
currentScene?.Draw(gameTime);
}
}
如果你想在这种情况下切换场景,你可以像这样调用
SwitchScene
:
MyGame.MyInstance.SwitchScene<MainMenu>();