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

2019/10/9追記・一部修正


ある程度、準備ができたので、
移動用の計算関数を導入して行こうと思います。

移動の処理は以前作った物を流用するのですが、
Moveがtrueの時に+15のtransformを行っており、

移動するマス数が分かっても、数値を直接入力する事が出来ません。

マス移動をPosition変数から座標を読み取っても、
移動処理を書き直さなくてはダメです。

非常に面倒なので、ここでMathf.Clampを利用したいと思います。

右移動のコマンドを例に
posX = Mathf.Clamp(transform.localPosition.x + 15, Min, Max);

現座標+15が移動スピード
Minが最小座標
Maxが最大座標

設定では、
Min=-150;
Max=150;
としているのですが、

この大小値にマス移動の数値を代入してやります。

例えば、Position0にあるピースが計算で2マス移動すると出た場合、
Max=50;としてやれば、それ以上は動かない事になります。

これを元に移動マスの計算を導入してみます。

まず、
private const float Min = -150; //移動範囲下限
private const float Max = 150; //移動範囲上限
constを外します。

private float Min = -150; //移動範囲下限
private float Max = 150; //移動範囲上限

これで書き換え可能な変数になったので、
移動計算の式を導入します。


まず、右方向への移動を作ってみます。

void DestinationR()
{
int temp = 0;
int pos = 0;

if (LineX<=2)
{
for (int i = 3; LineX<= i; i--)
{
if (AxisX[i] == 0)
{
pos++;
}
else if (AxisX[i] == temp)
{
pos++;
temp = 0;
}
else
{
temp = AxisX[i];
}
}
}

if (pos == 0)
{
PieceCorrection();
}
else
{
Min = Position[0];
Max = Position[LineX + pos];
gameManager.FlagOff(LineX, LineY, PieceNo);
Move = true;
}
}


計算式の説明は以前の記事を参照して下さい。

追加したのは、if(pos==0)~
これは、posが0なら移動無しなのですが、
念の為にポジションを確定する為に設定しています。

posが1以上ならMinとMaxを設定します。
ポジションから座標を取得するのは、Position変数を利用します。

後は、現ポジションの情報を消去して移動開始となります。


ここからは、左上下を順に
左移動

void DestinationL()
{
int temp = 0;
int pos = 0;

if (LineX >= 1)
{
for (int i = 0; LineX >= i; i++)
{
if (AxisX[i] == 0)
{
pos++;
}
else if (AxisX[i] == temp)
{
pos++;
temp = 0;
}
else
{
temp = AxisX[i];
}
}
}

if (pos == 0)
{
PieceCorrection();
}
else
{
Min = Position[LineX-pos];
Max = Position[3];
gameManager.FlagOff(LineX, LineY, PieceNo);
Move = true;
}
}



上移動

void DestinationU()
{
int temp = 0;
int pos = 0;

if (LineY >= 1)
{
for (int i = 0; LineY >= i; i++)
{
if (AxisY[i] == 0)
{
pos++;
}
else if (AxisY[i] == temp)
{
pos++;
temp = 0;
}
else
{
temp = AxisY[i];
}
}
}

if (pos == 0)
{
PieceCorrection();
}
else
{
Min = RePosition[3];
Max = RePosition[LineY-pos];
gameManager.FlagOff(LineX, LineY, PieceNo);
Move = true;
}
}



下移動

void DestinationD()
{
int temp = 0;
int pos = 0;

if (LineY <= 2)
{
for (int i = 3; LineY <= i; i--)
{
if (AxisY[i] == 0)
{
pos++;
}
else if (AxisY[i] == temp)
{
pos++;
temp = 0;
}
else
{
temp = AxisY[i];
}
}
}

if (pos == 0)
{
PieceCorrection();
}
else
{
Min = RePosition[LineY+pos];
Max = RePosition[0];
gameManager.FlagOff(LineX, LineY, PieceNo);
Move = true;
}
}


上下の移動はポジション数と座標が反転するので、
追加した、RePosition変数を使います。

どれも同じ式なので、一つにまとめようと思ったのですが、
分岐が複雑なのと、処理でおかしな動きをした時に原因が分からなくなるので、
敢えて、4つに分けました。

この辺は初心者の限界でっす(~ヘ~;)ウーン

これで、ピース毎に移動計算ができるようになったので、
後は、フリック時に計算関数が呼び出されるようにします。


void GetDirection()
{
float directionX = touchEndPos.x - touchStartPos.x;
float directionY = touchEndPos.y - touchStartPos.y;


if (Mathf.Abs(directionY) < Mathf.Abs(directionX))
{
if (30 < directionX)
{
//右向きにフリック
Direction = "right";
DestinationR();
}
else if (-30 > directionX)
{
//左向きにフリック
Direction = "left";
DestinationL();
}
}
else if (Mathf.Abs(directionX) < Mathf.Abs(directionY))
{
if (30 < directionY)
{
//上向きにフリック
Direction = "up";
DestinationU();
}
else if (-30 > directionY)
{
//下向きのフリック
Direction = "down";
DestinationD();
}
}
else
{
//タッチを検出
return;
}
}


フリック判定のGetDirectionに向きを取得するので、
そこで各関数を呼び出します。

ここまで来れば、ピースは移動するようになっています。

ただ、Moveがfalseにならないので、移動が無限ループします。
なので、移動処理部分を修正します。


void PieceMove()
{
float posX = 0;
float posY = 0;

switch (Direction)
{
case "right":
posX = Mathf.Clamp(transform.localPosition.x + 15, Min, Max);
posY = transform.localPosition.y;
Arrive(posX);
break;
case "left":
posX = Mathf.Clamp(transform.localPosition.x - 15, Min, Max);
posY = transform.localPosition.y;
Arrive(posX);
break;
case "up":
posX = transform.localPosition.x;
posY = Mathf.Clamp(transform.localPosition.y + 15, Min, Max);
Arrive(posY);
break;
case "down":
posX = transform.localPosition.x;
posY = Mathf.Clamp(transform.localPosition.y - 15, Min, Max);
Arrive(posY);
break;
}

transform.localPosition = new Vector3(posX, posY, 0);

if (Move == false)
{
PieceCorrection();
}

void Arrive(float pos)
{
if (pos >= Max || pos <= Min)
{
Move = false;
}
}
}

分かりにくいと思うので、説明すると
Moveがtrueになると繰り返しtransform±15の処理が実行されます。

縦と横では、代入する座標がx、yと変わります。
なので、どちらの座標を計算してるか知る必要があります。

変化してる値を引数に移動上下限に到達したら、
Moveをfalseにするようにしました。

これで、移動処理は完了でっす。
なんとか作る事ができました (T-T )( T-T) ウルウル

ま、コードが汚いとか処理が訳わからないとか聞こえてきそうですが、
初心者と言う事でスルーします (V)O¥O(V) フォフォフォ


さて、移動は出来るようになったのですが、
コラインダーの衝突判定は生きてるので、
このまま動かすとおかしな事に…

衝突判定はピース結合に使うので、消さずに保存しておきます。
次回は、衝突判定を修正していきます。
・・・・・・・・~~~ヽ(^◇^))) ほな、さいなら!




追記
移動の計算処理で
if (pos == 0)
{
PieceCorrection();
return;
}
と書いていましたが、returnがまったく意味がないので削除します。
(_ _(--;(_ _(--; pekopeko

この記事へのコメント