MonoGame简介和环境搭建

MonoGame是一款开源、跨平台的C#游戏开发框架。不同于提供可视化界面和拖拽操作的完整游戏引擎,MonoGame是一个偏底层、精简、Code First风格的代码框架,相比重型游戏引擎,MonoGame能赋予我们更大的自由度和灵活性,它能让我们自底向上的构建整个游戏,这可能对于实现那些游戏玩法新颖特殊或机制较复杂的游戏更有利。实际上,许多知名的独立游戏就是使用MonoGame或类似框架开发的,例如《星露谷物语(Stardew Valley)》、《潜渊症(Barotrauma)》等。
MonoGame的前身是微软的XNA Framework,它的目标是让独立开发者能用C#语言为Windows和Xbox 360开发游戏,XNA的设计非常优雅,其中的Game类、Update和Draw循环、内容管线等概念一直沿用至今,可惜随着微软战略的重心转移,2013年前后XNA被微软抛弃,停止维护。不过虽然原版XNA被废弃,但社区随后发起了开源项目MonoGame、FNA等继承了XNA,我们这里主要介绍的MonoGame不仅适配了新版.NET,还将原本锁定在Windows生态的XNA扩展到了Windows、Linux、macOS、Android、iOS、主机等各种游戏硬件平台上。
本系列笔记将基于最新的MonoGame 3.8.5版本和.NET 8,对MonoGame的使用进行简单介绍。
开发环境搭建
使用Visual Studio
使用Visual Studio搭建MonoGame开发环境比较简单,首先我们得确保Visual Studio中安装了「.NET 桌面开发」相关组件,然后在扩展中搜索「MonoGame Framework C# project templates」并安装即可,这回为我们安装包含MonoGame项目模板在内及相关功能的VSIX插件。

安装完成后,在Visual Studio中新建项目时,我们就能看到MonoGame相关的项目模板了。对于Windows平台,我们这里可以选择「MonoGame Windows Desktop Application」或「MonoGame Cross-Platform OpenGL Desktop Application」,前者使用DirectX 11作为后端,最为成熟稳定但仅支持Windows,后者也相当成熟,但它是基于OpenGL的,可以跨平台到MacOS、Linux下运行。

随着技术的发展,MonoGame目前也在大力推进DirectX 12和Vulkan后端,安装项目模板后其实你已经能看到相关选项了,不过我们这里还是以最稳定的两个后端为例进行介绍。
使用dotnet命令行
如果你不喜欢Visual Studio,现在的.NET也完全可以脱离Visual Studio进行开发,这需要我们先在系统中手动安装.NET SDK(实际所需版本你需要查看当前MonoGame官方文档,我这里使用的3.8.5需要.NET 8),有关这部分可以参考软件工程/dotNet/Csharp语言基础相关章节,这里就不赘述了,安装完成后,我们可以使用以下命令检查是否安装成功。
dotnet --version
MonoGame的项目模板也通过NuGet分发,我们需要使用以下命令安装。
dotnet new install MonoGame.Templates.CSharp
安装完成后,我们可以用dotnet new list查看已安装的模板,其中应该能看到mgwindowsdx、mgdesktopgl等MonoGame系列模板。
除了项目模板,我们还需要安装MGCB Editor,MGCB(MonoGame Content Builder)是MonoGame的内容管道工具,它负责把图片、音频、字体等原始资源编译成游戏可高效加载的.xnb格式,MGCB Editor就是它的独立图形界面编辑器,它需要被作为dotnet全局工具安装。
dotnet tool install --global dotnet-mgcb-editor
安装完成后,命令行执行mgcb-editor即可打开编辑器界面,测试是否安装成功。
创建MonoGame工程
我们这里还是以Visual Studio为例进行介绍,使用「MonoGame Windows Desktop Application」选项新建MonoGame工程,执行后生成的目录结构如下。
Gacfox.Demo.DemoGame
|_ Content
|_ Content.mgcb # 内容管道配置文件,Visual Studio中双击打开编辑,命令行方式可手动启动MGCB Editor打开编辑
|_ Game1.cs # 游戏主类
|_ Program.cs # 程序入口
|_ app.manifest # Windows应用程序清单文件
|_ Gacfox.Demo.DemoGame.csproj # 项目描述文件
|_ Icon.ico # 程序图标
我们可以发现,MonoGame项目工程中没有Unity工程那种一大堆看不懂的文件夹,项目中核心代码文件就两个,我们逐个看。
Program.cs
using var game = new Gacfox.Demo.DemoGame.Game1();
game.Run();
Program.cs简单到令人感动,它实例化一个Game1对象,然后调用Run()启动游戏循环。这里使用了using声明语法,保证游戏退出时Game1占用的非托管资源(图形设备等)被正确释放。
Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Gacfox.Demo.DemoGame
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
Game1是游戏主类,我们后续章节介绍的内容都会从这里展开。代码中可以看到,Game1是一个派生自Game的类,驱动游戏循环是框架负责的,我们只需要重写几个生命周期方法,往里面填写游戏和绘制逻辑。其中,Update负责更新游戏逻辑,Draw负责绘制画面,两者每帧交替调用,这就是著名的「游戏循环」概念。GraphicsDeviceManager则用于管理图形设备(分辨率、全屏等),Content用于加载资源,SpriteBatch是2D图形绘制的工具类。
运行工程
对于Visual Studio工程,我们点击绿色三角运行即可,如果你使用命令行,则执行以下命令启动。
dotnet run

稍等片刻编译完成后,屏幕上会弹出一个窗口,里面是一片宁静的矢车菊蓝(Cornflower Blue #6495ED),这也是从XNA时代传承至今的祖传默认背景色,看到这个颜色,就说明你的MonoGame之旅已经正式开始了。