*

[Unity]Unity2Dチュートリアル 番外編 これパズドラじゃなくね?

公開日: : 最終更新日:2014/12/07 C#, Unity, ソース

前回の続き。
パズドラみたく直線で3つ以上連なっているときに消したいんです。

そして、何を勘違いしたのか、3つ以上直線で連続で連なっているときに、それに隣接している同色も消去する、というロジックを作ってしまいました。
パズドラ+ぷよぷよして悪いとこ取りしたみたいな。

要件定義失敗です。

一応、この謎いソースも乗っけておきます……。

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

public class GameSystem : MonoBehaviour {
	private const int TileLineNum = 5;
	private const int TileColNum = 6;
	private const float TileWidth = 0.5f;
	private const float TileHeight = 0.5f;
	private const float FirstTilePosX = -1.5f;
	private const float FirstTilePosY = -2;
	private int[,] tileTable = new int[TileLineNum,TileColNum];

	public GameObject holdObj;
	public float holdPositionX;
	public float holdPositionY;
	private float z = 10f;
	private GameObject[,] tileSet;
	
	// Use this for initialization
	void Start () {
		SetTileSet();

	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetMouseButtonDown(0)){
			LeftClick();
		}
		if(Input.GetMouseButton(0)){
			LeftDrag();
		}
		if(Input.GetMouseButtonUp(0)){
			LeftUp();
			DeleteMatchTile();
		}
	}
	
	private void LeftClick(){
		Vector3 tapPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
		if(holdObj == null){
			Collider2D col = Physics2D.OverlapPoint(Camera.main.ScreenToWorldPoint(tapPoint));
			if(col != null){
				this.holdObj = col.gameObject;
				holdPositionX = this.holdObj.transform.position.x;
				holdPositionY = this.holdObj.transform.position.y;
				holdObj.transform.position = Camera.main.ScreenToWorldPoint(tapPoint);
			}
		}
		
	}
	private void LeftDrag(){
		Vector3 tapPoint = Input.mousePosition;
		if(holdObj != null){
			this.holdObj.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(tapPoint.x, tapPoint.y, z));
			Collider2D[] colSet = Physics2D.OverlapPointAll(Camera.main.ScreenToWorldPoint(new Vector3(tapPoint.x, tapPoint.y, z)));
			if(colSet.Length > 1){
				foreach(Collider2D col in colSet){
					if(!col.gameObject.Equals(this.holdObj)){
						float tmpPositionX = holdPositionX;
						float tmpPositionY = holdPositionY;
						holdPositionX = col.gameObject.transform.position.x;
						holdPositionY = col.gameObject.transform.position.y;
						col.gameObject.transform.position = new Vector3(tmpPositionX, tmpPositionY, z);
					}
				}
			}
		}
	}
	private void LeftUp(){
		if(holdObj != null){
			SetTileSet();
			holdObj.transform.position = new Vector3(holdPositionX, holdPositionY, z);
			holdObj = null;
		}
	}
	private void SetTileSet(){
		GameObject[,] tileSet = new GameObject[TileLineNum,TileColNum];
		for(int i = 0; i < TileLineNum; i++){
			for(int j = 0; j < TileColNum; j++){
				Collider2D col = Physics2D.OverlapPoint(new Vector2(FirstTilePosX + TileWidth * j, FirstTilePosY + TileHeight * i));
				if("tile".Equals(col.tag)){
					tileSet[i,j] = col.gameObject;
				}
			}
		}
		
		this.tileSet = tileSet;
	}

	private void DeleteMatchTile(){
		int cnt = 0;
		for(int i = 0; i < TileLineNum; i++){
			for(int j = 0; j < TileColNum; j++){
				cnt = CompareHorizontal(i, j, cnt);
				cnt = CompareVertical(i, j, cnt);
			}
		}

		DeleteTile();
	}

	private int CompareHorizontal(int i, int j, int cnt){
		if(j + 1 < TileColNum){
			Sprite nowSprite = GetSprite(this.tileSet[i,j]);
			Sprite nextSprite = GetSprite(this.tileSet[i,j+1]);
			if(nowSprite.Equals(nextSprite)){
				if(tileTable[i, j] > 0){
					tileTable[i,j+1] = tileTable[i,j]; 
				}else{
					int cntInTile = ReCompareHorizontal(i, j, nowSprite);
					if(cntInTile > 0){
						tileTable[i,j] = cntInTile;
						tileTable[i,j+1] = cntInTile; 
					}else{
						cnt++;
						tileTable[i,j] = cnt;
						tileTable[i,j+1] = cnt; 
					}
				}
			}
		}
		return cnt;
	}

	private int ReCompareHorizontal(int i, int j, Sprite baseSprite){
		int result = 0; 
		if(j + 1 < TileColNum){
			Sprite nextSprite = GetSprite (this.tileSet[i, j+1]);
			if(baseSprite.Equals(nextSprite)){
				if(tileTable[i,j+1] > 0){
					result = tileTable[i, j+1];
				}else{
					result = ReCompareHorizontal(i, j+1, baseSprite);
				}
			}else{
				result = 0;
			}
		}else{
			result = 0;
		}
		return result;
	}

	private int CompareVertical(int i, int j, int cnt){
		for(int k = 1; i + k < TileLineNum; k++){
			Sprite nowSprite = GetSprite (this.tileSet[i,j]);
			Sprite nextSprite = GetSprite(this.tileSet[i+k,j]);
			if(nowSprite.Equals(nextSprite)){
				if(tileTable[i,j] > 0){
					tileTable[i+k, j] = tileTable[i, j];
				}else{
					cnt++;
					tileTable[i,j] = cnt;
					tileTable[i+k,j] = cnt;
				}
			}else{
				break;
			}
		}

		return cnt;
	}

	private Sprite GetSprite(GameObject obj){
		SpriteRenderer renderer = obj.GetComponent<SpriteRenderer>();
		return renderer.sprite;
	}

	private void DeleteTile(){
		List<int> deleteList = GetDeleteNumList();
		for(int i = 0; i < TileLineNum; i++){
			for(int j = 0; j < TileColNum; j++){
				if(tileTable[i,j] > 0 && deleteList.Contains(tileTable[i,j])){
					Destroy(this.tileSet[i,j]);
				}
			}
		}
	}

	private List<int> GetDeleteNumList(){
		List<int> deleteList = new List<int>();


		for(int i = 0; i < TileLineNum; i++){
			int matchCnt = 1;
			int nowNum = tileTable[i,0];
			for(int j = 1; j < TileColNum; j++){
				if(nowNum != tileTable[i, j]){
					nowNum = tileTable[i, j];
					matchCnt = 1;
				}else if(nowNum > 0){
					matchCnt++;
					if(matchCnt > 2 && !deleteList.Contains(nowNum)){
						deleteList.Add(nowNum);
					}
				}
			}
		}

		for(int i = 0; i < TileColNum; i++){
			int matchCnt = 1;
			int nowNum = tileTable[0, i];
			for(int j = 1; j < TileLineNum; j++){
				if(nowNum != tileTable[j,i]){
					nowNum = tileTable[j,i];
					matchCnt = 1;
				}else if(nowNum > 0){
					matchCnt++;
					if(matchCnt > 2 && !deleteList.Contains(nowNum)){
						deleteList.Add(nowNum);
					}
				}
			}
		}

		return deleteList;
	}
}

