C基礎8 テトリス風ゲーム(多次元配列)
C基礎8 テトリス風ゲーム(多次元配列)
本章ではテトリス風のゲームを作ります。7つの基本ブロックを多次元配列を使って宣言します。キー操作しない時は、自動的にブロックが落ちていくようにするためには、標準入力と呼ばれるscanf関数やgetchar関数を使う事ができません。C言語が標準的に用意している関数ではありませんが、コンソール入力と呼ばれる方法を紹介します。この方法を使うと、方向キーでブロックを移動させたり、キーを押さない時は、別のプログラムが動く様なプログラムを書く事ができます。
動画は、Windows10とVisualStudio2019を使った説明になっていますが、WIndows11とVisualStudio2022を使った場合の操作方法と同じです。
多次元配列の宣言方法や初期化の書き方を説明しています。配列宣言すると、指定した要素数の数の箱が用意されますが、どの様な順に並べられるかのイメージを描ける様にすると良いでしょう。初期化したデータが、各要素にどの様にセットされていくのかが分かります。
配列を扱う場合、1次元配列ではfor文が1つでしたが、2次元配列を扱う場合はfor文がネストした二重ループになり、3次元配列は三重ループになります。
テトリス風ゲームで使うブロックを表示するプログラムを通して、多次元配列を扱うプログラムの基本を学びます。
・配列の次元が増える毎に [ ] が増える
1次元配列は [ ] が1つですが、2次元配列は [ ] が2つ、3次元配列は [ ] が3つという様に、配列の次元が増える毎に、 [ ] 数が増えていきます。
・多次元配列の要素のメモリ配置をイメージする
要素番号の0から順番にメモリに配置されます。次元が増えた場合は、一番右側の [ ] の要素番号からずらしていきます。
・初期化の { } は次元数の数分ネストするのが基本
次元数の数より多く{ }をネストすることは出来ませんが、少なくとも { } で囲まれていれば文法的には問題ありませんが、次元数の数分ネストした書き方が良いでしょう。但し、全て0にする場合は、何次元配列であっても、{ 0 } の様に、{ } は1つだけで良いです。
4つの正方形を組み合わせて作られた7種類のブロックを3次元配列に定義し、それを表示するプログラムを作成しましょう。また、ブロックの種類ごとに異なる色を割り付けて表示みましょう。
色表示関係のマクロ定義と関数は、右下のYouTube動画の説明の中にURLを記載していますので、そこからダウンロードして使ってください。
7種類のブロックを、ブロック毎に、90度ずつ右に回転させたものを表示するプログラムを作成してみましょう。練習問題32のプログラムを修正して作ると良いでしょう。
10×20のフィールドを暗い灰色で表示し、その最上段にブロックを表示するプログラムを作成しましょう。
ブロックは、乱数を使って7種類の基本ブロックのどれかを、適当に回転させたものを表示しましょう。また、改行キーを入力したならば、新しいブロックを表示し、*を入力したならばプログラムを終了させましょう。
以下の文字を入力したならば、フィールドに表示したブロックを動かすように、練習問題34のプログラムを修正してみましょう。
a 左移動
s 下移動
d 右移動
x 右に90度回転
スペース 最下段まで移動
ブロックを動かす際は、フィールドの外に移動させないようにし、最下段になったら、新しいブロックを再表示するようにしてみましょう。
フィールドに表示したブロックが最下段に移動した場合、フィールドに固定化し、フィールドデータとして表示するように、練習問題35のプログラムを修正してみましょう。
ブロックを下に移動させた時、フィールドデータとなったブロックに、ぶつかった場合も同様に、フィールドに固定化させましょう。また、ブロックを左右に移動させる時、固定化したブロックに当たってしまう場合は移動できないようにしましょう。
ブロックをフィールドに固定化した時、固定化したブロックの断片が横一列に並んだ場合、その行を削除して、上にあるブロック断片を下に移動させる様に、練習問題36のプログラムを修正してみましょう。
練習問題37の行削除が起きた時、得点アップするプログラムを追加してみましょう。そして、一定の点数に達したならばゲームクリア、新しく生成したブロックが動かせない状態になったならばゲームオーバーになるようにしてみましょう。
_kbhit関数と_getch関数を使うコンソール入力と呼ばれる方法でキー入力します。
_getch関数を呼び出すとキーが押されるまで待ちの状態になってしまいます。キーを押していない時に別の処理をさせたい場合は、_kbhit関数と_getch関数を組み合わせてた書き方をします。
標準入力との違いを学びます。
標準入力関数は、入力したキーに対応した文字を画面に表示しながら、入力バッファと呼ばれる入れ物にキーを溜め込みます。コンソール入力は、入力したキーを画面表示せずに、直ぐに呼出し元に入力した文字を知らせてくれます。
・_getch関数はエコーバック無しでキーを直ぐに返す
文字キーだけでなく、方向キーやファンクションキー等のキーも入力することができます。
・キー入力無しでも動くプログラムは_kbhit関数を使う
キーが押されていない状態で_getch関数を呼び出すと待ちが発生し、プログラムの動きが止まってしまいます。キー入力無しでも動くプログラムは、キーが押されている時だけ_getch関数を呼び出すようにしなければなりません。_kbhit関数を使ってキーが押されているかを調べてから_getch関数を呼び出すようにします。
_getch関数でキー入力した時、どの様なキー番号を取得できるか実験するプログラムを作成します。
ESCキーが押されるまで、_getch関数を使ってキー入力し、得られたキー番号を10進数と16進数で表示するプログラムを作成してみましょう。また、文字として表示可能な場合は、キー番号に対応した文字を表示してみましょう。表示可能な文字かどうかは、文字関数の1つであるisprint関数で調べることができます。
練習問題38まで、テトリス風ゲームを作ってきましたが、更に成長させ、キー入力していない時は自動落下させるようにします。そのための一歩として、標準入力からコンソール入力に切替えます。
練習問題38のプログラムでは、getchar関数でキー入力していましたが、これを_getch関数を使ったキー入力に修正してみましょう。
今回の修正で、テトリス風ゲームを完成させます。
_kbhit関数を使って、キーイベントが発生していない時は、ブロックが自動的に落ちてくるようにしてみましょう。
ゲームクリアの点数を変えたり、ゲームクリアまでにかかった時間を計測したり、次に登場するブロックを事前に表示させたり等、各自で工夫してみましょう。
テスト実施フォーム ← テストチャレンジできます
上記テストの解説と解答