【Unity】2048ピース移動の実装(その1)

2019/10/18修正


前回、フラフラになりながら移動処理を考えました(;´・`)> ふぅ
修正が多くて申し訳ないです。

今回は、移動処理を実装して行きたいのですが、
いきなり実装はできないので、準備をしていきます。


ポジション毎のピースのナンバーが必要になるので、
管理用のオブジェクトとスクリプトを用意します。
2048㉑.jpg
続いて、GameManagerスクリプトを編集します。

GameManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{

public static int[,] SetNum=new int [4,4]; //ピースNo管理用変数
private bool[,] Flag = new bool[4, 4]; //ポジション毎のピースの有無

// Start is called before the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{

}

//停止中のピースのポジション取得
public void FlagOn(int x,int y,int p)
{
SetNum[y, x] = p;
Flag[y, x] = true;
}

//移動時にピース情報を消去
public void FlagOff(int x,int y,int p)
{
SetNum[y, x] = 0;
Flag[y, x] = false;
}


配列変数を二つ用意しました。
一つはピースNoを管理するSetNum
一つはポジションのピースの有無を確認するFlag

SetNumは各ピースからも見えるようにする為、staticにしています。

ピースが停止した時にポジションを更新、
移動時にデータを消去する為、二つのメソッドを用意。


続いて、PieceManagerを編集します。

PieceManager


private GameManager gameManager; //ゲームマネージャーの取得変数
public int PieceNo; //ピースの識別番号

private int[] Position = { -150, -50, 50, 150 }; //X座標変数
private int[] RePosition = { 150, 50, -50, -150 }; //Y座標変数

private int[] AxisX = new int[4]; //横列のピース配置
private int[] AxisY = new int[4]; //縦列のピース配置


変数の修正と追加をします。

ピースNoを追加して各ピースに設定します。
座標変数は、Positionを用意していましたが、
上下に移動する際、座標が反転するので逆座標を追加。

最後にピースのポジションからX軸、Y軸それぞれに配置される
ピースNoを取り出す変数を用意しました。


// Start is called before the first frame update
void Start()
{
GameObject gamemanager = GameObject.Find("GameManager");
gameManager = gamemanager.GetComponent<GameManager>();

transform = GetComponent<RectTransform>();

PosNo(transform.localPosition.x, transform.localPosition.y);
gameManager.FlagOn(LineX, LineY, PieceNo);
}


まず、GameManagerをFindしてキャッシュしておきます。
続いて、ゲーム開始時やピース生成時に初期配置を登録できるように
しておきます。


//移動前のピース配置
void GetAxis()
{
for (int i = 0; i < 4; i++)
{
AxisX[i] = GameManager.SetNum[LineY, i];
AxisY[i] = GameManager.SetNum[i, LineX];
}
}

追加したAxisXとAxisYに横・縦並びのピース配置を取得する関数を用意します。
この取得した配置を元に移動処理の計算を行います。

わざわざAxis変数を用意して取得しなくても、
SetNumから直に値を引き出せば使えるのでは?となるんですが、

これには訳があります。
説明するのに少し流れを見てください。


マウス操作
・フリック方向の判定
・配置から移動マスの計算
・移動開始とポジションの消去
・移動完了とポジションの登録


処理の流れは、こんな感じになります。
ここで問題があります。

複数ピースが有る場合、
個々のピースで計算時間の誤差があると言う事です。

移動開始と同時に移動前のポジションが消去される為、
処理が少し遅れたピースは、SetNumの値が更新されているので、
計算が狂ってしまいます。

なので、ピースの移動が始まる前に配置をメモリ
しておく必要があります。

void Update()
{
if (Move)
{
return;
}
//タッチの始点を取得
if (Input.GetKeyDown(KeyCode.Mouse0))
{
touchStartPos = new Vector3(Input.mousePosition.x,
Input.mousePosition.y,
Input.mousePosition.z);
//移動前のピース配置取得
GetAxis();
}
//タッチの終点を取得
if (Input.GetKeyUp(KeyCode.Mouse0))
{
touchEndPos = new Vector3(Input.mousePosition.x,
Input.mousePosition.y,
Input.mousePosition.z);
GetDirection();
}
}


GetAxisメソッドを呼び出すタイミングですが、
いろいろと試した所、タッチ開始時が安定するので、
Input.GetKeyDownの所で呼び出す事にしました。

移動処理は4方向分の長編なので、
このまま書くと、とんでもない事になりそうな…

次回まとめたいと思います。
(o・・o)/~マタネェ


追記
タッチの終点を取得するメッソドに
実験で使用したメソッドが残っていました。

不必要なので削除しました。申し訳ありません。
(_ _(--;(_ _(--; pekopeko

この記事へのコメント