Unity中利用C#開發泡泡龍游戲

泡泡龍是一款非常經典的遊戲,版本有很多,如百度的《彩色泡泡》等。遊戲開始時,泡泡應該出現m行;如果連續n次發射泡泡沒有出現同色泡泡相消的情況,在屏幕上方自動加上一行泡泡;如果屏幕中泡泡全部被同色相消掉,則過關;如果屏幕中泡泡行數達到max行,則認爲闖關失敗。

開發軟件: Unity

開發語言: C#

對一些數據的定義及封裝:

<pre class="csharp" name="code">public  const int MaxRow = 11;     //泡泡所在位置的最大行
	public  const int MaxColumn = 9;   //泡泡所在位置的最大列

	public  int RowNum=8;     //初始化時產生氣泡 行數
	public  int ColumnNum = 9;//初始化時產生氣泡 列數

	public GameObject[] BubblePrefab; //預製對象數組

	public  struct BubbleClass        //bubble 結構體
	{
		public GameObject BubbleObj; //實例化的對象
		public int type;             //泡泡類型   如果顏色不同,則也認爲類型不同
		public Vector3 position;     // 泡泡位置
		public bool  IsDestroy;      //當前位置的泡泡是否被銷燬    如果當前位置的泡泡被銷燬,則認爲當前位置空閒,可以容納發射的泡泡
		public int   Life;           //不同類型的泡泡生命值不同 
		public bool  Isconnection; //true表示與第一排相連   false表示不與第一排小泡相連
	}
	
	public  BubbleClass[,] BubbleArray;        //屏幕中MaxRow*MaxColumn格中泡泡數組
	public  BubbleClass    BubbleCurrentShoot; //當前要發射的泡泡
	public  BubbleClass    BubbleNextShoot;    //下一次要發射的泡泡
	public  float          BubbleMoveSpeed=5f; //小球移動速度
	public  float          CircleRadius=0.24f;//小泡半徑
	
	private int NextNum=-1;    //發射球下一次標號     
	private int CurrentNum=-1; //發射球當前標號     
	private Vector3 NextPoint=new Vector3(-1.4f,-3.8f,0f); //下一個小泡發射位置 new Vector3(1.2f,-3.7f,0f)
	private Vector3 StartPoint=new Vector3(0.026f,-3.65f,0f); //小泡發射起點位置 new Vector3(0f,-3.6f,0f)

	public enum BState{READY,FLY,FINISH};//待發射小泡的三種狀態 發射前(準備態),運動中, 完成態
	public BState BubbleState;
//	private int BubblePrefabLength=0;
	public bool BubbleInitFlag=false;

	public float HorizontalStartX = -3.0f;       //開始點X -1.75
	public float VerticalStartY=3.0f;             //開始點Y
	public float HorizontalDistance=0.5f;         //水平小泡之間間距
	public float VerticalDistance=0.45f;          //豎直小泡之間間距
	public float HorizontalIdentitationDis=0.25f; //水平右縮進距離

	public bool IdentitationFlag=false; //true代表 0,2,4,6,8,10爲縮進,1,3,5,7,9爲不縮進  false則相反

	public int CurrentRowCount=0; //當前屏幕中氣泡行數

	//設計共10關 
	public  int GameLevel=1;         //遊戲難度等級   
	public int BubbleKindsCount=4; //當前等級下的小泡種類
	private GameObject[] BubbleCurrentPrefab; //當前難度等級下的小泡預製對象數組

	public bool StartFlag=false; //開始標誌
	public GameObject Menu; //菜單對象
	public int ShootBubbleCount=0; //發射小泡數
	public int Score=0;
	public UILabel LabelPoint;
	public int BubbleScore=10; //打掉一個氣泡的得分

	public int BubbleBoudary=0;//連續幾次沒打中,則加一排小泡


 

涉及的主要步驟有:

(1)泡泡的產生。

初始屏幕泡泡的產生,相鄰兩行泡泡需要交錯,才能形成完整的正六邊形。主要代碼:

//隨機在屏幕上方方格產生氣泡  初始化時調用此函數
	public void InitProduceScreenBubble()
	{
		int flagBubble = -1;
		for(int i=0;i<RowNum;i++)
		{
			if(i==0)
			{
			 flagBubble=Random.Range(0,2);//產生0,1數  0爲這排氣泡最左邊氣泡抵牆,1爲此排氣泡整體右縮進
			}
			else
			{
				if(flagBubble==0)
				{
					flagBubble=1;
				}
				else
				{
					flagBubble=0;
				}

			}
			for(int j=0;j<ColumnNum;j++)
			{
				float x1;
				if(i==0)   //第一排小泡
				{
					if(flagBubble==0)
					{
						x1=HorizontalStartX+HorizontalDistance*j;
						IdentitationFlag=false;
					}
					else
					{
						x1=HorizontalStartX+HorizontalDistance*j+HorizontalIdentitationDis;
						IdentitationFlag=true;
					}

				}
				else  //其它排小泡
				{
					if(flagBubble==0)
					{
						x1=HorizontalStartX+HorizontalDistance*j;
					}
					else 
					{
						x1=HorizontalStartX+HorizontalDistance*j+HorizontalIdentitationDis;
					}
				}
				int temp=Random.Range(0,BubbleKindsCount); //爲類型標號
				float x2=VerticalStartY-VerticalDistance*i;
				Vector3 tposition= new Vector3(x1,x2,0f);
				GameObject obj2=GameObject.Instantiate(BubblePrefab[temp],tposition,Quaternion.identity) as GameObject;
				BubbleArray[i,j].BubbleObj=obj2;
				BubbleArray[i,j].IsDestroy=false;
				BubbleArray[i,j].Life=1;
				BubbleArray[i,j].position=tposition;
				BubbleArray[i,j].type=temp;
				BubbleArray[i,j].Isconnection=true;
			}
		}
	}


