Twitter @HigenekoTwitter #XNA
Shawn Hargreaves氏のブログから拝借+ちょっと補足説明
XNA Game Studio 2.0になって追加、または修正された細かな機能を紹介します。
GamePadState.IsButtonDownとIsButtonUpメソッドの追加
今まではコントローラーのボタンが押されているかの判定はButtons.A == ButtonState.Pressedと言う様に長いコードを書かなければいけませんでした。特に複数のボタンのいずれかが押されているケースを判定するのには以下のようなコードになってしまいました。
// AボタンもBボタンもXボタンも全部ジャンプだ!! if (padState.Buttons.A == ButtonState.Pressed || padState.Buttons.B == ButtonState.Pressed || padState.Buttons.X == ButtonState.Pressed ) Jump();
XNA GS 2.0で追加されたIsButtonDownとIsButtonUpメソッドを使うことによって以下のようにスッキリとしたコードを書くことができます。
if ( padState.IsButtonDown(Buttons.A|Buttons.B|Buttons.X) ) Jump();
Keyboard.GetState(PlayeIndex player)オーバーロードの追加
このオーバーロードメソッドを使うことで、Xbox 360コントローラーにつけることのできるチャットパッドからの入力を取得することができます。以前の引数なしのメソッドを呼んだ場合はPlayerIndex.Oneを指定するのと同じ動作をします。
Audio.Cueの再生が途切れてしまう問題の解消
これは、1.0では参照されていないCueのインスタンスがガーベージコレクションが発生した場合、音声の再生の途中に関わらずに破棄されてしまい、その段階で音声が途切れてしまうという不具合がありました。、2.0ではCue.Finalizer内で音声再生中はインスタンスが破棄されないようにすることで解決しています。
この問題は特に3Dオーディオを再生する場合、Cueに対してリスナーとエミッターを関連付けるときに
Cue cue = soundBank.GetCue("fire"); cue.Apply3D( listener, emitter );
のようなコードを書く必要があり、このcueのインスタンスを保持するというのが面倒な作業になっていました。
2.0ではこの問題を解決し、上のように書いた場合でも問題なく動作するようになりました。また、SoundBank.PlayCue(string name, Listener listner, Emitter emitter)メソッドが追加されたので、簡単に3Dオーディオをサポートした効果音を再生することができます。
フレームワーク内での不要なメモリ確保の削除
不要なメモリ確保をすることはガーベージコレクションの頻繁な発生につながり、結果的にパフォーマンス低下に繋がります。特に世代別GCを実装していないXbox 360上では大きな問題になります。
2.0ではフレームワーク内で不必要なメモリ確保している部分の修正をしました。
簡単なところではGamePad.GetState、SpriteBatch.DrawStringメソッド内でメモリ確保しないようになりました。SpriteBatch.DrawString内では、Dictionary<K,T>を使って実装していたのですが、キーがバリュータイプだと不要なメモリ確保がXbox 360上で発生することがありました。興味深いのはデバッガ使用時と、未使用時でJITが生成するコードに違いがあり、デバッガ上で実行させるとボクシングが発生することがあります。ですから、GCの発生の有無を調べる場合はF5ではなく、Ctrl+F5で実行することをお勧めします。
ModelMeshCollection、ModelMeshPartCollection、ModelEffectCollection、そしてModelBoneCollectionクラスのGetEnumeratorメソッドの実装がIEnumeratorを返す代わりに、Enumerator構造体を返すように実装されました。
これはモデルを描画するのによく使われるパターンとして
foreach (ModelMesh mesh in model.Meshes) { foreach (Effect effect in mesh.Effects) { BasicEffect be = effect as BasicEffect; if (be != null) { be.Projection = proj; be.View = view; } } mesh.Draw(); }
のようにforeachを多用します。この時、コレクションがIEnumeratorを返すと暗黙的なメモリ確保が発生してしまいます。せっかく便利なforeach文なのに、GCを避けるためにわざわざfor文に書き換える必要がありましたが、2.0ではforeachを使ってもメモリ確保は発生しません。
SpriteFontのカー��ングサポート
カーニング(Kerning)とは、英数字でWAITのような文字を表示したときに全体の見た目のバランスを取るためにAとWの間を意図的に狭めるような処理のことです。これはspritefontファイル内に<UseKerning>ture</UseKerning>を指定することで設定できます。spritefontファイルで何も指定しない場合はカーニング処理をしないので、1.0で作ったファイルをカーニングさせるのにはUseKerningエレメントを追加してSpacingの値を0することをお勧めします。
2007/11/28追記:メールでの解除キー取得はベータ版でのテストのみに必要です。リリース版では解除キー取得の必要はありません
XNA Game Studio 2.0のベータ版がリリースされました。日本語での概要はXNA Japan Team Blogに載っています。
最初のリンクは英語ですが、今までXNA GSEを使っていた人、初めて使い始める人のためのセットアップの仕方が載っています。直ぐにダウンロードしたい人は以下のリンクから。
http://www.microsoft.com/downloads/details.aspx?FamilyId=1A096AC7-AEC5-4CD0-9826-1F07EB26EEFD&displaylang=en
基本的にそのままインストールするだけで使えるようになりますが、以下に幾つかの注意点などを書いておきます。
といった感じです。
XNA TeamブログにXNA GS 2.0におけるネットワークサポートについての投稿がありました。元の投稿では各シナリオについて細かい説明がありますが、ここではできるだけシンプルなルールを書いていこうと思います。
XNA Game Studio 2.0ではネットワーク対応のマルチプレイヤーゲームを作れるような仕組みが提供されます。このネットワークの接続形態はシステムリンクとLive!接続の二つがあります。
システムリンクは、同じサブネット内同士でのマルチプレイヤーゲームを可能にします。一般的なのは同じネットワークハブにPC、Xbox 360を繋げた時に使うことができます。
Live!接続ではXbox 360上ならばXbox Live!、Windows上ならばGames for Windows - LIVEを通す、つまりLive!サーバーを介してのマルチプレイヤーゲームを可能にします。離れた場所からのネットワーク接続を可能にする方法です。
ここで注意しないといけないのはLive接続によってゲームを遊ぶ為にはXbox 360、Windowsの両方ともLiveゴールド会員であることとXNAクリエーターズクラブ会員である必要があるということです。
マルチプレイヤーゲームを遊ぶのに必要なものをまとめると以下の用になっています。
注:XNA CCはXNAクリエーターズクラブの略
WindowsでのLive接続にXNA CCは必要ないのでは?と思ってしまいますが、そこらへんは色々と解決しないといけない問題があるので現状のようになっています。
ともかく、XNA 2.0のベータ版をはもうすぐでますので、より良いものにするためにバグ報告、要望などを言って貰えると有難いです。