記事の前の部分(
パートI )では、Windows Phone 7向けのゲーム作成の基本的な問題であるツールとテクノロジーの選択について検討しました。 次に、プログラミングと電話との相互作用の問題を詳細に調べます。
ゲームロジック
別のGameControllerクラスですべてのゲームロジックを取り出します。 ゲームクラスのUpdate関数は次のとおりです。
protected override void Update(GameTime gameTime) {
GameTimeクラスオブジェクトをGameController.Updateに渡していることに注意してください。 これにはElapsedGameTimeプロパティがあり、Update関数の前回の呼び出しから経過した時間を示します。 原則として、この時間は固定されており、電話は33ミリ秒に相当しますが、それを当てにするのではなく、送信された値をすべての計算で使用することをお勧めします。
ゲーム世界のオブジェクトの動きを計算する必要がある場合はいつでも、ElapsedGameTimeを使用します。 たとえば、(電話の傾きの影響下で)白いボールの新しい位置を計算する必要がある場合、コードは次のようになります。
position += (float)(acceleration * gameTime.ElapsedGameTime.TotalSeconds);
ボールとブロットの半径(出現時)は、次のように計算されます。
radius += (float)(GrowSpeed * gameTime.ElapsedGameTime.TotalSeconds);
当然、これらの計算はすべて別々のクラスで行います-それぞれに同様の関数Update(gameTime)があります。 そして、GameController.Updateはそれらを呼び出すだけです。
グラフィックスを描く
また、図面をGameControllerクラスに転送します。 ゲームクラスのDraw関数は次のようになります。
protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.Black); spriteBatch.Begin(); GameController.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
SpriteBatchクラスのオブジェクトのみをGameController.Drawに渡すことに注意してください-これは描画専用です。 ここではGameTimeは必要ありません。必要な計算はすべてUpdate関数で既に行われているためです。
次に、GameController.Drawは、ゲームワールドのロジックを実装するクラスで同様のDraw(spriteBatch)関数を呼び出します。
描画自体は非常に簡単に見えます。
spriteBatch.Draw(texture, position, color);
つまり、完成したテクスチャのみを画面に表示できます。2Dプリミティブ(線、長方形、楕円など)の描画はXNAでは提供されていません。
テクスチャは、コンテンツからダウンロードすることで取得できます。
Texture2D texture = Content.Load<Texture2D>(assetName);
テクスチャはすでにロードされており、すべての位置が計算されています。 しかし、色を使用すると、面白いことができます。 テクスチャの元の色が必要な場合は、Color.Whiteを渡す必要があります。
ただし、別の色を転送すると、この色のオーバーレイでテクスチャが描画されます。 アルファチャンネルで色を設定すると、テクスチャは半透明になります。 したがって、オブジェクトの滑らかな外観と消失、およびそれらの色の変化を制御できます(これはすべてゲームで必要です)。
2つの色を混合するには、Color.Lerp関数を使用します。 また、アルファチャネルを追加するには、Color.FromNonPremultiplied関数を使用する必要があります。
spriteBatch.Draw関数には他にもオプションがあり、テクスチャを回転させて拡大縮小することができます。 彼らも私たちに役立つでしょう。
テキストを表示する
画面にテキストを表示するのは、グラフィックを表示するのと同じくらい簡単です。
spriteBatch.DrawString(spriteFont, text, position, color);
SpriteFontクラスのオブジェクトは、コンテンツからロードすることで取得できます。
SpriteFont spriteFont = Content.Load<SpriteFont>(assetName);
ここで、同じ方法でテキストの色を指定できます。 また、アルファチャンネルで色を設定すると、テキストは半透明で描画されます。
フロート位置でテキストを表示するための座標を指定すると、テキストがわずかに歪んで表示される場合があります。 したがって、テキストのスムーズな移動が必要な場合は常に、座標を整数に丸めます。
spriteBatch.DrawString関数には、テキストの回転と拡大縮小を可能にする他のオプションがあります。 ただし、このような操作はテキストの歪みを引き起こすことを覚えておく必要があります。 これは、XNAが元のベクターフォントではなく、プロジェクトのコンパイル時に作成され、コンテンツに追加されるビットマップ表現では機能しないためです。
タッチスクリーン
ユーザーが画面のどこをクリックしたかを判断するには、Microsoft.Xna.Framework.Input.Touch.TouchPanelクラスからデータを取得する必要があります。
foreach (var item in TouchPanel.GetState()) { if (item.State == TouchLocationState.Pressed || item.State == TouchLocationState.Moved) {
したがって、ユーザーが指で触れただけの画面上のすべてのポイントを取得します。
ただし、ユーザーが画面上で1回タップした場所(押した状態と離した状態)のデータも必要になります。 これは、一時停止などの画面ボタンのクリックを追跡するために必要です。 このデータを取得するには、ジェスチャサポートを使用します。
最初は、ゲームの開始時に、そのようなジェスチャー(タップ)のサポートが必要であることを示します。
TouchPanel.EnabledGestures = GestureType.Tap;
その後、ゲームループの各反復でジェスチャーを取得できます。
while (TouchPanel.IsGestureAvailable) { GestureSample gesture = TouchPanel.ReadGesture(); if (gesture.GestureType == GestureType.Tap) {
加速度計
電話の傾きに関する情報を取得するには、Microsoft.Devices.Sensors.Accelerometerクラスを使用します。 残念ながら、加速度計から直接データを取得することは不可能です(TouchPanelで行ったように)-イベントモデルのみをサポートします。 したがって、オブジェクトを作成し、そのイベントをサブスクライブするヘルパークラスを作成する必要があります。
accelerometer = new Microsoft.Devices.Sensors.Accelerometer(); accelerometer.ReadingChanged += AccelerometerChanged; accelerometer.Start();
イベントハンドラでは、加速の値を記憶し、将来の使用のために保存します。
private void AccelerometerChanged(object sender, AccelerometerReadingEventArgs e) { vector = new Vector3((float)eX, (float)eY, (float)eZ); }
加速度ベクトルには3つの軸すべて(X、Y、およびZ)に関する情報が含まれますが、最初の2つだけが必要です(電話の縦向きに関して)。 したがって、座標系で加速度を返すプロパティは次のようになります。
public Vector2 Acceleration { get { return new Vector2(vector.X, -vector.Y); } }
白いボールに与えるのはこの加速です。
ここでは、加速度計の軸のより視覚的な表現を取得でき
ます 。
音を鳴らす
XNAでサウンドを再生するには、SoundEffectクラスのオブジェクトのPlay関数を使用します。 このクラスのオブジェクトは、コンテンツからダウンロードできます。
SoundEffect sound = Content.Load<SoundEffect>(assetName);
実際、それだけです-サウンドで他に何もする必要はありません。
窓
最後に、ゲームが完了します。白いボールは加速度計によって制御され、残りはそれを追いかけ、指でそれらをクリックするとしみに変わり、ポイントがカウントされ、音が出ます。 すべて準備ができているようですか? あった!
次に、ウィンドウを作成する必要があります:開始ウィンドウ(メインメニュー)、一時停止ダイアログ、およびゲーム完了ウィンドウ(スコア表示と記録付き)。
XNA for Windows Phoneにはウィンドウがないため、自分でウィンドウを作成する必要があります。 一見思えるほど難しくはありません。
親、子、境界、表示、有効、および更新と描画機能の主要なプロパティで基本的なコントロールを作成するだけで十分です。 次に、ウィンドウ、ボタン、ラベルなど、いくつかの相続人を作成します。
その後、ウィンドウ内に要素を簡単に配置できます。
状態保存
電話のゲームは、ハードウェアのホームボタンを押すか、別の外部イベントによっていつでも中断できます。 したがって、ゲームの状態をいつでも維持し、ゲームをロードするときにこの状態を復元することを心配する必要があります。
状態(および同時に設定)を保存するには、System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettingsクラスを使用します。 このクラスはIDictionary <string、object>インターフェースを実装しているため、非常に簡単に使用できます。 このディクショナリにゲーム世界のすべてのオブジェクトの現在の状態(残念ながら、それらのいくつかがあります)を追加し、IsolatedStorageSettings.ApplicationSettings.Save()関数を呼び出します。
アプリケーションの終了時に保存します。このため、ゲームクラスのOnExiting関数をブロックします。
protected override void OnExiting(object sender, EventArgs args) { GameController.SaveState(); base.OnExiting(sender, args); }
状態の復元も同様に実行されます-アプリケーションを読み込むときに、IsolatedStorageSettings.ApplicationSettingsからデータを取得し、ゲームワールドのすべてのオブジェクトを復元します。
アプリケーションを有効化および無効化する
アプリケーションは常にアクティブな状態にあるとは限りません-場合によっては(たとえば、着信コールによって)非アクティブ化してから、再びアクティブにすることができます。
これらのイベントを追跡するために、ゲームクラスのOnActivatedおよびOnDeactivated関数をブロックします。
アプリケーションが非アクティブ化されると、ゲームが一時停止モードになります-そのため、ユーザーがゲームに戻ると、ユーザーはゲームを続行するための提案のダイアログを見つけることができます。
さらに、非アクティブ状態の電話機のコンピューティングリソースを無駄にしないために、ゲームクラスのUpdate関数の先頭に次のコードを追加します。
if (!IsActive) { SuppressDraw(); return; }
スプラッシュスクリーン
私たちのゲーム(またはゲームコンテンツ)は数秒間読み込まれ、同時に生命の兆候は表示されません-黒い画面のみが表示されます。 アプリケーションが機能していることを何らかの形でユーザーに示す必要があります。 これを行うには、ゲームの開始時に美しいスプラッシュスクリーンを描画して表示します。

Windows Phone用のSilverlightアプリケーションでは、SplashScreenImage.jpgファイルをプロジェクトに追加するだけで、起動時に自動的に表示されます。 ただし、これはXNAプロジェクトでは機能しません。
コンテンツの読み込みをやり直す必要があります-最初に、スプラッシュスクリーンのテクスチャを読み込み、Draw関数を初めて呼び出したときに描画します。 そして、残りのコンテンツをすべてダウンロードして、ゲームを起動します。 そして、残りのコンテンツがロードされている間、ユーザーは画面上でスプラッシュ画面を見ることができます。
これで、アプリケーションの起動がより良くなりました。
電話でのゲームの場所
ゲームを[ゲーム]セクションの電話に表示するには(電話の開始画面で[XBOX LIVE]というボタンをクリックすると表示されます)、プロジェクトのWMAppManifest.xmlファイルを編集する必要があります。 このファイルでは、ジャンル=「Apps.Normal」の行の代わりに、ジャンル=「Apps.Games」と記述する必要があります。
同時に、同じファイル内のゲームの名前と説明を(Title属性とDescription属性で)示します。 不要な要件を削除します(セクション)。 このセクションでは、加速度計をサポートするために/>のみを残します。 このバージョンのゲームの残りの部分はまだ必要ありません。
プロジェクトには、GameThumbnail.pngとBackground.pngの2つの画像が必要です。
最初の画像はゲームセクションでゲームを表示するために必要で、2番目の画像は携帯電話のスタート画面に必要です。 両方の画像は同じサイズである必要があります:173x173ピクセル。
試用モード
ゲームは有料になるため、試用モードのサポートを追加する必要があります。 試用検証は既にプラットフォームに組み込まれており、Microsoft.Phone.Marketplace.LicenseInformationクラスを使用して実行されます。
var license = new Microsoft.Phone.Marketplace.LicenseInformation(); return license.IsTrial();
この関数の動作はかなり遅いため、ゲームループの繰り返しごとに呼び出すことはありません。 代わりに、ゲームクラスのOnActivated関数でアプリケーションがアクティブになったときにのみ呼び出し、結果を変数に保存します。
アプリケーションが試用モードで起動された場合、ゲームの数分後に、アプリケーションを購入するか、新しいゲームを開始するという提案のダイアログがユーザーに表示されます。
[購入]ボタンをクリックすると、Windows Phoneマーケットプレイスにアプリケーションが表示されます。
var market = new Microsoft.Phone.Tasks.MarketplaceDetailTask(); market.Show();
購入後、ユーザーはアプリケーションに戻ってゲームを続行できます。
戻るボタン
最後に、すべての準備が整い、アプリケーションをWindows Phoneマーケットプレイスに送信しています。 公開前に、Microsoftで徹底的にテストされ、数日後に評決が出されます。合格していません。 問題は何ですか?
この問題は、更新機能に残したコードそのものにあることが判明しました。
protected override void Update(GameTime gameTime) {
ハードウェアの[戻る]ボタンはどこでも特定の方法で機能するはずです-ユーザーを前の画面に戻します。 また、アプリケーションの終了は、ユーザーがアプリケーションの開始画面(ゲームのメインメニュー)にいる場合にのみ実行する必要があります。 一時停止ダイアログが開いている場合、[戻る]ボタンを押すとゲームに戻ります。
しかし、[戻る]ボタンは常にアプリケーションを終了させました。 このコードを削除し、[戻る]ボタンの正しい処理を行い、確認のために再度送信します。 繰り返しのレビューにかかる時間ははるかに短くなります。
結果
そしてついに受け入れられました! 現在、ゲームはWindows Phone Marketplaceにあります。
合計で約2週間が開発に費やされました(さらに2週間がゲームをストアに配置するのに費やされました)。 結果は非常に素晴らしくエキサイティングなゲームです:


Best WP7 Games Webサイトのエディターは、このゲームをレビューしました:
www.bestwp7games.com/splash-fun-accelerometer-game-for-wp7-review.htmlそして、登場から1週間後、このゲームはWindows Phoneマーケットプレイスで有料ゲームのトップ100を獲得しました。
ここからゲームをダウンロードできます
。このゲームを開発した経験からどのような結論を引き出すことができますか? Windows Phone 7用のゲームの作成は本当に簡単です!