發射小泡的產生:

	//隨機在下方產生當前和下一次要發射的小泡
	public void ProduceBubbleBottom()
	{
		if((CurrentNum==-1)&&(NextNum==-1))  //說明遊戲剛開始
		{
			int m1 = Random.Range (0, BubbleKindsCount);
			int m2 = Random.Range (0, BubbleKindsCount);
			CurrentNum=m1;
			NextNum=m2;
			GameObject obj1=GameObject.Instantiate(BubblePrefab[m1],StartPoint,Quaternion.identity) as GameObject;
			GameObject obj2=GameObject.Instantiate(BubblePrefab[m2],NextPoint,Quaternion.identity) as GameObject;
			InitBubbleCurrent(obj1,m1,StartPoint,false,1);
			InitBubbleNext(obj2,m2,NextPoint,false,1);
			BubbleState=BState.READY;
		}
		else //如果遊戲進行中
		{
			CurrentNum=NextNum;
			BubbleCurrentShoot.BubbleObj=BubbleNextShoot.BubbleObj;
			BubbleCurrentShoot.IsDestroy=BubbleNextShoot.IsDestroy;
			BubbleCurrentShoot.Life=BubbleNextShoot.Life;
			BubbleCurrentShoot.type=BubbleNextShoot.type;
			BubbleCurrentShoot.BubbleObj.transform.position=StartPoint;
			BubbleCurrentShoot.position=StartPoint;

			int m2 = Random.Range (0, BubbleKindsCount);
			GameObject obj2=GameObject.Instantiate(BubblePrefab[m2],NextPoint,Quaternion.identity) as GameObject;
			InitBubbleNext(obj2,m2,NextPoint,false,1);
			NextNum=m2;
			BubbleState=BState.READY;
		}

	}


發射小泡的運動:將發射小泡添加Rigidbody屬性,去掉重力,設置其速度Velocity(矢量)即可實現運動。

	//氣泡發射函數
	void BubbleShoot()
	{
		//如果鼠標左擊
		if(Input.GetMouseButton(0))
		{
			//UICamera.mainCamera.ScreenToWorldPoint
			Vector3 currentPosition = BubbleCurrentShoot.position ;
			Vector3 moveToward = Camera.main.ScreenToWorldPoint( Input.mousePosition );
			Vector3 moveDirection = moveToward - currentPosition;
			moveDirection.z = 0; 
			moveDirection=moveDirection.normalized;
			Vector2 Direction=new Vector2(moveDirection.x,moveDirection.y);
			BubbleCurrentShoot.BubbleObj.rigidbody2D.velocity=Direction.normalized*BubbleMoveSpeed;
			//BubbleState==BState.FLY;  //小泡發射後就變爲運動態
			BubbleState=BState.FLY;
		}
	}


(2) 發射小泡的碰撞檢測

a. 發射小泡碰撞到左右屏幕邊界,則需要反向彈回。

發射小泡從AO射入,則從OB射出,且OB與X同OA與X的夾角是相同的。檢測方法,則在屏幕左右邊緣加上“線碰撞器”,當發射小泡碰撞線碰撞器時,進入碰撞函數,改變發射小泡的速度方向即可。

void OnTriggerEnter2D(Collider2D collision)
	{
		//屏幕邊界碰撞檢測
		if(maincontrol.BubbleInitFlag)
		{
			if(collision.gameObject==maincontrol.BubbleCurrentShoot.BubbleObj)
			{
				Vector2 tp = collision.gameObject.rigidbody2D.velocity;
				tp=new Vector2(-tp.x,tp.y);
				collision.gameObject.rigidbody2D.velocity= tp.normalized*maincontrol.BubbleMoveSpeed;
			}
		}
	}


 

b.發射小泡與屏幕中小泡碰撞

屏幕中的小泡以及發射小泡都是預製(Prefab)對象實例化而得到的。因而在的=建立預製對象時,就給預製對象加上組件”Circle Collider 2D",圓形2D碰撞器,爲了去掉物理特性碰撞,選擇“IsTrigger" ,這是爲了避免小泡被撞飛。 注意: Unity 中要實現碰撞,務必保證碰撞物體和被撞物體兩者中至少有一個具有剛體屬性。

