落ちモノパズル スーパーローテーションの実装
あいさつ
どうも、はかせです。
今回はテトリスのスーパーローテーションの実装が出来たと思うので
(私の技量が足りずちゃんとした検証が出来ない・・・)
それについてです。
スーパーローテーションとは?
テトリミノを回転させるとき壁や他のピースにぶつかりできないときがあります。
そうなったとき回転軸をずらすことでプレイヤーがスムーズに直感的に操作できるようにする機能です。
この機能のロジックはなにやらテトリスのバージョンだとかで変わるらしく
実装に関してはいろんな方法があるようです。
実装方法
まずはざっくりと流れを。
①テトリミノの形を取得
②回転前と後の回転状態を取得
③①と②で取得したデータをもとに回転軸の移動量を計算
④計算した移動量分移動させて重複チェック
⑤重複していなければ確定、していたら計算しなおして④から
①と②はテトリミノにそれぞれの情報を公開させて取得しました。
③はこの記事の最後にある参考サイトをもとに計算しました。
④は既に作ってある移動メソッドに計算結果を渡してるだけです。
⑤はそのままですが、都度コントローラー側で判定して
メソッドキックするのもなんか気に食わなかったので
再起処理を使って実装しています。
//回転軸の移動量計算 //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