简介

FNA是微软的XNA的重新实现,其与MonoGame较为类似,基本代码可通用.但是FNA更多的精确地重新实现,所以可能与XNA兼容,但MonoGame则有所拓展,并非100%兼容.

相比MonoGame,FNA资料较少(中文则是更少了),这篇文章主要介绍是入门开发的拦路虎:环境搭建.

为什么选择XNA

如果你喜欢C#的接口、封装、抽象,不喜欢庞大的IDE,不喜欢庞大的引擎有一堆永远赘余的功能,如果你喜欢传统写代码方式自己控制流程而不是在引擎中写脚本来开发游戏,那么你可能会喜欢这个游戏框架。

我最大的感受是它在大包大揽的引擎和底层的API中达到一种平衡.你拥有很大程度的控制权,并且不必与底层系统纠缠。

下载

官方Github可以下载,这里下载FNA-2008,不要下载FNA-2009(新版本用到了FNA3D渲染,对应DLL需要自己编译我们暂时也用不到),下载并解压

下载2008版 同时下载一些依赖的本地库,比如SDL2,FAudio等等,目前下载地址在这里:http://fna.flibitijibibo.com/archive/fnalibs.tar.bz2 ,或者在官网的这里下载:

enter image description here

HelloWorld

准备好之后可以在Visual Studio 中新建一个控制台工程:

enter image description here

然后选择你的项目名字(比如HelloFNA),等待工程创建完成,再选择解决方案->添加->现有项目

enter image description here

选择之前解压的FNA.csproj工程,之后的项目结构如下

enter image description here

之后在HelloFNA项目中引用FNA项目:

enter image description here

选择FNA项目点确定

enter image description here

然后再HelloFNA的项目下新建一个类:

enter image description here

再取个名字,比如AwasomeGame,然后这个类继承自Microsoft.Xna.Framework.Game:

using Microsoft.Xna.Framework;

namespace HelloFNA
{
    class AwasomeGame : Game
    {
        private GraphicsDeviceManager graphicsMgr;
        public AwasomeGame()
        {
            graphicsMgr = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
    }
}

之后在Program.cs中调用如下代码:

namespace HelloFNA
{
    class Program
    {
        static void Main(string[] args)
        {
            var game = new AwasomeGame();
            game.Run();
        }
    }
}

然后按下F5运行,不出意料你会遇到如下错误

enter image description here

该提示为没有找到本地库(dll文件),所以需要在项目的输出文件(HelloFNA/bin/Debug)中把之前下载的本地库拷贝进去,选择x86文件夹下的全部dll文件(不要拷贝文件夹,只拷贝文件),拷贝到Debug文件夹

enter image description here

此时再运行就能看到窗口了!

enter image description here

加载和显示图片

只显示一个窗口很无聊,下面的代码将会显示一张图片.假设我们要显示这么一张图片(来源自:https://kenney.nl/assets/animal-pac):

enter image description here

我们先在项目中新建一个Content文件夹,并把这个图片放进

enter image description here

然后在Visual Studio中当前项目中新建文件夹->添加项->选择全部文件->选择图片,这里注意文件格式要选择所有文件 enter image description here

下面是最重要也是一开始最容易忽略的一点,我们要在工程中设置图片属性为复制到输出目录,点击图片右键选择属性

enter image description here

在XNA中的Game类中有几个方法需要注意

  • LoadContent:加载资源
  • Initialize:初始化
  • Update:更新逻辑
  • Draw:游戏的绘制

所以我们想要显示图片,第一件事就是加载图片,然后再Draw方法里面绘制出来即可。这里绘制图片需要有一个SpriteBatch对象,所以接着在AwasomeGame.cs中声明Texture2D对象和SpriteBatch对象

private Texture2D texture2D;
private SpriteBatch spriteBatch;

之后所需要的的就是加载,初始化和绘制的逻辑

protected override void Initialize()
{
    base.Initialize();
    spriteBatch = new SpriteBatch(GraphicsDevice);
}

protected override void LoadContent()
{
    base.LoadContent();
    texture2D = Content.Load<Texture2D>("penguin");
}

protected override void Draw(GameTime gameTime)
{
    base.Draw(gameTime);
    spriteBatch.Begin();
    Vector2 screenPos = new Vector2(0, 0);
    spriteBatch.Draw(texture2D, screenPos, Color.White);
    spriteBatch.End();
}

这个时候按下F5运行即可看到我们的图片显示出来了。

enter image description here

如果你对MonoGame有所了解可能会了解MGCB软件,使用这个软件可以将资源导出给MonoGame使用,同时FNA也可以使用。一般比较简单的资源是不需要使用这个软件导出给FNA使用(一般也不推荐用,感觉多了一个步骤,本来修改导出就很简单),只要你遇到比较复杂比如SpriteFont3d模型时候可能需要,不然一般自己读取即可。

至此这篇文章的任务就达成了,我们搭建成了FNA的环境,有了这个基础,你可以继续看其他XNA/Monogame/FNA书籍教程来学习并继续探索。

对第三方库保持谨慎态度

在XNA也有一些框架可供使用,比如NEZMonoGameExtend,但是我个人并不推荐在你不熟悉的时候就拿这些框架来用。

我比较喜欢的方式是先看代码,觉得合适的再把那一部分过来(有些时候只需要精简版)。在符合自己需求下用代码会比较符合代码复用。你会发现这些框架很多互相借鉴。

代码复用应该尽量保持代码量小而精,一下子加一堆可能永远也用不上的代码也没什么用处。

最后,希望本文对你有帮助,也希望你能享受写代码做游戏的乐趣。

Sadi

2020年9月25日

参考

AwasomeMonogame

2D Graphics Programming for Games

FNA From Scratch