プログラムの練習で作るゲームといえばテトリス!
ネックとなる「ブロックを回転させる」プログラムを作ります。
知ってる? スーパーローテーションシステム(SRS)
テトリスブロックを回転させるためにはSRSの存在を知らなければなりません。
ブロックを回転させたとき、何かにぶつかったら回転軸をずらして再試行する機構です。
これを実装しないと「壁けり」や「Tスピントリプル」が発生せず、テトリスの練習に使うことができません。
(https://ja.wikipedia.org/wiki/%E3%83%86%E3%83%88%E3%83%AA%E3%82%B9)
実践例だとこちらが見やすいと思います https://www.mintscore333.com/2018-09-05-203200/
前提
右がXのプラス方向、下がYのプラス方向、回転は角度は右回転方向とします。
回転していない状態を「状態0」として、右回転ごとに状態1・状態2・状態3とします。
初期回転軸を[0,0]としたブロックを定義する!
ここでは初期回転軸を[0,0]としてブロックを定義します。
この座標[0,0]は回転する「点」であり、「ブロックの中心点」となります。
T字ブロックは [[0,0],[1,0],[-1,0],[ 0,-1]] です。(上の状態0の図を参照)
カドの部分は0.5ズレた座標になります。
……I字ブロックは [[-1.5,-0.5],[-0.5,-0.5],[0.5,-0.5],[1.5,-0.5]]です(小声)
通常時の座標の回転
座標を回転させましょう。
座標[x,y]を回転軸[0,0]で右に90度だけ回転するのだから、一般的に回転後の座標は
x' = x * cos(90度) - y * sin(90度)
y' = x * sin(90度) - y * cos(90度)
で求められます。
テトリスだと90度単位しか使わないので sin(90度) = 1、cos(90度)=0で計算すると
x' = -y
y' = x
となります。
逆回転の場合は sin(-90度) = -1、cos(-90度)=0なので
x' = y
y' = -x
となります。
なでしこ3では複数変数への代入文が使えるので このように書けます。
x,y = [-y, x] //回転する(右回転)
回転、かんたんですね!
複数変数への代入文について(v3.2.6以降) なでしこさん マニュアル - 文法/代入文
実例
T字ブロックの状態0は[[0,0],[1,0],[-1,0],[ 0,-1]]。
右回転すると状態1の座標[[0,0],[0,1],[0,-1],[1,0]になるはず。
なでしこ3で式を入れて確認してみましょう。
[[0,0],[1,0],[-1,0],[ 0,-1]]を反復
x,y = 対象
x,y= [-y,x]
[x,y]を表示
ここまで
座標[[0,0],[0,1],[0,-1],[1,0]が表示されました!
SRSに対応する回転式
テトリス99やぷよぷよテトリスなどでは、床についたT字ブロックを右回転すると、壁際に立ちます。
このとき、「ブロックは[0,-1]を中心に回転した」はずです。
中心が[0,0]でない場合、「回転の中心」を引いて、回転して、「回転の中心」を足します。
これをプログラムしてみます。
中心X,中心Y=[0,-1]
[[0,0],[1,0],[-1,0],[ 0,-1]]を反復
x,y = 対象
x,y = [x-中心X,y-中心Y] //中心を引く
x,y = [-y,x] //回転する(右回転)
x,y = [x+中心X,y+中心Y] //中心を足す
[x,y]を表示
ここまで
実行結果は[[-1,-1],[-1,0],[-1,-2],[0,-1]]を示しています。 これで合ってます!
Tスピントリプルの回転
Tスピントリプルの場合も中心が違うだけです。
右回転によるTスピントリプルの回転中心は[-1.5,0.5]です。
(ブロックの中心が[0,0]なので、角は0.5ずれた座標になります)
回転の中心座標テーブルを用意する
ブロックを回転した時に衝突判定をして、なにかにぶつかったら別の回転中心を使います。
[0,0]で右回転してダメだったら[-0.5,-0.5]、そこもだめなら[0,-1]、[-1,1]、[-1.5,0.5]の順に回転の中心を変更して衝突判定します。
上記の座標は「T字ブロックが、状態0から、右回転するとき」の座標です。
この座標は、ブロック種類と状態と回転方向で変わりますから、座標をテーブルでもつ必要があります。
※ 間違いがあればお気軽にコメント欄でおねがいします
※ テトリスちゃんねるさんの図には間違いがあります
これで美しい残像をもったTスピントリプルが描画できそうです。