XNA

XNAベースのゲームをAndroidに移植する方法(その4)

前回からの続き。

ちょっとツールの話。Mono for AndroidにはMonoDevelopという開発環境が付属していて、これでLinuxやAndroid用のアプリケーションをC#で開発できる。使い勝手もVisualStudioとあまり変わらないので、非常に使えるツールである。MonoDevelopでも当然ExEnを用いたゲームをビルドしてデバッグできる。デバッグ機能も豊富だ。しかし、MonoDevelopでは、XNAプロジェクトが開けない。この移植作業では、既存のXNAプロジェクトのソース修正がメインになるので、これは非常に不便である。VisualStudioでXNAプロジェクトを開いてソース修正&ビルドを行ってMonoDevelopで配置&デバッグ実行うか、VisualStudioだけですべての作業を行うか、の選択となる。VisualStudioだけですべて行う方が作業が美しいと思うので、ここではそうした。

VisualStudioだけでMono for Androidプロジェクトをデバッグする際の注意点として、既定の設定では、BlankGameプロジェクトが依存している既存の自作XNAゲームプロジェクトのソースを更新しても、デバッグ実行時に、その変更が反映されない。これでは、移植作業が進められないので、BlankGameプロジェクトのプロパティを開き[Mono Android Options]タブの[Use Fast Deployment (debug mode only)]のチェックを外す。こうすることで、既存の自作ゲームのexeが更新されても、デバッグ実行時にその変更が反映されるようになる。

なお、VisualStudioでもMonoDevelopでも、例外が発生した箇所でブレークし、その時点の変数の値やコールスタックなどを確認することができ、とても便利だ。Visual StudioでWindows Mobileのプログラムを実機でデバッグするのと同じ感覚で、ARMデバイスをICEでつないでRealViewでデバッグするのと同じ感覚でデバッグできる。いとも簡単に。

それから、自作ゲームのソース中に

    System.Diagnostics.Debug.WriteLine("Hello...");   
のように出力しておくと、(エミュレータでの)デバッグ実行時に、VisualStudioの[出力]ウィンドウに、出力した文字列が表示され、デバッグの役に立つ。MonoDevelopでも出力は表示できるが、Android自身のログ、Mono for Androidのログ、ExEnのログと混ざって出力される。VisualStudioではメニューの[表示]-[その他のウィンドウ]-[Android Device Logging]を表示することで、Android自身のログなどを参照できる。

さて、いよいよAndroidエミュレータ上でゲームを実行してみる。…動かない。起動してもすぐに終わってしまう。なんかgraphics.ApplyChanges()でNullReferenceExceptionみたいなの出るし。Androidでは要らないのだろう。ExEnのサンプルソースにもこの処理なかったし。そんな感じで、実行時エラーが出る個所をちょこちょこ直していく。そうそう、画面の解像度が異なるから、デバイスに合わせて変えないといけない。場合によっては背景画像などのコンテンツも修正が要るだろう。これは仕方のないことだ。

それから、pngファイルをLoad()するときにjava.lnag.OutOfMemoryError(だったか?)が出た。Android端末だから搭載メモリが少ないのは仕方ない…が、これは少なすぎだろう、という感じだったので、AVDマネージャーで仮想Androidマシンのheapsizeを24から256まで増やした。とりあえず移植できるかの検証が目的なので、今はこれで対処しておく。(仮想Androidマシンのheapsizeをそれ以上にすると、仮想マシンが起動中に停止し、起動できないっぽい。。。)ところがところが、これでもゲームの全コンテンツをLoadすることはできなかった。う~むパソコン向けゲームとは違って、画像や音声の容量をできるだけ節約する必要がありそうだ。とりあえずいまは、余計なアニメーションを省いて、テクスチャを減らして対処しておく。

あと、ソース中で指定しているコンテンツのアセット名とファイル名の大文字小文字が合っておらず、コンテンツのLoad()が例外になった場合、VisualStudio上でコンテンツのファイル名を変更しただけでは、変更がapkファイルに反映されないっぽい。そういう場合は、コンテンツファイルのプロパティで[ビルドアクション]を[なし]にしてBlankGameをリビルドしてから[ビルドアクション]を[Android Asset]にして再度リビルドすると、反映される。

