特集:C#開発者向けゲーム開発フレームワーク「MonoGame」
C#とMonoGameで作るWindowsストア・アプリ向けゲーム
アクション性の高いゲームをC#で開発する際には「MonoGame」が使える。その概要を紹介し、実際のサンプル開発を通して、その基本機能を説明する。
Windowsストア・アプリ向けにアクション性の高いゲームをC#で開発する際には、Windowsランタイム(WinRT)の標準機能では力不足だ。その力不足を補うのに使えるフレームワークの1つに「MonoGame」がある。
本稿ではこのMonoGameの概要を紹介し、実際のサンプル開発を通して、その基本機能を説明する。
本題に入る前に、まずはWindowsストア・アプリの基盤となっている「Windowsランタイム」の概要について、また、それとゲーム開発の関係について簡単にまとめる。
Windowsストア・アプリとゲーム開発
Windows 8の新しいUI(ユーザー・インターエイス)で動作するWindowsストア・アプリの開発には、Windowsのコンポーネント技術の中核となっているCOMを拡張した新しいフレームワーク「Windowsランタイム(WinRT)」のAPIを用いる。
Windowsランタイム自身は、.NET FrameworkのCLR(共通言語ランタイム)のようにWin32 API上に構築されたランタイムの上で動作するのではなく、C++で開発されたアプリと同じようにWindowsネイティブで動作する。しかも、ネイティブでありながら、アプリケーション・プラットフォームやプログラミング言語には依存しない。例えばWindowsランタイム上に構築できるWindowsストア・アプリでは、XAML+.NET言語(C#/Visual Basic )や、HTML+JavaScriptでも開発できるのだ。次の図は、Windowsランタイムとプログラミング言語の関係を表した図である。
ところが、Windowsストア・アプリで利用可能な一部の機能はWindowsランタイム化されていない。そのため、非ネイティブである.NET FrameworkやWebブラウザーからはアクセスできない機能が残されている。その代表的な機能が、DirectXによるリアルタイムのレンダリング、低水準なマルチメディア処理、Windows Imaging Componentによる画像処理などである。これらの機能はCOMを直接扱わなければならないため、C++言語によるプログラムから利用するか、一度、C++でラッパーを作成しなければならない。
このため、C#でアクション性の高いゲームを開発するのは極めて困難であり、現時点において、標準のフレームワークの範囲内で高度な描画処理が求められるゲームをWindowsストア・アプリとして開発するには、C++言語とDirectXの組み合わせ以外に選択肢はない。C#で開発する場合はXAMLを駆使して表現する必要があるが、現実的な開発方法ではないだろう。
デスクトップ・アプリ分野においても、C#はマルチメディアやゲーム開発を得意としていないが、それでもWPFではDrawingContextクラス(System.Windows.Media名前空間)による直接描画や、3Dグラフィックスを扱う機能が提供されていた。WindowsランタイムのXAMLには、このような機能も削られているため、描画機能が極めて乏しくなっている。
C#とXNA Framework
これまで、WindowsデスクトップやWindows Phone、Xbox 360向けにC#でゲームを開発するには、XNA Frameworkが用いられていた。XNA Frameworkはマイクロソフトが公式に提供しているゲーム開発用のフレームワークで、描画やオーディオ処理に加え、ゲーマー・サービスや通信、コンテンツ管理など、ゲーム開発に必要となる機能を含んでいる。XNA Frameworkを基盤にした場合のゲーム・アプリ構成をまとめたのが次の図である。
XNA Frameworkは、C#でゲームを開発するに当たって、非常に優秀で使いやすいフレームワークだが、マイクロソフトはXNA Frameworkの開発を終了し、今後、アップデートしない方針を明らかにしている。残念だが、XNA FrameworkはWindowsストア・アプリに対応しておらず、今後も対応する可能性は極めて低いだろう。
MonoGame
そういった経緯から、C#を用いて高度な描画処理を行うWindowsストア・アプリを開発するには、オープンソースで開発されているXNA Framework互換環境の「MonoGame」がお勧めだ。
MonoGameは、同じくオープンソースで開発されている.NET Framework互換環境のMonoをベースとしているため、Windowsに限らず、多様な環境で動作するゲームをクロスプラットフォームで開発できることが特徴だ。
マイクロソフトが提供するXNA FrameworkはWindowsデスクトップ、Windows Phone、そしてXbox 360しか対応していなかったが、MonoGameは対応プラットフォームを拡大し、iOS、Android、Mac OS X、Linux、そしてWindowsストア・アプリなど、多くの環境に対応している。コードの大部分を変更することなく、多様な環境で動くゲームを実装できる。
MonoGameは無償でダウンロードして利用できるが、iOSとAndroidの開発にはXamarinのライセンスが必要となる。
Windowsストア・アプリの開発であれば特に制限はなく、MonoGameをインストールすると、Visual Studio(2012もしくは2010)のプロジェクト・テンプレートに「MonoGame」という項目が追加され、この中の「MonoGame Windows Store Project」テンプレートからアプリ開発を始められる(次の画面を参照)。もちろん、無償のVisual Studio Express 2012 for Windows 8にも対応している。
MonoGameはXNA Frameworkのコードをほとんど変更することなく移行できる。ただし、ストレージや通信など、セキュリティやシステム依存が強い部分は調整が必要になる。また、スナップ表示やチャームなど、Windows 8固有の機能に対応するにはコードを追加しなければならない。
コンテンツの読み込み
XNA Frameworkでは、ゲームで読み込まれるテクスチャやフォントなどを事前コンパイルする「コンテンツ・パイプライン」と呼ばれる仕組みがある。このコンテンツ処理用のプロジェクトはゲーム用のプロジェクトとは別に作成しなければならない。
Windowsストア・アプリのプロジェクトでコンテンツ・パイプラインを利用するには、事前にコンテンツ用の「MonoGame Content Project」テンプレート(次の画面を参照)から新規プロジェクトを作成して、コンテンツをビルドしておく必要がある。
このコンテンツ用プロジェクトは、XNA Game Studioの機能を使っているため、本家のXNA Game StudioがVisual Studio 2012(=最新バージョン)に対応していないことから、Visual Studio 2012で作成すると警告が発生する。従って、コンテンツ用のプロジェクトにはVisual Studio 2010(=1つ前のバージョン)が推奨されている。 そのためVisual Studio 2010環境が手元にあれば、その環境に切り替えてコンテンツ・プロジェクトを作成してほしい。
アセットの作成
実際に「MonoGame Content Project」プロジェクトを作成すると、[ソリューション エクスプローラー]内に、ビルド用のダミー・プロジェクトと、コンテンツ登録用のプロジェクトの、2つのプロジェクトが生成される。プロジェクト名の末尾が「Content」で終わっているプロジェクトが、コンテンツ登録用のプロジェクトだ。
コンテンツ登録用のプロジェクトに、.pngファイルなどのコンテンツ(=ビルドされる元ファイル)を追加し、そのファイルを選択した状態で[プロパティ]ウィンドウから任意のアセット名と処理方法を指定する。このように設定するのは、ゲーム側でコンテンツを読み込むときは、ファイル名ではなくアセット名で読み込むためだ。
登録したコンテンツは、ビルド時にコンテンツ・パイプラインによって事前処理され、結果がアセット・ファイルとして出力される。事前ビルドによって、オブジェクトとして直接読み込める形式にシリアライズし、ゲーム実行時の読み込みを効率化する仕組みだ。
次の画面は、生成された2つのプロジェクトの表示例と、[プロパティ]ウィンドウでのアセット関連の指定例を示している。
そして、プロジェクトの構成でビルド対象のプラットフォームを選択して(Windowsストア・アプリの場合は「Windows8」)、ビルドを実行する。ただし、前述したように、このプロジェクトは事前ビルド用のダミーなので、実行することはできない。
ビルドが成功すると、次の画面例のように、プロジェクトの「bin\Windows8\Content」フォルダ内に「アセット名.xnb」というファイルが作成されている。
アセットの読み込み
これを(コンテンツ・プロジェクト用のVisual Studio 2010の環境から切り替えて)Visual Studio 2012のゲーム・プロジェクトに追加する。追加した.xnbファイルの[ビルド アクション]プロパティを「コンテンツ」に、[出力ディレクトリにコピー]プロパティを「新しい場合はコピーする」に変更することで(次の画面はその実施例)、ContentManagerオブジェクト(Microsoft.Xna.Framework.Content名前空間)から読み込めるようになる。
これで、ビルドしたアセットをContentManagerオブジェクト(=Gameクラス(Microsoft.Xna.Framework名前空間)のContentプロパティから取得できる)のLoadメソッドから読み込める(次のコードを参照)。この仕組みによって、元のファイル形式を気にすることなく、ゲーム側ではオブジェクトとしてデータを受け取れる。
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace GameName1
{
public class Game1 : Game
{
GraphicsDeviceManager _graphics;
SpriteBatch _spriteBatch;
Texture2D _texture;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
_texture = Content.Load<Texture2D>("sample");
}
protected override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
_spriteBatch.Begin();
_spriteBatch.Draw(_texture, Vector2.Zero, Color.White);
_spriteBatch.End();
base.Draw(gameTime);
}
}
}
|
コード1は前述したアセットを読み込み、画面に描画する単純なプログラムだ。XNA Frameworkの経験者ならば、XNA Game Studioで開発する場合と変わらないことが確認できる。
このように、C#でWindowsストア・アプリ向けにゲームを開発するなら、MonoGameを用いた方が、自由で制約のない描画が可能だ。それだけではなくXAMLとの相互運用も可能なので、ゲーム場面を描画しつつ、UIはXAMLで記述できる。
■
WindowsでゲームといえばC++とDirectXの印象が強いが、C#開発者も、ぜひMonoGameでWindowsストア・アプリ対応のゲーム開発に挑戦していただきたい。