一応↓で動きます……。

Unity_
レ点をつけたところが条件を満たしたところです。
条件をみたしたので、それにくっついている同色の○印も消えます。
謎パズル。
ついでに最初の一回だけはパズルを入れ替えてもOKになってます。

何を勘違いしたんだろうか……。

ちゃんと直線で3つ揃った場合に消すのはこちら→[Unity]Unity2Dチュートリアル 直線で3つ同色のパズルを消去する

ad

関連記事

cropped-wannabenote_logo.png

[Unity]Unity4.6 UIチュートリアル Lesson11.UI Mask 日本語要約

Unity関連まとめページはこちら→Unity Unity4.6 UIチュートリアル Less

記事を読む

logo

[C#]XML Serializerで読み書き

XML XMLを触りたいので適当にメモ書き 書き出し using System.IO;

記事を読む

unity

[Unity]コードリファレンス GameObject生成

Unityをまじめに扱う必要が出てきたので、自分用のリファレンスを書いていきます。 適当にボタ

記事を読む

Wannabenote

[Unity]Unity2Dチュートリアル パズルを落下させる。

前回の続き。 とりあえず、パズルが消えたので、パズルを落としましょう。 以下のようにソースを

記事を読む

Unity_

[Unity]Unity4.6 UIチュートリアル Lesson5.UI Text 日本語要約

前回の続き。今回はUI Textについての説明。 とはいえ、さすがにテキストなので、あまり説明

記事を読む

unity ご祝儀

[Unity?]割り切れない関係のためのご祝儀計算シミュレータ

今日、親友が結婚します。 なので、ご祝儀を用意するんですが、相場は3万円ですね。 じゃあ、な

記事を読む

wannabenote

[C#]ポートを使用しているプロセスを特定してAcivateするやつ

ポートからプロセスを特定してAcivateするやつ作りました。 https://github.

記事を読む

instantiate cube unity

[Unity]コードリファレンス GameObjectの複製

GameObjectを複製します。 Object.Instantiate(Object ori

記事を読む

logo

[C#, AS400]列挙体の文字列化&DB2/400にODBC接続

定数をなるべく書きたくないんです。 あとからメンテをするときに複数箇所変更しなくてはいけないから。

記事を読む

cwbx.dll 参照の追加

[C#,AS400]C#でAS400のプログラムCallとコマンドの実行方法。

PCのプログラムからCall AS400のRPGPGMをPCから呼び出ししたいときがあります。

記事を読む

ad

Message

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

ad

  •  Auther;わなび

     「オープン系得意だよね? 俺のPCの調子悪いんだけど」という無茶振りから解き放たれゲームエンジニアに。
    C#とかUnityを扱います。
    Twitterフォロー大歓迎です。
    githubアカウント→wannabenote
  • follow us in feedly
PAGE TOP ↑