はかせのラボ

私の頭の中を書いていく雑記ブログです

落ちモノパズル スーパーローテーションの実装

あいさつ

どうも、はかせです。
今回はテトリススーパーローテーションの実装が出来たと思うので
(私の技量が足りずちゃんとした検証が出来ない・・・)
それについてです。

スーパーローテーションとは?

テトリミノを回転させるとき壁や他のピースにぶつかりできないときがあります。
そうなったとき回転軸をずらすことでプレイヤーがスムーズに直感的に操作できるようにする機能です。
この機能のロジックはなにやらテトリスのバージョンだとかで変わるらしく
実装に関してはいろんな方法があるようです。

実装方法

まずはざっくりと流れを。
①テトリミノの形を取得
②回転前と後の回転状態を取得
③①と②で取得したデータをもとに回転軸の移動量を計算
④計算した移動量分移動させて重複チェック
⑤重複していなければ確定、していたら計算しなおして④から

①と②はテトリミノにそれぞれの情報を公開させて取得しました。
③はこの記事の最後にある参考サイトをもとに計算しました。
④は既に作ってある移動メソッドに計算結果を渡してるだけです。
⑤はそのままですが、都度コントローラー側で判定して
メソッドキックするのもなんか気に食わなかったので
再起処理を使って実装しています。

//回転軸の移動量計算
//switch分とif分の暴力で長いためブログでは省略
if(mTetriMinoType == I)
{
//Iテトリミノの計算
}
else 
{
//Iテトリミノ以外の計算
}
//移動出来たらtrue mMovePosition = 計算した移動量
if (mTetriMino->MoveTetriMinoSafe(mMovePosition.x, mMovePosition.y)) return true;
//出来ずにスーパーローテーション判定が終わればfalse
else if (mSuperRotationState == Four) return false;
//スーパーローテーション判定が残っていれば次の判定へ
else return IsSuperRotationCheck(preState, state);

スーパーローテーションは1~4の段階で判定する実装が多いそうなので
私もそれに倣ってみました。

あとがき

今回はスーパーローテーションの実装をしてみたという話でした。
実際この機能がスーパーローテーションとしてちゃんと動くのか
私の技量不足で確認が完全には取れていませんorz
でも壁際で回転できたのできっと出来てると思っています・・・

また今回はIテトリミノのスーパーローテーション
実装はまだ出来ていません。
というのもこのIテトリミノのスーパーローテーションには
枠の端まで行くみたいな処理があるのですが、
私のプログラムでは枠というものは概念からしてありません。

もちろんケースバイケースで全ての値を決め打ちで作れば実装できますが、
何かうまい方法はないものかと考えています。

それでは今回はこの辺でノシ

今回作ったものはgithubに上げました
github.com