【プログラミング中級者向け】ExcelVBAでスネークゲームを自作してみよう!応用編

難易度変更 PC

どうも、室井(@muroiwataru)です。
今回は以前作成したスネークゲームに機能を追加していきます。

前回の記事を読んでいない方は、先にそちらを読んでください。

【プログラミング初心者向け】ExcelVBAでスネークゲームを自作してみよう!基礎編

2018.05.13

難易度選択機能の追加

ゲームの難易度は自機の移動速度を変更すれば調節できます。
sleep関数による待機時間を短くすれば難易度が上昇しますね。

やるべきことをリストアップすると以下のようになります。

  • 難易度を切り替えるボタンの追加
  • 難易度を確認できる表示の追加
  • 難易度ごとにSleep関数の時間を変更
難易度選択ボタン

UIはこのようになります。
順番に実装していきましょう。

難易度を切り替えるボタンの追加

難易度を選択するためのコマンドボタンを作成します。
EASY・NORMAL・HARDの3つのコマンドボタンを追加しました。

コマンドボタンの作成方法は方向キーを作成したときと同様です。
忘れてしまった方は前回の記事の外部設計を確認してください。

作成したコマンドボタンに以下のプログラムを追加します。
levelの値は難易度ごとに変更します。
今回はEASYを0、NORMALを1、HARDを2としてください。

levelという変数はまだ宣言していないので、標準モジュールにPublicで宣言しておきましょう。
型はInteger型を推奨します。

lebel変数は何に使うの?

Sleep関数を実行する前にlebel変数の値で分岐させることで、難易度を変更するために使います。
また、後に実装するランキング機能でも利用します。

If play = 0 Thenの意味は?

ゲームプレイ中には難易度の変更ができないようにするための処理です。
プレイ中に難易度を変更されると、ランキングが正常に機能しないためです。

難易度を確認できる表示の追加

VBAでは Cells(行, 列) = “文字列” でセルに任意の文字列を入力できます。
難易度を表示させるウィンドウを、セルを結合して表現しましょう。

今回はAA2~AE3を結合して中央揃えにしているので、Cells(2, 27) に文字列を入力します。
先程書いたコマンドボタンのプログラムに1行追加します。

難易度変更

難易度ごとにSleep関数の時間を変更

Select Case文を使って、難易度ごとに自機の移動速度を変更しましょう。
前回、Sleep 90‘待ち時間の調節  と記述した部分を以下のように書き換えます。

キーボードからの操作

コマンドボタンのプロパティからAcceleratorを設定すると、キーボードを押下した際にクリックしたときと同様の処理が走ります。
ただし、Altキーと同時押しする必要があります。

キーボード操作

上下左右にwasdなどを割り当てておくといいでしょう。

ランキング機能の実装

CSVファイルの作成

複数人でデータを共有できるように、csvファイルとしてユーザー名と得点を保持します。

csvファイル

1~3行目をEASY、4~6行目をNORMAL7~9行目をHARDの記録として使います。
1行ごとに 得点,”ユーザー名” となっているので、最初は0と適当な文字列を入れておきましょう。

上記のプロシージャを実行すれば、自動でscore.csvファイルが作成されます。
デバッグ中にファイルを初期化したい状況が出てくるので、書いておくといいでしょう。

外部設計

ユーザー名&ランキング

ユーザー名の入力フォームの作成

テキストボックスでユーザー名の入力フォームを作成します。

プロパティから入力できる文字数を制限できます。
ランキングの表示が崩れないように、MaxLengthを設定しておきましょう。

入力文字数制限

ランキングを表示するラベルの作成

ランキングを表示するためのラベルを作成します。
プロパティからフォントを等幅フォントに変更しておいてください。

プロポーショナルフォントだと、下の画像のように表示が崩れてしまいます。

プロポーショナルフォント

コマンドボタンを1つ作成しておいてください。

ランキングを読み込む処理

csvファイルを読み込んで、ラベルに出力する処理です。
リアルタイムで更新することは難しいので、コマンドボタンを押したときに呼び出します。

先程作成したコマンドボタンにCall文を追加しましょう。

ランキングを書き出す処理

記録を更新した際に、csvファイルを更新するための処理です。
排他制御していないので、複数人が同時にゲームオーバーすると正常に更新されない可能性があります。

このプロシージャを、ゲームオーバーの判定をしているIf文の中から呼び出せるようにしましょう。

ユーザー名を記録できるように、ゲーム開始時にplayer変数にテキストボックスの値を格納できるようにします。
player変数は標準モジュールにPublicで宣言しておいてください。
型はString型です。

僕の場合はSheet1.TextBox1を使っているので、player = Sheet1.TextBox1.Text をスタートボタンに記述します。

最終的にスタートボタンのプログラムはこのようになりました。
Excel起動時に難易度の表示と変数の値がズレている場合があるので、難易度の表示を確認する処理も追加しています。

プレイ中の得点の表示

スコア

赤いブロックを取得するたびに、カウントアップしていくようにします。
難易度の表示と同様に、結合したセルに表示させています。
今回はU2のセルを使用しています。

赤いブロックを取得したかどうかのIf文に、下記の1行を追加します。
cntをインクリメントする前に記述してください。

また、初期化プロシージャに表示をリセットするための1行も追加します。

あとがき

ランキング機能はうまく実装できましたか?
csvファイルなので簡単に改ざんされますが、そこはVBAの限界ということで妥協してください。

室井
csvファイルをゲームに活用する手法は他にも使い道がありそうな気がする。