泡泡龍是一款非常經典的遊戲,版本有很多,如百度的《彩色泡泡》等。遊戲開始時,泡泡應該出現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;
}