//小泡碰撞檢測函數
	void OnTriggerEnter2D(Collider2D collision)
	{
		if(maincontrol.StartFlag==true)
		{
		//如果當前氣泡就是發射氣泡
		if(maincontrol.BubbleInitFlag)
		{
			if(collision.gameObject==maincontrol.BubbleCurrentShoot.BubbleObj)
			{
					maincontrol.ShootBubbleCount++;
				Vector2 tp = collision.gameObject.rigidbody2D.velocity;
				collision.gameObject.rigidbody2D.velocity= tp.normalized*0f;
				//調整發射小泡的位置
				ShootBubblePosition(gameObject);
				//Debug.Log ("行號:" + bbPosition.rown+"列號:" + bbPosition.columnn);


				Count=0;
				InitBubbleSameType();
				//delete []BubbleSameType;
				BubbleSameType[Count].obj=maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].BubbleObj;
				BubbleSameType[Count].rowNum=bbPosition.rown;
				BubbleSameType[Count].ColumnNum=bbPosition.columnn;
				Count++;
				CountBubble(maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].BubbleObj,maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].type);
	
				if(Count>=3)
				{
						maincontrol.ShootBubbleCount=0;
					int r=FindMinRow(); //找出顏色相同氣泡中最小行號
					for(int i=0;i<Count;i++)
					{
						GameObject CrackObj=GameObject.Instantiate(BubbleCrackPrefab,BubbleSameType[i].obj.transform.position,Quaternion.identity) as GameObject;
						Destroy(CrackObj,1f);
						Destroy(BubbleSameType[i].obj);

						int k1=BubbleSameType[i].rowNum;
						int k2=BubbleSameType[i].ColumnNum;
						maincontrol.BubbleArray[k1,k2].BubbleObj=null;
						maincontrol.BubbleArray[k1,k2].IsDestroy=true;
						maincontrol.BubbleArray[k1,k2].Life=0;
						maincontrol.BubbleArray[k1,k2].type=-1;
						maincontrol.BubbleArray[k1,k2].Isconnection=false;
					}
					//Debug.Log(Count);
					maincontrol.Score+=Count*maincontrol.BubbleScore;   
					Count=0;
					InitBubbleSameType();
					QueryBubbleSuspended(r);//清除懸空氣泡
					if(Count>=1)
					{
						
						for(int i=0;i<Count;i++)
						{
							Destroy(BubbleSameType[i].obj);
							int k1=BubbleSameType[i].rowNum;
							int k2=BubbleSameType[i].ColumnNum;
							maincontrol.BubbleArray[k1,k2].BubbleObj=null;
							maincontrol.BubbleArray[k1,k2].IsDestroy=true;
							maincontrol.BubbleArray[k1,k2].Life=0;
							maincontrol.BubbleArray[k1,k2].type=-1;
							maincontrol.BubbleArray[k1,k2].Isconnection=false;
						}
						//Debug.Log(Count);
					} 
				  maincontrol.Score+=Count*maincontrol.BubbleScore;   

				} else
				{
						//連續3次沒打中想銷燬
						if(maincontrol.ShootBubbleCount==maincontrol.BubbleBoudary)
						{
							Vector3 pp=maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].position;
							pp.y=tp.y-maincontrol.VerticalDistance;

							maincontrol.BubbleArray[bbPosition.rown+1,bbPosition.columnn].BubbleObj=	maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].BubbleObj;
							maincontrol.BubbleArray[bbPosition.rown+1,bbPosition.columnn].BubbleObj.transform.position=pp; 
							maincontrol.BubbleArray[bbPosition.rown+1,bbPosition.columnn].position=pp;
							maincontrol.BubbleArray[bbPosition.rown+1,bbPosition.columnn].IsDestroy=	maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].IsDestroy;
							maincontrol.BubbleArray[bbPosition.rown+1,bbPosition.columnn].Life=	maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].Life;
							maincontrol.BubbleArray[bbPosition.rown+1,bbPosition.columnn].type=	maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].type;
							maincontrol.BubbleArray[bbPosition.rown+1,bbPosition.columnn].Isconnection=	maincontrol.BubbleArray[bbPosition.rown,bbPosition.columnn].Isconnection;
							
						}

				}

				
				Count=0;
				InitBubbleSameType();
				maincontrol.BubbleCurrentShoot.BubbleObj=null;
				maincontrol.BubbleCurrentShoot.IsDestroy=true;
				maincontrol.BubbleCurrentShoot.position=new Vector3(0f,0f,0f);
				maincontrol.BubbleCurrentShoot.type=-1;
				maincontrol.BubbleState=MainControl.BState.FINISH;
				maincontrol.BubbleCurrentShoot.Isconnection=false;

			}
		  }
		}
	}


 

(3)發射泡泡運動停止後的位置確定

下圖綠色爲被撞泡泡,以其爲中心的六邊形如下:圖片來源:http://blog.csdn.net/luchenqun/article/details/8393879

根據碰撞函數可以得到被碰小泡(上面綠色)的座標,根據它,可以得出其周圍六個頂點小泡的位置 (假設都有小泡),再根據 

public  BubbleClass[,] BubbleArray;

數組(記錄了屏幕中所有泡泡信息),判斷六個位置是否有泡泡,根據發射小泡入射角度和六邊形角度範圍,給出發射小泡的位置。

