Unity で テトリス風ゲームを作ってみる(実装編)#4
Unity Version 2022.3.4
前回の続き
前回、入力イベントとテトリミノの移動を説明した。今回はテトリミノの回転について実装方法の説明をする。
テトリミノの回転
左右回転キーのAction は、下記のOnTurnLeftEvent とOnTurnRightEvent コールバック関数に割り当てる。左右移動と同様に、InputActionPhase.Started のイベントだけに反応するようにフィルターをかける。左右どちらの回転も結局は回転方向が異なるだけで、処理自体は同一のため、共通の回転関数Rotate を作る。
Tetrimino.cs の抜粋(左右回転キーイベントコールバック)
- public void OnTurnLeftEvent (InputAction.CallbackContext context) {
- if (IsOperatable() && context.phase == InputActionPhase.Started) {
- Rotate(90);
- }
- }
- public void OnTurnRightEvent (InputAction.CallbackContext context) {
- if (IsOperatable() && context.phase == InputActionPhase.Started) {
- Rotate(-90);
- }
- }
Rotate 関数は回転角を引数で受け取り、現在の回転角と足して、回転角ごとのenum 値に変換する。enum 値に変換するのはブロック座標配列のIndex に変換する必要があるため。Tetriminio.Type と Tetrimino.Rotation から回転後の4 つのブロックの座標を配列から取得し(BlockPosition 関数)、それぞれのポジションに対して他のブロックがないかを確認する(CollisioinChek 関数)。他のブロックがなければ、回転角をメンバ_rotation に保存して、回転後の位置に各ブロックを移動する(LocateBlocks 関数)
Tetrimino.cs の抜粋(左右回転)
- public void Rotate (int degree) {
- var rotation = RotateAngle(_rotation, degree);
- var positions = BlocksPosition(_type, rotation);
- foreach (var pos in positions)
- if (CollisionCheck(this.transform.position + new Vector3(pos.x, pos.y, 0))) return;
- _rotation = rotation;
- LocateBlocks();
- }
- private Rotation RotateAngle (Rotation rotation, int degree) {
- var deg = degree % 360;
- var rot = ((int)rotation * 90 + deg);
- if (rot < 0) rot = 360 + rot;
- rot = rot / 90;
- switch (rot) {
- case 0:
- return Rotation.R0;
- case 1:
- return Rotation.R90;
- case 2:
- return Rotation.R180;
- case 3:
- return Rotation.R270;
- default:
- return Rotation.R0;
- }
- }
- private bool CollisionCheck (Vector2 position) {
- var hitResult = new List<RaycastHit2D>();
- var start = position;
- var length = 0.1f;
- var direct = Vector2.down;
- var hitCount = Physics2D.Raycast(
- start, // レイの原点
- direct, // レイの方向
- _contactFilter, // チェックする対象を設定するフィルター
- hitResult, // ヒットしたオブジェクトの情報
- length // レイの長さ
- );
- //Debug.DrawRay(start, direct * length, Color.blue, 1f); // Debug用
- return (hitCount > 0)? true : false;
- }
- public List<GameObject> GetBlocks() {
- return _blockPrefabs;
- }
以上でテトリミノの回転は終了。考え方は左右移動とほぼ同じで、移動するか回転するかの違いだけ。
次の記事