今回は昔がなつかしくなるレトロなゲーム・万引少年をアスキーアートでつくります。こんな感じのゲームになりますが、デバッグ情報がタイトルバーに出力されちゃってますが、ご愛敬ということで・・・。

万引少年はどんなゲーム?

万引少年は、1979年に日本で発表されたゲームソフトです。「万引少年A」を操作し、深夜営業のスーパー・ストアで閉店時間までにすべての商品を万引きします。店内では文部省(当時存在したのは文部科学省ではなく「文部省」。時代を感じます)から派遣された監視員Kが見張っており、彼に万引するところを見つかったり、閉店時間を過ぎると、監視員に捕まって警察へと連行される。

これは実際にプレイしている様子です。コンピュータはMZ-80、当時はパソコンではなくマイコンと呼ばれていいました。

アスキーアートでゲームをつくる

このゲームの面白さはアスキーアートでつくられた警備員Kの動き。どう見ても阿波踊りを踊ってるようにしか見えないです。「文部省から派遣された監視員K(本名:菊山)」というだけあって身体自体が「K」に見えます。こういうゲームはアスキーアートで作るに限ります。

万引きの舞台はオリジナルではセブンイレブインという名称ですが、ここではコンビニの名称を一部伏せ字にしました。セブンイレブインさん、ごめんね。それから万引きは窃盗罪であり、最長10年の懲役または50万円以下の罰金になります。絶対にやらないように。ダメ、絶対!

シーンをつくる

このゲームは大きくわけて複数のシーンで構成されています。最初の「アイテテヨカッタ」、実際に店内で万引きをするシーン、警備員にみつかって捕まってしまうシーン、すべての商品を万引きしてステージクリアのあとに表示される「アシタモタノムゾ」のシーン、そして警備員につかまった少年が警察署の近くまで連行されて警備員によって締め上げられるシーンの5つがります。

Positionクラスは商品が置かれている座標を管理するためのものです。

ゲームをつくる

ではゲームをつくってみましょう。

フィールド変数

実際にForm1クラスで使うフィールド変数を示します。

文字によって幅に違いがあるとズレてしまうのでフォントは「MS ゴシック」を使用しています。ただ掲載したコードは別のフォントなのでズレが生じています。また記事を管理しているエディタの都合で機種依存文字が?に化けてしまっています。そこで画像としてキャプチャしたものも掲載します。

コンストラクタの処理

まずアプリケーションが開始されたときの処理を示します。Form1クラスのコンストラクタは以下のようになっています。

タイマーを使って各キャラクタを移動させるのでタイマーの初期化をして、Timer.Tickイベントを処理できるようにしています。そして最初は店に入るまえのシーンを表示させたいので、フィールド変数 _sceneにはScene.Openingを代入しています。あとはゲームらしく背景を黒にすることとちらつきをなくすためにダブルバッファーの設定をしています。

それ以外の初期化の設定はInitGameメソッドでおこなっています。

ゲームの初期化

InitGameメソッドにおける処理を示します。GameOverUpdateCountとKKoraUpdateCountはゲームオーバー処理のときだけ値がインクリメントされます。前回ゲームオーバーになったときに初期値とは違う値に変わっているので再度ゲームを開始するときは0にリセットします。

それから前回のゲームのスコアも0にリセットして、シーンをScene.Openingに変更します。

Timer.Tickイベントの処理

再描画の処理は基本的にタイマーをつかっておこなわます(キー操作によって再描画の処理がおこなわれることもある)。そこでTimer.Tickイベントが発生したときの処理を示します。シーンによってDrawStart、DrawStoreField1、DrawStoreField2、DrawPolice、DrawGameClearの各メソッドを呼び出して処理をしています。

(DrawStartメソッドの定義はすぐ下にあります。DrawStoreField1、DrawStoreField2、DrawPolice、DrawGameClearの各メソッドは次回の記事を参照してください)。

文字をフォームに描画する

最初はDrawStartメソッドによって再描画がおこなわれます。ここではフィールド変数のStartFieldに格納されている文字列が表示されるだけです。StartFieldに格納されている文字列をフィールド変数FieldStringに格納してInvalidateメソッドを呼び出せばオーバーライドされたOnPaintメソッドによって描画処理がおこなわれます。

オーバーライドされたOnPaintメソッドを示します。一番上にはスコアや制限時間も表示させます。それ以外のシーンで制限時間を表示させてもあまり意味ないので表示はさせません。

オープニングの処理

オープニング画面からゲーム開始までの処理を示します。

Sキーを押したらゲーム開始

画面に「アイテテヨカッタ」と表示されているときに書かれているようにSキーを押したら店内に侵入して万引きミッションが始まるようにします。そこでOnKeyDownメソッドもオーバーライドします。

少年を移動させるときもキーを押すのですが、押しっぱなしで連続移動できてしまうと高速移動ができてしまうのでnoMoveフラグをつかってキーを移動したい距離だけ押さなければならないようにしています。キーを押したらnoMoveフラグによって移動処理ができないようにします。キーが離されたらnoMoveフラグをクリアします。

シーンがScene.OpeningのときにSキーを押せばInitStoreメソッドが実行され、シーンがScene.Store1に変更され、万引きミッションに移行します。