さて、最初からここまでで、結構、自作ゲームのソースをいじった。Mono for Androidプロジェクトには、プロジェクトのプロパティの[ビルド]タブを見るとわかるのだが、"ANDROID"という条件付きコンパイルシンボル(いわゆる#define値)が定義されているので、Android専用のコードは#ifdef ANDROIDと#endifでくくっておけばよかった。そうすることで、パソコン用とAndroid用のソースを一本化できる。

さて、デバッグ実行。ゲームがAndroidエミュレータで起動し、グラフィックやBGMが流れた!!う~むすばらしい。

しかし、実行してみるとまだまだ問題が発生。

  • まず、めちゃくちゃ重い(エミュレータだから?)
  • キーボードの押下が検出できない
  • 独自のファイル(設定ファイル)が読み込めない(見つからないエラーになる)
  • mp3が2曲つながって再生される。
  • フォントが表示できない(Loadで例外になる)

これらの対処法はまた次回。。。

| | コメント (0) | トラックバック (0)

XNAベースのゲームをAndroidに移植する方法(その3)

前回からの続き。

いよいよAndroid版のビルドである。Visual Studioでソリューションをリビルドする。しかしここで、いろんなコンパイルエラーが発生した。ExEnはXNAのすべてをサポートしているわけではないので、使えないAPIもあるのだろう。エラーになる個所はAndroid版では不要になる個所だったので全てコメントアウト等した。またBlankGameプロジェクトから自作ゲームのアセンブリを参照する必要もあるのでそれを追加した。そしてようやく、ビルドが通った。BlankGameプロジェクトのbin\Android\Releaseフォルダに必要なファイルができている。ただ、ここまでは純粋に.NETでの作業である。ビルドで生成されたのは.NETのアセンブリに過ぎない。Androidで実行するには生成したファイルのapkファイル化が必要だ。これはどうやるのか。。。

ビルドしたアセンブリをapkにパッケージ化するのは、Mono for Androidの機能だ。今は評価版なのでDebug版でAndroidエミュレータへの配置しかできない。とりあえずBlankGame含め、自作ゲームのプロジェクトをDebug版にしてビルドする。そしてVisual StudioのソリューションエクスプローラーでBlankGameプロジェクトを右クリックし[配置]を実行すると、Androidの仮想デバイスを選択するウィンドウが出てくる。(仮想デバイスは、Android SDKのAVD Managerというツールで事前に作成しておかなければならない。Android SDK関連のツールの使い方は、豊富な資料がネット上にあるので見てほしい。)配置先仮想デバイスを選択すると、BlankGameプロジェクトのbin\Android\Debugフォルダにapkファイルが生成され、Androidエミュレータ(仮想デバイス)に自作ゲームが配置される。

Visual Studioで[デバッグ開始](F5)を押すだけで、自動的にビルド&apkパッケージ化&配置&エミュレータでの実行ができる。すごいぞMono for Android!

しかししかし!結論から言うと、ここから、結構ソースを修正しないとゲームは動かないのであった。。。続きは次回。。。

| | コメント (0) | トラックバック (0)

XNAベースのゲームをAndroidに移植する方法(その2)

XNAベースのゲームをAndroidに移植した時に実施した手順は以下の通り。

まずExEnを動かすために必須のMono for Android(フリー版)をダウンロードしてインストールする。Android SDKも必要だった気がする。

その後、ExEnに同梱のドキュメント(Porting Check List)を見ながらやるも、その通りできない。そもそもiPhoneやSilverlightへの移植方法になってるし。。。ExEn関連の資料少なすぎ。。。(;´д`)トホホ…

そこで、Mono for Androidの仕組みから、こうなるはずだという想定で作業していくことにした。まず、ExEn同梱の"BlankGame Android.csproj"というプロジェクトをベースにする。ちなみにMonoTouchはiPhone用なのでだまされないように。

BlankGameプロジェクトを使って、デフォルトのActivityから自分のゲームのエントリ(Game1クラス)を呼び出すようにする必要があるはず。さらに、自作ゲームは本物の(Microsoft製の)XNAアセンブリを参照しているので、ExEnのアセンブリ(XNAの代わりになるもの)を参照する必要があるはず。

<作業内容>

"BlankGame Android.csproj"のファイル名は適切なものに変えておき(BlankGameのままでも良いので、ここではそのままにする)、csprojファイルをテキストエディタで開いて(1)RootNamespaceを自作ゲームに合わせて変更、(2)AssemblyNameも適切なものに変更、(3)ProjectGuidは後でVisualStudioが自動生成してくれるので削除しておく。

VisualStudioのソリューションエクスプローラーで自作ゲームのソリューションを右クリックして[追加]-[既存のプロジェクト]からExEnのBlankGameプロジェクトを追加する。BlankGameの"Android Activity.cs"ソースを開き、名前空間を自作ゲームの名前空間に変え、

game = new BlankGameGame();

の行を、自作ゲームのエントリ(Game1など)をnewするように変更する。BlankGameGameクラスは不要なので、BlankGame.csはプロジェクトから削除しても良い。BlankGameプロジェクトをスタートアッププロジェクトにする。

VisualStudioのソリューションエクスプローラーで、自作ゲームのXNAプロジェクトの参照アセンブリ一覧から、XNA関連(本物のMicrosoft製XNAアセンブリ)の参照をすべて参照解除する。そして、ExEnのアセンブリ(ExEnCoreとExEnAndroid)を参照に追加する。あ、これをするために、事前に、自作ゲームのソリューションにExEnのExEnAndoird、ExEnCore、ExEnCommonの3プロジェクトを追加してそれぞれをビルドしdllを生成しておく。(プロジェクト参照でもいいだろう)

さて、コンテンツも移植しないといけない。まず、ExEn(Android)でサポートされていない形式のファイルがあれば、サポートされているものに変更しなければならない。(wma→mp3など)。mp3やwav、pngなどはサポートされているのであまり問題にはならないだろう。そして、コンテンツフォルダ自体をBlankGameプロジェクト直下にコピーし、コピーしたContentフォルダをBlankGameプロジェクトに追加する。XNAプロジェクトでは、デフォルトで、Game1のコンストラクタでContentRootを"Content"というフォルダ名にしているので、ContentフォルダをBlankGame直下に置くのだ。ContentRoot名を変えている場合はそれに合わせる。

さらに、全てのコンテンツファイルのプロパティで[ビルドアクション]を[Android Asset]にする。これはとってもメンドクサイのであるが、しとかないとLoadできないので、やっておく。

(ExEnの作者は、将来、ここまでの作業を自動的に行えるようにするつもりのようだ。ぜひ、そうしてほしい。)

コンテンツに関してもう一つ重要なことは、ゲームのソースコードでLoad時に指定しているアセット名と、コンテンツのファイル名を厳密に一致させておく必要があるってことだ。Windowsでは、Game.Content.Load()に指定するassetNameとコンテンツファイルのプロパティで指定したAssetNameの大文字小文字は区別されない。しかしAndroidはLinuxベースのためか、大文字小文字が区別されるので、ファイル名とアセット名の大文字小文字があっていないと、Loadでファイルが見つからないという例外となる。これを合わせていくのも一苦労なのだが、仕方ないのでやる。

続きは次回...

| | コメント (0) | トラックバック (0)

XNAベースのゲームをAndroidに移植する方法

XNAベースのゲームをAndroidに移植してみた。というと、「メンドクサイことをしたな」と思うかもしれない。何しろXNAといえば.NET Framework上でDirectXを使うフレームワークなので、C#で書かれたWindows(もしくはWindows PhoneやXBox360)用のプログラムである。AndroidといえばLinuxベースのOSであり、アプリケーションはDalvikというVM上で動作するものをJavaで記述する。OSも違えば言語も違うので、移植するとしたらプログラムを全面的に書き換えないといけない。

しかし!C#で書いたXNAベースのプログラムをほぼそのままAndroidで動かす方法が存在するのだ。それは、ExEnを使う方法である。ExEnは、Mono for Android(以下、MfAという)上で動作するXNA Framework APIサブセットの実装だ。

Monoとは、オープンソースの.NET Framework実装であり、Linuxやその他OSで動作する。MonoのAndroid版がMfAである。MfAは有償製品で、Androidエミュレータ上でのデバッグ実行だけならフリー(の評価版)でできる。

今回、自作のXNAベースのゲームをExEnのフリー版を使ってAndroidのエミュレータ上で動作させてみたので、その方法を記録しておく。

具体的方法は次回...

| | コメント (0) | トラックバック (0)

XNA Game Studio 4.0のインストール

もう3年ほど前に作りかけたゲームを完成させようと思い立った。当時はVisual Studio 2008 + XNA Game Studio 3.0 だったが、今はVisual Studio 2010の時代。2010で続きを作ろうと思いきや、C#のプロジェクトが変換エラーになり、開発ができない。う~ん、ただのC#プロジェクトなのに。。。いや、そういや、思い出してきた。XNA専用のプロジェクトだった気がする。Visual Studio 2010用XNA Game Studioをインストールしないといけないんだな、と気づく。

さっそくマイクロソフト社のサイトで調べてみると、4.0がリリースされており、それがVisual Studio 2010に対応しているとのこと。さらにWindows Phone 7にも対応済み。XNA 3.x時代はWindows Mobileに対応してなかったからなぁ。すばらしいじゃないか。

…ところが、ところがである。ダウンロードページでいくら検索しても「XNA Game Studio 4.0」が無いではないか!日本語パックはあるのに…。いったい、何の仕打ちかと。何か悪いことをした罰なのか。

だがしかし。そうではなかった。実はXNA Game Studio 4.0は単体でリリースされているのではなく、Windows Phone Developer Toolsに含まれる形でリリースされているのでした。今やWindows Phoneがメインということか。(Windows XPの人用にXNA Game Studio 4.0単体インストーラはあるものの、ダウンロードサイトでは検索されない。)

さっそくWindows Phone Developer Toolsをダウンロードし、インストーラを実行。しかし、これがエラーとなる。"vm_web.exe"を実行すると、「compatibility modeでは実行できないッスわ」的な英語のメッセージが出る。exeファイルのプロパティを見ると、なぜかWindows Vistaモードの互換性モード固定になっていた。なんでダウンロードしたファイルが勝手に互換性モードになってんの。やはり何かの罰なのか。exeファイルのプロパティの[互換性]タブの[すべてのユーザーの設定を変更]ボタンをクリックし、[互換モードでこのプログラムを実行する]のチェックをはずして、解決!

| | コメント (0) | トラックバック (0)