見出し画像

【Unity C#】キャンディークラッシュ風マッチ3パズルの作り方 #7 タイル交換下準備

このレクチャーでは
タイル交換用の関数の定義
をやっていきます



タイル交換用の変数を追加

まずはMatchPuzzleSceneDirectorのGameMode gameMode変数の下に
タイル交換に関する変数を定義します。

GameMode gameMode;

// 交換するタイルのインデックス
Vector2Int swapIndexA;
Vector2Int swapIndexB;
// 押したワールドの場所
Vector2 touchDownPoint;
// 押したフラグ
bool isTouchDown;

解説

タッチモードで使うタイル交換用の変数の定義になります。

// 交換するタイルのインデックス
Vector2Int swapIndexA;
Vector2Int swapIndexB;

交換する2つのタイルデータのインデックスになります。
Aが最初に押したタイルのインデックスで、Bが離した時のタイルのインデックスになります。

// 押したワールドの場所
Vector2 touchDownPoint;

押した場所のポイントを保存する変数になります。
この変数と、離した場所との差分を計算して、上下左右どの場所のタイルと交換するかを決定します。

// 押したフラグ
bool isTouchDown;

押した時にこのフラグを立てて、離したときにこのフラグを落とします。

ワールド座標をインデックスに変換する関数

// ワールド座標をインデックス座標に変換
Vector2Int WorldToIndexPosition(Vector2 position)
{
    Vector2Int index = new Vector2Int();

    float x = position.x - 0.5f + fieldWidth / 2.0f;
    float y = position.y - 0.5f + fieldHeight / 2.0f;

    index.x = (int)x;
    index.y = (int)y;

    return index;
}

解説

こちらは【#3 タイルを1つだけ生成】のレクチャーの

インデックス座標をワールド座標に変換する関数
の逆をやっている関数になります。


タイルデータを入れかえる関数

// 2つのタイルデータを入れかえる(視覚的なポジションの移動はしない)
bool SwapTileDatas(Vector2Int indexA, Vector2Int indexB)
{
    // 配列外
    if (IsOutOfRange(indexA.x, indexA.y) || IsOutOfRange(indexB.x, indexB.y)) return false;
    // 同じ場所
    if (indexA == indexB) return false;

    // データを入れかえる
    TileController tmpTile = fieldTiles[indexA.x, indexA.y];
    fieldTiles[indexA.x, indexA.y] = fieldTiles[indexB.x, indexB.y];
    fieldTiles[indexB.x, indexB.y] = tmpTile;

    return true;
}

解説

この関数は、AとB2つのタイルのデータのみを入れ替えるためのものです。
入れ替えはタイルの内部データのみであり、タイルがゲーム画面上でどこに表示されるかの移動は行いません。
戻り値は入れ替えが成功したかどうかを返します。

引数の
Vector2Int indexA, indexBは入れ替えたいタイルデータのインデックスの位置になります。

    // 配列外
    if (IsOutOfRange(indexA.x, indexA.y) || IsOutOfRange(indexB.x, indexB.y)) return false;

まず、指定された2つのインデックスが
ゲームフィールドの範囲内にあるかをチェックします。
もしどちらかが範囲外であれば、関数は false を返して終了します。
これにより、無効なインデックスによるエラーを防ぐことができます。

    // 同じ場所
    if (indexA == indexB) return false;

次に、2つのインデックスが異なることを確認します。
もし同じ位置であれば、入れ替える必要がないので
この場合も関数は false を返して終了します。

TileController tmpTile = fieldTiles[indexA.x, indexA.y];
fieldTiles[indexA.x, indexA.y] = fieldTiles[indexB.x, indexB.y];
fieldTiles[indexB.x, indexB.y] = tmpTile;

これらの行で実際のデータの入れ替えを行っています。
まず tmpTile に indexA の位置にあるタイルを一時的に保存します。
その後、indexA の位置に indexB のタイルを移動し、最後に tmpTile に保存していたタイルを indexB の位置に移動します。

最後に、入れ替えが成功したということで true を返します。


タイルデータとポジションを入れかえる関数

// 2つのタイルデータとポジションを入れかえる
void SwapTiles(Vector2Int indexA, Vector2Int indexB)
{
    // 内部データを交換
    bool isSwapTileDatas = SwapTileDatas(indexA, indexB);

    // 交換できなかった(配列外 or 同じ場所)
    if (!isSwapTileDatas) return;

    // 視覚的に移動
    fieldTiles[indexA.x, indexA.y].SwapMove(fieldTiles[indexB.x, indexB.y].transform.position);
    fieldTiles[indexB.x, indexB.y].SwapMove(fieldTiles[indexA.x, indexA.y].transform.position);
}

解説

ここから先は

1,824字 / 1画像

全てのアセットを含む有料記事・マガジンが読み放題です。

スタンダードプラン

¥500 / 月

この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?