TictactoeSkinner
Skinner
のサブクラスは、イメージ(スキン)ファイルを読み込むために必要とされます。これらのファイルを用いて、すべての画面のすべてのUIが描画されます。
public class TictactoeSkinner extends Skinner { [Embed(source="tictactoe\\rsrc\\Outline.png")] private static var OutlineClass:Class; [Embed(source="tictactoe\\rsrc\\ui.png")] private static var UIClass:Class; [Embed(source="tictactoe\\rsrc\\frame.png")] private static var FrameClass:Class; public function TictactoeSkinner() { } protected override function load():void { m_outline = (new OutlineClass() as BitmapAsset).bitmapData; m_ui = (new UIClass() as BitmapAsset).bitmapData; m_frame = (new FrameClass() as BitmapAsset).bitmapData; } }
このカスタムSkinner
はいたって単純です。上記が、このクラスの全リストです。load
メソッドをオーバーライドしてoutline
、ui
およびframe
のBitmapAsset
を作成します。これらはSkinner
クラスで定義されたプロテクトフィールドです。実行中にアセットを部分にカットしたり、部分を集めて1つにしたりする面倒な仕事は、すべてこのSkinner
オブジェクトで処理されます。
TictactoeNewGameScreen
このサブクラスはオプションですが、今回のゲームでは、Pulseサーバにゲームルームの詳細な特性(ターン制、ルームごとの最大プレイヤー数が2人であることなど)を伝えるために必要とされます。
public override function createNewRoom():void { PulseGame.getInstance().setCreatingRoom(); var room:GameRoomClient = new GameRoomClient(); room.setRoomName(m_ti.text); room.setMaxPlayerCount(2); room.setRoomType(GameConstants.ROOM_TURN_BASED); PulseGame.getInstance().getGameClient().createGameRoom(room); }
この新規ゲーム画面をカスタマイズすることで、作成されるルームの種類を定義します。上記は「三目並べ」ゲームに固有の設定です。このコードにより、ロビーでプレイヤーが目にするルーム名がセットアップされ、ルームの許容プレイヤー数が2人に設定され、このルームがターン制のゲームであることがPulseに通知されます。
Pulseは、これらのパラメータに基づいて動作します。詳細については、devガイドとAPIガイドを参照ください。
TictactoeGameScreen
ゲーム開始後にゲームルーム内で行われるすべてのアクションに関するクラスです。
このゲームコードの実装に用いられているクラスがあと2つあります(本稿には掲載されていませんが、Pulseパッケージをダウンロードすれば、ソースコード全体を見ることができます)。それは次の2つのクラスです。
- 「TictactoeHotspot」-ゲームボードの9個の領域を監視するためのスプライトのサブクラス。この領域には、プレイヤーに応じて「O」または「X」が子として追加されます。
- 「TictactoeGameStatus」-いくつかの定数を保持する簡単なクラス。
init
メソッドをオーバーライドして、ホットスポットなどを初期化します。これはゲームクライアントのライフタイムで1回だけ実行されます。ソースはここに掲載されていません。
ゲーム画面の初期化
上記のinit
メソッドが呼び出されるのは1回だけですが、プレイヤーはルーム(ゲーム画面)に何度でも入ったり出たりできます。
プレイヤーがゲームルームに入るたびにshow
メソッドが呼び出され、プレイヤーがルームを去るときは必ずhide
が呼び出されます。
public override function show():void { super.show(); }
このゲームでは、show
メソッドで何かを描画することはせず、ゲームが開始されるのを待つことにします。super.show()
が、GameScreen
クラスのshow
メソッドを呼び出し、これにより「go」または「wait」スプライトが表示されます。ルーム作成者が自動的にそのルームのホストとなり、PulseUIによって、ホストプレイヤー側には「go」が、そのルームに参加するその他のプレイヤー側には「wait」が必ず表示されるようになります。
特別な扱いを必要としないゲームなら、このオーバーライドを省いてもかまいません。ここに示したのは、少し説明した方がよいと考えたからです。
startGame
メソッドは、ホストが「go」スプライトをクリックしたとき、すべてのプレイヤークライアントで呼び出されます。フィールドm_putValue
が初期化され、これを用いて「O」と「X」のどちらを表示するかが決められます。
public override function startGame():void { super.startGame(); if ( PulseGame.getInstance().getGameClient().isGameHost() ) { m_putValue = 1; } else { m_putValue = -1; } addChild(m_borderSprite); for each (var hotspotArray:Array in m_hotspotArray) { for each (var hotspot:TictactoeHotspot in hotspotArray) { m_borderSprite.addChild(hotspot); } } m_isGaming = true; }
super
側の実装により「go」または「wait」スプライトが削除されます。ゲームボードが初期化されます。
次のhide
メソッドでは、ゲーム画面の関連するスプライトが確実に削除されるようにしています。
public override function hide():void { if (m_showingTurn) { removeChild(m_turnSprite); } if(m_borderSprite.numChildren> 0) { for each (var hotspotArray:Array in m_hotspotArray) { for each (var hotspot:TictactoeHotspot in hotspotArray) { if(hotspot.numChildren> 0) hotspot.removeChildAt(0); m_borderSprite.removeChild(hotspot); } } } if ( m_isGaming ) { finishRound(); removeChild(m_borderSprite); } m_isGaming = false; super.hide(); }
プレイヤーがゲーム画面から去ることを選ぶと、lobbyHit
メソッドが呼び出されます。この段階で、ゲームを終了させます。今回のゲームの実装では、対戦相手が去った後もルームにプレイヤーを残しておいても意味がないので、一方のプレイヤーが去ったなら、直ちに両方のプレイヤーをロビーに戻します。ここで必要なら独自の動作を実装してもかまいません。
protected override function lobbyHit():void { //Host send finish game and non-host sent enterlobby if ( m_isGaming == true ) m_tictactoeGame.getGameClient().finishGame(); super.lobbyHit(); }
以上が、このゲームボードの画面管理の部分です。次に、ゲームがどのように進行するか見てみましょう。