//計算當前被撞小泡的位置  即當前小泡對象  obj爲發射小泡碰撞的小泡
	void ShootBubblePosition(GameObject obj)
	{
		int row=0, column=0;
		bool isIdentitation=false;
		GeneralBubblePosition (ref row, ref column,obj.transform.position); //
		if(maincontrol.IdentitationFlag)
		{
			if(row%2==0)
			{
				isIdentitation=true;
			}
			else
			{
				isIdentitation=false;
			}
		}
		else
		{
			if(row%2==0)
			{
				isIdentitation=false;
			}
			else
			{
				isIdentitation=true;
			}
		}
//		int Currenttype=maincontrol.BubbleArray[row,column].type;

		bool Ichange = false; //判斷obj小泡周圍是否有同顏色的小泡(重複的不算)
//		float pbegin,pbegin1;
	//	float pend,pend1;
		int LeftUpNum, LeftDownNum, RightUpNum, RightDownNum;

		Vector3 tp = maincontrol.BubbleCurrentShoot.BubbleObj.transform.position - obj.transform.position;
		tp.z = 0f;
		tp = tp.normalized;
		float angle=0f;
		if((tp.x>-0.00001f)&&(tp.x<=0.00001f))
		{
			if(tp.y>=0)
			{
				angle=90f;
			}
			else
			{
				angle=-90f;
			}
			
		}
		else
		{
			
			if(tp.x>0f) 
			{
				if(tp.y>=0f)//第一象限
				{
					angle=Mathf.Atan(tp.y/tp.x)*Mathf.Rad2Deg;
				}else  //第四象限
				{
					angle=Mathf.Atan(tp.y/tp.x)*Mathf.Rad2Deg;
				}
			}
			else
			{
				if(tp.y>=0f)//第二象限
				{
					angle=180f+Mathf.Atan(tp.y/tp.x)*Mathf.Rad2Deg;
				}else  //第三象限
				{
					angle=-180f+Mathf.Atan(tp.y/tp.x)*Mathf.Rad2Deg;
				}
			}
			
		}
		if(isIdentitation) //如果當前行縮進
		{
			//pbegin=PStartx;  //當前氣泡的左右氣泡肯定縮進
			//pend=PEndx;
			
			//pbegin1=PStartx0;//當前氣泡的左上、左下、右上、右下氣泡肯定不縮進
			//pend1=PEndx0;
			
			LeftUpNum=column;
			RightUpNum=column+1;
			LeftDownNum=column;
			RightDownNum=column+1;
			
		}
		else
		{
			//pbegin=PStartx0; //當前氣泡的左右氣泡肯定不縮進
			//pend=PEndx0;
			
			//pbegin1=PStartx;//當前氣泡的左上、左下、右上、右下氣泡肯定縮進
			//pend1=PEndx;
			
			LeftUpNum=column-1;
			RightUpNum=column;
			LeftDownNum=column-1;
			RightDownNum=column;
		}

		//直接計算位置   obj爲中心的六邊形定點位置
		Vector3 Left = new Vector3 (obj.transform.position.x - maincontrol.HorizontalDistance, obj.transform.position.y, obj.transform.position.z);
		Vector3 Right = new Vector3 (obj.transform.position.x + maincontrol.HorizontalDistance, obj.transform.position.y, obj.transform.position.z);

		Vector3 LeftUp = new Vector3 (obj.transform.position.x - maincontrol.HorizontalIdentitationDis, obj.transform.position.y+maincontrol.VerticalDistance, obj.transform.position.z);
		Vector3 RightUp = new Vector3 (obj.transform.position.x + maincontrol.HorizontalIdentitationDis, obj.transform.position.y+maincontrol.VerticalDistance, obj.transform.position.z);
		Vector3 LeftDown = new Vector3 (obj.transform.position.x - maincontrol.HorizontalIdentitationDis, obj.transform.position.y-maincontrol.VerticalDistance, obj.transform.position.z);
		Vector3 RightDown = new Vector3 (obj.transform.position.x + maincontrol.HorizontalIdentitationDis, obj.transform.position.y-maincontrol.VerticalDistance, obj.transform.position.z);



		//if((Left.x>=pbegin)&&(Left.x<=pend))
		//{
		if((column-1)>=0)
		{
			if(maincontrol.BubbleArray[row,column-1].BubbleObj==null)
			{
				if(((angle>=-180f)&&(angle<-150f))||((angle>=150f)&&(angle<180f)))
				{
					BoundaryDeal(Left,row,column-1);
					return ;
				}
			}
		}
		//}
		//if((Right.x>=pbegin)&&(Right.x<=pend))
		//{
		if((column+1)<=(MainControl.MaxColumn-1))
		{
			if(maincontrol.BubbleArray[row,column+1].BubbleObj==null)
			{
				if((angle>=-30f)&&(angle<30f))
				{
					BoundaryDeal(Right,row,column+1);
					return ;
				}
			}
		}	
		//}
		
		
		//if((LeftUp.x>=pbegin1)&&(LeftUp.x<=pend1)&&(LeftUp.y>=PEndy)&&(LeftUp.y<=PStarty)) //上一行沒有縮進
		//{

		if(((row-1)>=0)&&(LeftUpNum>=0)&&(LeftUpNum<=(MainControl.MaxColumn-1)))
		{
			if(maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj==null)
			{
				if((angle>90f)&&(angle<=150f))
				{
					BoundaryDeal(LeftUp,row-1,LeftUpNum);
					return ;
				}
			}
		}
		//}
		
		//if((RightUp.x>=pbegin1)&&(RightUp.x<=pend1)&&(RightUp.y>=PEndy)&&(RightUp.y<=PStarty)) //上一行沒有縮進
		//{
		if(((row-1)>=0)&&(RightUpNum>=0)&&(RightUpNum<=(MainControl.MaxColumn-1)))
		{
			if(maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj==null)
			{

				if((angle>=30f)&&(angle<90f))
				{
					BoundaryDeal(RightUp,row-1,RightUpNum);
					return ;
				}
			}
		}
		//}
		
		
		//if((LeftDown.x>=pbegin1)&&(LeftDown.x<=pend1)&&(LeftDown.y>=PEndy)&&(LeftDown.y<=PStarty)) //下一行沒有縮進
		//{
		if(((row+1)<=(MainControl.MaxRow-1))&&(LeftDownNum>=0)&&(LeftDownNum<=(MainControl.MaxColumn-1)))
		{
			if(maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj==null)
			{

				if((angle>=-150f)&&(angle<-90f))
				{
					BoundaryDeal(LeftDown,row+1,LeftDownNum);
					return ;
				}else if((column==0)&&(angle>=-180f)&&(angle<-90f)&&isIdentitation)
				{
					BoundaryDeal(LeftDown,row+1,LeftDownNum);
				}

			}
		}
		//}
		
		//if((RightDown.x>=pbegin1)&&(RightDown.x<=pend1)&&(RightDown.y>=PEndy)&&(RightDown.y<=PStarty)) //下一行沒有縮進
		//{
		if(((row+1)<=(MainControl.MaxRow-1))&&(RightDownNum>=0)&&(RightDownNum<=(MainControl.MaxColumn-1)))
		{
			if(maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj==null)
			{
				if((angle>=-90f)&&(angle<-30f))
				{
					BoundaryDeal(RightDown,row+1,RightDownNum);
					return ;
				}
			}
		}
		//}



		//如果都不屬於   默認處理
		if(!Ichange)
		{
			if(isIdentitation) //如果當前行縮進
			{
				if(((angle>=-180f)&&(angle<-150f))||((angle>=150f)&&(angle<180f)))//left
				{
					if(column==0)
					{
						BoundaryDeal(LeftUp,row-1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(Left,row,column-1);
						return ;
					}
				}else if((angle>=-30f)&&(angle<30f)) //right
				{
					if(column==0)
					{
						BoundaryDeal(Right,row,column+1);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(LeftDown,row+1,column);
						return ;
					}
				}
				else if((angle>90f)&&(angle<=150f)) //LeftUp
				{
					if(column==0)
					{
						BoundaryDeal(LeftUp,row-1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(LeftUp,row-1,column);
						return ;
					}
				}
				else if((angle>=30f)&&(angle<90f))//rightup
				{
					if(column==0)
					{
						BoundaryDeal(RightUp,row-1,column+1);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(LeftUp,row-1,column);
						return ;
					}
				}
				else if((angle>=-150f)&&(angle<-90f))//leftdown
				{
					if(column==0)
					{
						BoundaryDeal(LeftDown,row+1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(LeftDown,row+1,column);
						return ;
					}
				}
				else if((angle>=-90f)&&(angle<-30f))//rightdown
				{
					if(column==0)
					{
						BoundaryDeal(RightDown,row+1,column+1);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(LeftDown,row+1,column);
						return ;
					}
				}
			}
			else
			{
				if(((angle>=-180f)&&(angle<-150f))||((angle>=150f)&&(angle<180f)))//left
				{
					if(column==0)
					{
						BoundaryDeal(RightUp,row-1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(Left,row,column-1);
						return ;
					}
				}else if((angle>=-30f)&&(angle<30f)) //right
				{
					if(column==0)
					{
						BoundaryDeal(Right,row,column+1);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(RightDown,row+1,column);
						return ;
					}
				}
				else if((angle>90f)&&(angle<=150f)) //LeftUp
				{
					if(column==0)
					{
						BoundaryDeal(RightUp,row-1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(LeftUp,row-1,column-1);
						return ;
					}
				}
				else if((angle>=30f)&&(angle<90f))//rightup
				{
					if(column==0)
					{
						BoundaryDeal(RightUp,row-1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(RightUp,row-1,column);
						return ;
					}
				}
				else if((angle>=-150f)&&(angle<-90f))//leftdown
				{
					if(column==0)
					{
						BoundaryDeal(RightDown,row+1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(LeftDown,row+1,column-1);
						return ;
					}
				}
				else if((angle>=-90f)&&(angle<-30f))//rightdown
				{
					if(column==0)
					{
						BoundaryDeal(RightDown,row+1,column);
						return ;
					}
					if(column==MainControl.MaxColumn)
					{
						BoundaryDeal(RightDown,row+1,column);
						return ;
					}
				}
			}

		}

	}


(4)同色小泡有3個以上,小泡相消(包含發射小泡)

核心:計算同色小泡數目以及記錄同色小泡信息

//找出與小泡obj同色且相連的小泡  type包含顏色   當前小泡碰撞了發射小泡
	public void CountBubble(GameObject obj,int type)
	{
		int row=0, column=0;
		bool isIdentitation=false;

		GeneralBubblePosition (ref row, ref column,obj.transform.position); //
		int Currenttype=maincontrol.BubbleArray[row,column].type;
		if(maincontrol.IdentitationFlag)
		{
			if(row%2==0)
			{
				isIdentitation=true;
			}
			else
			{
				isIdentitation=false;
			}
		}
		else
		{
			if(row%2==0)
			{
				isIdentitation=false;
			}
			else
			{
				isIdentitation=true;
			}
		}
		//直接計算位置   obj爲中心的六邊形定點位置
		/*
		Vector3 Left = new Vector3 (obj.transform.position.x - maincontrol.HorizontalDistance, obj.transform.position.y, obj.transform.position.z);
		Vector3 Right = new Vector3 (obj.transform.position.x + maincontrol.HorizontalDistance, obj.transform.position.y, obj.transform.position.z);
		Vector3 LeftUp = new Vector3 (obj.transform.position.x - maincontrol.HorizontalIdentitationDis, obj.transform.position.y+maincontrol.VerticalDistance, obj.transform.position.z);
		Vector3 RightUp = new Vector3 (obj.transform.position.x + maincontrol.HorizontalIdentitationDis, obj.transform.position.y+maincontrol.VerticalDistance, obj.transform.position.z);
		Vector3 LeftDown = new Vector3 (obj.transform.position.x - maincontrol.HorizontalIdentitationDis, obj.transform.position.y-maincontrol.VerticalDistance, obj.transform.position.z);
		Vector3 RightDown = new Vector3 (obj.transform.position.x + maincontrol.HorizontalIdentitationDis, obj.transform.position.y-maincontrol.VerticalDistance, obj.transform.position.z);
           */
		bool Ichange = false; //判斷obj小泡周圍是否有同顏色的小泡(重複的不算)
//		float pbegin,pbegin1;
	//	float pend,pend1;
		int LeftUpNum, LeftDownNum, RightUpNum, RightDownNum;

		if(isIdentitation) //如果當前行縮進
		{
			//pbegin=PStartx;  //當前氣泡的左右氣泡肯定縮進
			//pend=PEndx;

			//pbegin1=PStartx0;//當前氣泡的左上、左下、右上、右下氣泡肯定不縮進
			//pend1=PEndx0;

			LeftUpNum=column;
			RightUpNum=column+1;
			LeftDownNum=column;
			RightDownNum=column+1;

		}
		else
		{
			//pbegin=PStartx0; //當前氣泡的左右氣泡肯定不縮進
			//pend=PEndx0;

			//pbegin1=PStartx;//當前氣泡的左上、左下、右上、右下氣泡肯定縮進
			//pend1=PEndx;

			LeftUpNum=column-1;
			RightUpNum=column;
			LeftDownNum=column-1;
			RightDownNum=column;
		}

		//if((Left.x>=pbegin)&&(Left.x<=pend))
			//{
		if((column-1)>=0)
		{
				if(maincontrol.BubbleArray[row,column-1].BubbleObj!=null)
				{
					if(Currenttype==maincontrol.BubbleArray[row,column-1].type) //如果類型相同
					{
						if(!IsExistInArray(maincontrol.BubbleArray[row,column-1].BubbleObj)) //如果原數組中不存在
						{
						 Ichange=true;
						 BubbleSameType[Count].obj=maincontrol.BubbleArray[row,column-1].BubbleObj;
						 BubbleSameType[Count].rowNum=row;
						 BubbleSameType[Count].ColumnNum=column-1;
						 Count++;
						 CountBubble(maincontrol.BubbleArray[row,column-1].BubbleObj,Currenttype); //遞歸調用
						}
					}
				}
		}
				
			//}
		  //if((Right.x>=pbegin)&&(Right.x<=pend))
		//	{

		if((column+1)<=(MainControl.MaxColumn-1))
		{
				if(maincontrol.BubbleArray[row,column+1].BubbleObj!=null)
				{
					if(Currenttype==maincontrol.BubbleArray[row,column+1].type) //如果類型相同
					{
						if(!IsExistInArray(maincontrol.BubbleArray[row,column+1].BubbleObj))//如果原數組中不存在
						{
						 Ichange=true;
						 BubbleSameType[Count].obj=maincontrol.BubbleArray[row,column+1].BubbleObj;
						 BubbleSameType[Count].rowNum=row;
						 BubbleSameType[Count].ColumnNum=column+1;
						 Count++;
						 CountBubble(maincontrol.BubbleArray[row,column+1].BubbleObj,Currenttype); //遞歸調用
						}
					}
				}
		}	
		//	}


		//if((LeftUp.x>=pbegin1)&&(LeftUp.x<=pend1)&&(LeftUp.y>=PEndy)&&(LeftUp.y<=PStarty)) //上一行沒有縮進
		//	{
		if(((row-1)>=0)&&(LeftUpNum>=0)&&(LeftUpNum<=(MainControl.MaxColumn-1)))
		{
			if(maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj!=null)
				{
				if(Currenttype==maincontrol.BubbleArray[row-1,LeftUpNum].type) //如果類型相同
					{
					if(!IsExistInArray(maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj))//如果原數組中不存在
						{
						    Ichange=true;
						    BubbleSameType[Count].obj=maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj;
						    BubbleSameType[Count].rowNum=row-1;
						    BubbleSameType[Count].ColumnNum=LeftUpNum;
						    Count++;
						    CountBubble(maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj,Currenttype); //遞歸調用
						}
					}
				}
		}
		//	}

	//	if((RightUp.x>=pbegin1)&&(RightUp.x<=pend1)&&(RightUp.y>=PEndy)&&(RightUp.y<=PStarty)) //上一行沒有縮進
		//	{
		if(((row-1)>=0)&&(RightUpNum>=0)&&(RightUpNum<=(MainControl.MaxColumn-1)))
		{
				if(maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj!=null)
				{
				if(Currenttype==maincontrol.BubbleArray[row-1,RightUpNum].type) //如果類型相同
					{
					if(!IsExistInArray(maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj))//如果原數組中不存在
						{
						    Ichange=true;
						    BubbleSameType[Count].obj=maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj;
						    BubbleSameType[Count].rowNum=row-1;
						    BubbleSameType[Count].ColumnNum=RightUpNum;
						    Count++;
						    CountBubble(maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj,Currenttype); //遞歸調用
						}
					}
				}
		}
			//}


		//if((LeftDown.x>=pbegin1)&&(LeftDown.x<=pend1)&&(LeftDown.y>=PEndy)&&(LeftDown.y<=PStarty)) //下一行沒有縮進
			//{
		if(((row+1)<=(MainControl.MaxRow-1))&&(LeftDownNum>=0)&&(LeftDownNum<=(MainControl.MaxColumn-1)))
		{
			if(maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj!=null)
				{
				if(Currenttype==maincontrol.BubbleArray[row+1,LeftDownNum].type) //如果類型相同
					{
					if(!IsExistInArray(maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj))//如果原數組中不存在
						{
						    Ichange=true;
						    BubbleSameType[Count].obj=maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj;
						    BubbleSameType[Count].rowNum=row+1;
						    BubbleSameType[Count].ColumnNum=LeftDownNum;
						    Count++;
						    CountBubble(maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj,Currenttype); //遞歸調用
						}
					}
				}
		}
			//}

		//if((RightDown.x>=pbegin1)&&(RightDown.x<=pend1)&&(RightDown.y>=PEndy)&&(RightDown.y<=PStarty)) //下一行沒有縮進
		//	{
		if(((row+1)<=(MainControl.MaxRow-1))&&(RightDownNum>=0)&&(RightDownNum<=(MainControl.MaxColumn-1)))
		{
			if(maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj!=null)
				{
				if(Currenttype==maincontrol.BubbleArray[row+1,RightDownNum].type) //如果類型相同
					{
					if(!IsExistInArray(maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj))//如果原數組中不存在
						{
						    Ichange=true;
						    BubbleSameType[Count].obj=maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj;
						    BubbleSameType[Count].rowNum=row+1;
						    BubbleSameType[Count].ColumnNum=RightDownNum;
						    Count++;
						    CountBubble(maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj,Currenttype); //遞歸調用
						}
					}
				}
		}
			//}

		if (Ichange == false)
		{
						return;
		}
	}


 

(5)泡泡掉落(主要判斷泡泡是否直接或間接與屏幕中第一行的泡泡相連)

如果沒有相連(即泡泡懸空),泡泡會自然掉落(也需要消去)。

// 查詢整個屏幕中懸浮氣泡
	void QueryBubbleSuspended(int row)
	{
		for(int i=row;i<MainControl.MaxRow;i++)
		{
			if(IsRowHaveEmpty(i))
			{
				for(int j=0;j<MainControl.MaxColumn;j++)
				{
					if((!maincontrol.BubbleArray[i,j].IsDestroy)&&(maincontrol.BubbleArray[i,j].BubbleObj!=null)) //如果當前位置有小泡
					{
						connectionCount=0;
						InitConnectionPathObj();
						if(IsConnection(maincontrol.BubbleArray[i,j].BubbleObj)) //如果當前小泡與第一排直接或間接相連
						{

						}
						else  //如果當前小泡爲孤立小泡(沒有與第一排的小泡友直接或間接相連)
						{
							if(!IsExistInArray(maincontrol.BubbleArray[i,j].BubbleObj))//如果原數組中不存在
							{
							  BubbleSameType[Count].obj=maincontrol.BubbleArray[i,j].BubbleObj;
							  BubbleSameType[Count].rowNum=i;
							  BubbleSameType[Count].ColumnNum=j;
							  maincontrol.BubbleArray[i,j].Isconnection=false;
							  Count++;
							}
						}
					}
				}
			}
		}
	}

	//一行中所有小泡位置是否有空
	bool IsRowHaveEmpty(int row)
	{
		for(int j=0;j<MainControl.MaxColumn;j++)
		{ 
			if(maincontrol.BubbleArray[row,j].IsDestroy==true) //如果有空 所在位置的氣泡被消滅
			{
				return true;
			}
		}
		return false;
	}
	
	//遞歸查詢一個氣泡obj是否與上一層想連接
	//1-6 分別代表調用IsConnection的obj爲當前obj的Left,Right,LeftUp,RightUp,LeftDown,RightDown 0表示初始調用
	bool  IsConnection(GameObject obj)
	{
		int row=0, column=0;
		bool isIdentitation=false;
		GeneralBubblePosition (ref row, ref column,obj.transform.position);

		ConnectionPathObj[connectionCount++] = obj;
		//如果obj已經處於第一排  則返回
		if(row==0)
		{
			return true;
		}
		/*
		if(row<r)
		{
			if(maincontrol.BubbleArray[row,column].Isconnection)
			{
				return true;
			}
			else
			{
				//去除路徑不通的小泡
				if(connectionCount>0)
				{
					connectionCount--;
					ConnectionPathObj [connectionCount] = null;
				}
				return false;
			}
		}
		*/

		if(maincontrol.IdentitationFlag)
		{
			if(row%2==0)
			{
				isIdentitation=true;
			}
			else
			{
				isIdentitation=false;
			}
		}
		else
		{
			if(row%2==0)
			{
				isIdentitation=false;
			}
			else
			{
				isIdentitation=true;
			}
		}
		//bool BoolConnection = false; //判斷obj小泡周圍是否有同顏色的小泡(重複的不算)
//		float pbegin,pbegin1;
	//	float pend,pend1;
		int LeftUpNum, LeftDownNum, RightUpNum, RightDownNum;
		
		if(isIdentitation) //如果當前行縮進
		{
			//pbegin=PStartx;  //當前氣泡的左右氣泡肯定縮進
			//pend=PEndx;
			
			//pbegin1=PStartx0;//當前氣泡的左上、左下、右上、右下氣泡肯定不縮進
			//pend1=PEndx0;
			
			LeftUpNum=column;
			RightUpNum=column+1;
			LeftDownNum=column;
			RightDownNum=column+1;
		}
		else
		{
			//pbegin=PStartx0; //當前氣泡的左右氣泡肯定不縮進
			//pend=PEndx0;
			
			//pbegin1=PStartx;//當前氣泡的左上、左下、右上、右下氣泡肯定縮進
			//pend1=PEndx;
			
			LeftUpNum=column-1;
			RightUpNum=column;
			LeftDownNum=column-1;
			RightDownNum=column;
		}


			if(((column-1)>=0))    //Left
			{
				if(maincontrol.BubbleArray[row,column-1].BubbleObj!=null)
				{

					if(!IsInConnectionPathObj(maincontrol.BubbleArray[row,column-1].BubbleObj))
					{
						if(IsConnection(maincontrol.BubbleArray[row,column-1].BubbleObj)) //遞歸調用
						{
							return true; 
						}
					}
				}
			}
			if((column+1)<=(MainControl.MaxColumn-1)) //Right
			{
				if(maincontrol.BubbleArray[row,column+1].BubbleObj!=null)
				{
				   if(!IsInConnectionPathObj(maincontrol.BubbleArray[row,column+1].BubbleObj))
					{
						if(IsConnection(maincontrol.BubbleArray[row,column+1].BubbleObj)) //遞歸調用
						{
							return true; 
						}
					}
				}
			}	
			if(((row-1)>=0)&&(LeftUpNum>=0)&&(LeftUpNum<=(MainControl.MaxColumn-1))) //LeftUp
			{
				if(maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj!=null)
				{
				if(!IsInConnectionPathObj(maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj))
					{
						if(IsConnection(maincontrol.BubbleArray[row-1,LeftUpNum].BubbleObj)) //遞歸調用
						{
							return true; 
						}
					}
				}
			}
			if(((row-1)>=0)&&(RightUpNum>=0)&&(RightUpNum<=(MainControl.MaxColumn-1))) //RightUp
			{
				if(maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj!=null)
				{
				if(!IsInConnectionPathObj(maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj))
					{
						if(IsConnection(maincontrol.BubbleArray[row-1,RightUpNum].BubbleObj)) //遞歸調用
						{
							return true; 
						}
					}
				}
			}
			if(((row+1)<=(MainControl.MaxRow-1))&&(LeftDownNum>=0)&&(LeftDownNum<=(MainControl.MaxColumn-1))) //LeftDown
			{
				if(maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj!=null)
				{
				if(!IsInConnectionPathObj(maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj))
					{
						if(IsConnection(maincontrol.BubbleArray[row+1,LeftDownNum].BubbleObj))//遞歸調用
						{
							return true; 
						}
					}
				}
			}
			if(((row+1)<=(MainControl.MaxRow-1))&&(RightDownNum>=0)&&(RightDownNum<=(MainControl.MaxColumn-1))) //RightDown
			{
				if(maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj!=null)
				{
				    if(!IsInConnectionPathObj(maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj))
					{
						if(IsConnection(maincontrol.BubbleArray[row+1,RightDownNum].BubbleObj)) //遞歸調用
						{
							return true; 
						}
					}
				}
			}

	    //去除路徑不通的小泡
		if(connectionCount>0)
		{
		  connectionCount--;
		  ConnectionPathObj [connectionCount] = null;
		}
		return false;

	}


 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章