VBAテトリス 詳細編 テトリミノを画面に表示する
どうもこんにちは。
programminghajimetemita.hatenablog.com
このテトリスをどうやって作ったのか解説していきたいと思います。
今回は「テトリミノを表示する」プログラムをどうやって作成したのかについてです。
- 1.作成ステップ
- 2.テトリスのブロックをエクセルでどうやって表現するか?
- 3.テトリミノを画面上にどうやって表示させるか?
- 4.ランダムに1種類のテトリミノを表示する挙動をどうやって実現するか?
- 5.おわりに
1.作成ステップ
まず、テトリスのブロック(テトリミノ)をエクセルでどうやって表現するか、
というところから考えました。
次に、各種類のテトリミノをエクセル上にどうやって表示させるかを考えました。
最後に、全7種類のテトリミノからランダムに1つ表示される挙動をどうやって実現するかを考えました。
まとめると以下3ステップです。
① ブロックのデザインをエクセルでどう実現するか考える
② 画面上にテトリミノをどうやって表示させるかを考える
③ ランダムに1種類を表示する挙動をどう実現するか考える
①については前回紹介した「ゲーム画面を作る」と考え方は同じですね。
programminghajimetemita.hatenablog.com
②・③は自分がイメージしている挙動をプログラムでどうやって実現するか、
試行錯誤を繰り返す感じです。プログラミングらしくなってきましたね。
では、それぞれについて解説していきたいと思います。
2.テトリスのブロックをエクセルでどうやって表現するか?
一つ目、テトリスのブロックをエクセルでどうやって表現するかについてです。
これについては、せっかくエクセルで作るのだからセルを生かさない手はないと思い、
セルをブロックに見立ててテトリミノを表現する方向で考えました。
ただ、単純にセルに色付けするだけではテトリスっぽさがないなと感じたので、
書式を工夫してそれっぽく見えないかなーと色々試しました。
結果、セルの背景色を黒にし、白色の二重罫線を引くという書式が一番それっぽかったので採用しました。以下、ゲーム画面の一部です。
いかがでしょうか?それっぽいですよね?
テトリスミニのゲーム画面を参考にして一番近いと思ったのがこの組み合わせでした。
以上をまとめると以下の通りです。
・テトリスのブロックはセルの書式を変更することで再現する
・書式の変更内容は「背景色:黒」、「二重罫線」、「罫線色:白」の3点
3.テトリミノを画面上にどうやって表示させるか?
ブロックについては上述の通り、セルの書式を変更することで再現しました。
次はテトリミノをどうやって表示させるかについてです。
これは単純に、テトリミノの形になるセル範囲の書式の変更ができればよいと考えました。
そのために、テトリミノの形になるセル範囲を選択する必要があります。
これには「Union」というコードを使用しました。
複数の独立したセル範囲を選択できるコードです。
では、Unionを使って具体的にどの範囲のセルを選択したのかについてですが、
テトリミノの位置はテトリスのゲーム中、色んな場所に変わり得るので、
変数で表現しました。
具体的にはテトリミノを表現するのに選択され得る範囲の一番左上のセルの座標を(r,c)として、
そのセルを起点に書式変更が必要なセルの座標を変数で表しました。
(※ rは行番号、cは列番号を表しています)
以下のようなイメージです。
テトリミノの全ての種類について上記と同じことをしてセル範囲の選択を行いました。
これで(r, c)に表示させたい位置を代入すれば、その位置にテトリミノを表示させることができるようになりました。
さて、コードを書く上でテトリミノのセル範囲に対して何か処理を行わせたい時に、
上記のセル範囲を毎回書くのは面倒です。
そこでオブジェクト変数を宣言し、予めその変数に上記のセル範囲を登録しました。
コードは以下のような記載です。
Dim block1 As Range
Set block1 = Union(Cells(r, c), Range(Cells(r + 1, c), Cells(r + 1, c + 2)))
これでテトリミノのセル範囲に何か行いたい時は、
"block1"に対して命令を書けばOKになります。
ここまでをまとめます。
・テトリミノを画面に表示するには、その形のセル範囲を選択し、書式を変更する
・テトリミノの形のセル範囲の選択には「Union」を使う
・Unionで指定するセル範囲は変数で表す
・Unionで指定するセル範囲は予めオブジェクト変数に代入しておく
4.ランダムに1種類のテトリミノを表示する挙動をどうやって実現するか?
ここまででテトリミノをエクセル画面上に表示させることができるようになりました。
最後に、7種類あるテトリミノからランダムに1種類が選択され、
それが画面に表示されるようにする動きを再現する方法です。
これは以下のように処理させれば実現できると考えました。
・予め各テトリミノに1~7までの番号を振っておく
・1~7の整数をランダムに発生させる
・発生した値に応じたテトリミノを呼び出す
まず、各テトリミノへの番号の割り振りですが、これはテトリミノごとにオブジェクト変数を用意すれば自ずと実施することになります。
以下のようなイメージです。
①L字型ブロック:block1 ⇒ Set block1 = Union(・・・)
②逆L字型ブロック:block2 ⇒ Set block2 = Union(・・・)
③凸型ブロック:block3 ⇒ Set block3 = Union(・・・)
・・・
次に、1~7の整数をランダムに発生させる方法です。
この処理にはRnd関数を利用しました。
以下のようなコードを書くと1~7までの整数をランダムに生成することが可能になります。
Int( Rnd * 7 ) + 1
この値を変数に格納することで、その変数を参照すれば1~7のランダム整数を得ることができるようにしました。
私が作ったマクロでは"block"という変数に入れていました。
最後に1~7の整数に応じて対応するテトリミノを呼び出す処理です。
これは変数block(1~7のランダム整数値)を引数にして、
引数の値に応じて条件分岐(Select Case)させることで実現しました。
具体的には以下のようなコードイメージです。
Sub createblock(block As Integer)
Select Case block
Case 1
With block1
.Interior.ColorIndex = 1
.Borders.LineStyle = xlDouble
.Borders.ColorIndex = 2
End With
・・・
ちなみに、With~End Withで記載している部分は、
呼び出した"block1"に対して書式を変更させるコードになります。
block1を呼び出すだけではエクセル画面に変化は起きませんので、
2.で解説した書式の変更を加える必要があります。
以上により、7種類あるテトリミノからランダムに1種類選択され画面に表示される挙動の完成です。
まとめです。
・テトリミノごとにオブジェクト変数を準備する(ex.block1=~,block2=~...)
・Rnd関数を使って1~7のランダム整数値を生成する
・Select Caseを使ってランダム整数値ごとに対応するテトリミノのセル範囲を呼び出す
・呼び出したセル範囲に対し、書式の変更を行う
5.おわりに
今回は「テトリミノを表示する」方法について解説しました。
ゲーム画面のNEXTの部分にテトリミノを表示する方法についても解説したかったのですが、
内容が多くなってしまったのでそれは次回お話しすることにします。
ではまた。