前回はフィールド上(フィールド変数と紛らわしい)を歩くだけのプログラムでしたが、城からフィールド、フィールドから城へと移動できるようにします。城はマップの上に描画されているので、それと重なる位置に移動したら城のなかに入ることができるようにします。

Mapクラスにメソッドを追加

すべてのマップの基底クラスになるMapクラスに以下を追加します。

これはマップのテキストのなかにある文字からブロックの位置を取得するメソッドです。取得できるのは最初に見つかったブロックの位置です。フィールド上に「城」とか「魔」とあるので、この位置から城の位置を取得します。

主人公の現在位置はダンジョンがある位置か?

これは引数として渡されたブロック(Rectangle)のリストのなかに点(x, y)が存在するのかどうかを調べるメソッドです。主人公の現在位置が城やダンジョンのある位置の内部なのかどうかを調べるときに使います。

Map1クラスにメソッドを追加

Map1クラスに以下を追加します。

まず城のなかに入ったときは城の内部を描画できるようにしなければなりません。ふたつの城は両方とも下から城に入るようになっています。そこで上に移動したときに城の内部に入っているかどうかを調べるIsCastleメソッドとIsEnenyCastleメソッドを作成します。

プレイヤーが城に入ったかどうか?

城のなかに移動した場合のイベントを定義

城がある位置に移動した場合はフィールドではなく城の内部を描画させたいのでEnterCastleイベントとEnterEnemyCastleイベントを定義します。

BGMを再生したり停止できるようにします。

Form1クラスの変更

Form1クラスを少し変更します。

コンストラクタが呼び出されたら自作メソッド InitDungeonsを実行します。ここでMap1クラス、MapCastleクラスのインスタンスを生成します。

城に入るとき、城から出るときのイベントが発生したら表示を切り替えます。

描画処理にかんする部分を示します。_map == nullの場合は全面を黒にします。

城の内部を描画するクラス

城の内部を描画するクラスを作成します。

城はとりあえず2つだけ作ります。コンストラクタの引数で自分の城と敵の城を区別します。第二引数が0なら自分の城、1なら敵の城です。

城の初期化

初期化の処理を示します。敵の城の場合は「王」の位置に魔王を表示させます。

城内の描画処理

ImageRectangle.DrawWithShiftメソッドに以下を追加してBlockTypeが壁、床、階段、王女、魔王のとき適切な描画ができるようにします。

BlockTypeとBlockImageクラスにメソッドを追加して、壁、床、王、魔王のイメージを取得できるようにします。

これで城の内部が描画されるようになります。

BGMの開始と終了

BGMを開始したり終了できるようなメソッドを作成します。BGMはフィールド上と同じものを使用しています(サンプルなので手抜きです)。

城の外に移動する処理

ExitCastleイベントを定義して出口に移動したら城の外に出る処理がおこなえるようにしておきます。

以下は移動しようとしている場所に出口や人がいるかどうかを調べるためのメソッドです。

これでフィールドから城へ、城からフィールド上への移動ができるようになりました。