【#9】~ゲームオーバー+α編~新人プログラマーはテトリスを作れるのか?【C#.NET】

2021.07.19

CATEGORY : C#.NET プログラミング

こんにちは、あんみんどうふです。

今回はゲームオーバーの実装…だけだとすぐ終わっちゃうので、ゲームが始まるときのカウントダウンも実装します。

前回の記事はこちら。

こんにちは、あんみんどうふです。 今回はフィールドを見やすくするためにマス目と、ミノの置く場所をわかりやすくするためにゴーストを実装します。 前回の記事はこちら。 https://www.terasol.co.jp/%e3...
あんみんどうふです。番外編です。 今回は今作っているテトリスのデバッグに便利な機能を実装します。別に必要ないけど自己満足で作ります。 前回の記事はこちら。 https://www.terasol.co.jp/%e3%83%...

全編見たい方はタグからどうぞ。

9-1.自由落下

ゲームオーバーの前に先に実装しておきたかったのが「自由落下」です。実装するタイミングがなかなか掴めず、後へ後へと先延ばししていたらここまで来てしまったのでここでやります・・・。

自由落下についてですが、いわゆる「重力」のことです。
テトリスもぷよぷよも、放っておけば勝手に落下しますよね。これを実装します。

 

まずデザイナーを開き、ツールボックスからTimerを追加しnameを「freeFall」にし、Intervalを「500」にします。
これでfreeFallを動かしている間は500ミリ秒=0.5秒ごとに処理が行われます。

 

次にfreeFallのTickイベントを追加し、以下のコードを書きこみます。

自由落下の処理はこれだけです。0.5秒ごとに下へ移動するだけ。
(デバッグモードを有効にしている時は自由落下させないようにしてます)

 

ただ、自由落下が有効になっていないのでmainFormのLoadイベントの最後の方に追記します。

これでゲーム開始時から落下するようになります。
ちなみにデバッグモード中は自由落下しないようにしています。

 

また、挙動を本家テトリスに近づけるため少し手を加えます。
自由落下の経過時間を下移動する度にリセットされるようにしたいので、KeyDownイベントを修正します。

上キー、下キーの処理の最後にfreeFallを再スタートさせます。
ちなみにデバッグモードの時は再スタートさせないようにしないと勝手に自由落下し始めてしまうので注意。

また、設置時にも同じようにしたいのでminoDropメソッドの最後に同じものを追記します。

 

これでテトリスに重力の概念が生まれました。

 

 

9-2.ゲームオーバー

ゲームオーバーの条件は、次のNEXTに進行した際にミノの生成位置が障害物と被っていることです。
NEXTはミノを設置したタイミングで進行するので、minoDropで実行することになります。

そしてゲームオーバーになると操作ができなくなるようにします。逆に、ゲームオーバーではない時のみ操作できるようにしたいわけですね。

ということで、まずゲームを操作できるフラグとしてグローバル変数に「gameStart」というbool型変数を追加します。

※初期値はtrueにしてますが、後々falseに変えます。それは後ほど

 

次にKeyDownイベントに追記し、処理をすべてif文で囲うことでgameStartがtrueの時のみ操作できるようにします。

 

本題です。
新規メソッド「GameOver」を作成し、以下のコードを入力します。
ただ操作できなくなるだけだと地味なので、簡単なアニメーションを作ってます。
Locationを直接動かしているのでかなり無理矢理だけど。

(アニメーションがいらないなら最初の「gameStart = false;」だけで十分です・・・)

 

最後にミノを設置した時にGameOverメソッドを呼び出したいので、minoDropに追記します。
座標初期化時に重複チェックを行い、重複していればゲームオーバーです。
また、gameStartがtrueの時のみ処理を行うようにし、自由落下を停止しています。これらがないとゲームオーバー後も自由落下し続けて不自然な挙動になってしまうので。

ぷよぷよみたいにフィールドが落っこちてゲームオーバーになります。
ばたんきゅ~。

 

おまけ

お好みでゲームオーバー後の画面とか作るのもいいですね。

gameOverTextというLabelにわかりやすく「GAME OVER」と表示させて、gameOverButtonというButtonでフォームが閉じられるようにしてみました。

 

9-3.カウントダウン

3、2、1、START!と表示されてからゲームが始まるやつです。

カウントダウンを終えるまでは操作できないようにするため、先ほど初期値をtrueで作った変数gameStartを修正します。

 

カウントダウンを表示する領域を作るため、デザイナーを開き、わかりやすい場所にLabelを配置します。nameは「StartCountDown」にします。

私の場合はフィールドと同じ大きさに広げてフィールドのど真ん中に配置しています。仮テキストとして「—」と書いているやつです。

コードに戻り、Loadイベントのprivateの後に「async」を追加します。
これで一定時間待機させられる「await Task.Deray()」が使えるようになります。

 

そしてカウントダウンの処理をLoadイベントに追記します。初期座標を設定する部分の手前に書きます。

カウントダウンが終わり、描画まで終えたタイミングで操作が可能になるので、gameStartをtrueにするのを忘れずに。

できました。ゲーム感増しましたね。


ゲームオーバーも出来上がったので、テトリスとして普通に遊べるレベルになりました。

ここからは更にゲーム性を高めるための開発を行う予定です。
とりあえず一段落、自分にお疲れ様。

次回はTスピンの判定を作ります。
これまでは回転入れができるだけで特に何かあるわけでもなかったので、Tスピンしたことをよりわかりやすく強調表示させたいと思います。

#10 Tスピン判定編へ続く。

こんにちは、あんみんどうふです。 今回はTスピンを行ったかどうかの判定を作って、いろいろ応用したいと思います。 現状、回転入れができるだけなのでTスピンをしても特に何もありません。 高度なテクニックをきめたのに何も見返りがない...