Unity3d开发“类三消”游戏
新建一个Project,导入图片素材和声音文件,把图片的Texture Type都修改为Sprite(2D and UI)【1】。新建一个命名为Background的GameObject,为之添加背景素材图片【2】。再新建一个命名为GameController的GameObject,为之添加GameController脚本和AudioSource组件。把消除素材图片都做成预设体(Prefabs)【3】,顺便再Copy多一个预设体,重命名为Gemstone,把Sprite设为空(None),为之添加Gemstone脚本和BoxCollider组件。
【1】 【3】
【2】
GameController.sc脚本
1 using System.Collections; 2 3 public class GameController : MonoBehaviour { 4 public Gemstone gemstone; 5 public int rowNum=7;//宝石列数 6 public int columNum=10;//宝石行数 7 public ArrayList gemstoneList;//定义列表 8 private Gemstone currentGemstone; 9 private ArrayList matchesGemstone; 10 public AudioClip match3Clip; 11 public AudioClip swapClip; 12 public AudioClip erroeClip; 13 // Use this for initialization 14 void Start () { 15 gemstoneList = new ArrayList ();//新建列表 16 matchesGemstone = new ArrayList (); 17 for (int rowIndex=0; rowIndex<rowNum; rowIndex++) { 18 ArrayList temp=new ArrayList(); 19 for(int columIndex=0;columIndex<columNum;columIndex++){ 20 Gemstone c=AddGemstone(rowIndex,columIndex); 21 temp.Add(c); 22 23 } 24 gemstoneList.Add(temp); 25 } 26 if (CheckHorizontalMatches () || CheckVerticalMatches ()) {//开始检测匹配消除 27 RemoveMatches(); 28 } 29 } 30 public Gemstone AddGemstone(int rowIndex,int columIndex){//生成宝石 31 Gemstone c = Instantiate (gemstone)as Gemstone; 32 c.transform.parent = this.transform;//生成宝石为GameController子物体 33 c.GetComponent<Gemstone>().RandomCreateGemstoneBg(); 34 c.GetComponent<Gemstone>().UpdatePosition(rowIndex,columIndex); 35 return c; 36 } 37 38 // Update is called once per frame 39 void Update () { 40 41 } 42 public void Select(Gemstone c){ 43 //Destroy (c.gameObject); 44 if (currentGemstone == null) { 45 currentGemstone = c; 46 currentGemstone.isSelected=true; 47 return; 48 } else { 49 if(Mathf.Abs(currentGemstone.rowIndex-c.rowIndex)+Mathf.Abs(currentGemstone.columIndex-c.columIndex)==1){ 50 //ExangeAndMatches(currentGemstone,c); 51 StartCoroutine(ExangeAndMatches(currentGemstone,c)); 52 }else{ 53 this.gameObject.GetComponent<AudioSource>().PlayOneShot(erroeClip); 54 } 55 currentGemstone.isSelected=false; 56 currentGemstone=null; 57 } 58 } 59 IEnumerator ExangeAndMatches(Gemstone c1,Gemstone c2){//实现宝石交换并且检测匹配消除 60 Exchange(c1,c2); 61 yield return new WaitForSeconds (0.5f); 62 if (CheckHorizontalMatches () || CheckVerticalMatches ()) { 63 RemoveMatches (); 64 } else { 65 Exchange(c1,c2); 66 } 67 } 68 bool CheckHorizontalMatches(){//实现检测水平方向的匹配 69 bool isMatches = false; 70 for (int rowIndex=0; rowIndex<rowNum; rowIndex++) { 71 for (int columIndex=0; columIndex<columNum-2; columIndex++) { 72 if ((GetGemstone (rowIndex, columIndex).gemstoneType == GetGemstone (rowIndex, columIndex + 1).gemstoneType) && (GetGemstone (rowIndex, columIndex).gemstoneType == GetGemstone (rowIndex, columIndex + 2).gemstoneType)) { 73 //Debug.Log ("发现行相同的宝石"); 74 AddMatches(GetGemstone(rowIndex,columIndex)); 75 AddMatches(GetGemstone(rowIndex,columIndex+1)); 76 AddMatches(GetGemstone(rowIndex,columIndex+2)); 77 isMatches = true; 78 } 79 } 80 } 81 return isMatches; 82 } 83 bool CheckVerticalMatches(){//实现检测垂直方向的匹配 84 bool isMatches = false; 85 for (int columIndex=0; columIndex<columNum; columIndex++) { 86 for (int rowIndex=0; rowIndex<rowNum-2; rowIndex++) { 87 if ((GetGemstone (rowIndex, columIndex).gemstoneType == GetGemstone (rowIndex + 1, columIndex).gemstoneType) && (GetGemstone (rowIndex, columIndex).gemstoneType == GetGemstone (rowIndex + 2, columIndex).gemstoneType)) { 88 //Debug.Log("发现列相同的宝石"); 89 AddMatches(GetGemstone(rowIndex,columIndex)); 90 AddMatches(GetGemstone(rowIndex+1,columIndex)); 91 AddMatches(GetGemstone(rowIndex+2,columIndex)); 92 isMatches=true; 93 } 94 } 95 } 96 return isMatches; 97 } 98 void AddMatches(Gemstone c){ 99 if (matchesGemstone == null) 100 matchesGemstone = new ArrayList (); 101 int Index = matchesGemstone.IndexOf (c);//检测宝石是否已在数组当中 102 if (Index == -1) { 103 matchesGemstone.Add(c); 104 } 105 } 106 void RemoveMatches(){//删除匹配的宝石 107 for (int i=0; i<matchesGemstone.Count; i++) { 108 Gemstone c=matchesGemstone[i]as Gemstone; 109 RemoveGemstone(c); 110 } 111 matchesGemstone = new ArrayList (); 112 StartCoroutine (WaitForCheckMatchesAgain ()); 113 } 114 IEnumerator WaitForCheckMatchesAgain(){//连续检测匹配消除 115 yield return new WaitForSeconds (0.5f); 116 if (CheckHorizontalMatches () || CheckVerticalMatches ()) { 117 RemoveMatches(); 118 } 119 } 120 void RemoveGemstone(Gemstone c){//删除宝石 121 //Debug.Log("删除宝石"); 122 c.Dispose (); 123 this.gameObject.GetComponent<AudioSource> ().PlayOneShot (match3Clip); 124 for (int i=c.rowIndex+1; i<rowNum; i++) { 125 Gemstone temGemstone=GetGemstone(i,c.columIndex); 126 temGemstone.rowIndex--; 127 SetGemstone(temGemstone.rowIndex,temGemstone.columIndex,temGemstone); 128 //temGemstone.UpdatePosition(temGemstone.rowIndex,temGemstone.columIndex); 129 temGemstone.TweenToPostion(temGemstone.rowIndex,temGemstone.columIndex); 130 } 131 Gemstone newGemstone = AddGemstone (rowNum, c.columIndex); 132 newGemstone.rowIndex--; 133 SetGemstone (newGemstone.rowIndex, newGemstone.columIndex, newGemstone); 134 //newGemstone.UpdatePosition (newGemstone.rowIndex, newGemstone.columIndex); 135 newGemstone.TweenToPostion (newGemstone.rowIndex, newGemstone.columIndex); 136 } 137 public Gemstone GetGemstone(int rowIndex,int columIndex){//通过行号和列号,获取对应位置的宝石 138 ArrayList temp = gemstoneList [rowIndex]as ArrayList; 139 Gemstone c = temp [columIndex]as Gemstone; 140 return c; 141 } 142 public void SetGemstone(int rowIndex,int columIndex,Gemstone c){//设置所对应行号和列号的宝石 143 ArrayList temp = gemstoneList [rowIndex]as ArrayList; 144 temp [columIndex] = c; 145 } 146 public void Exchange(Gemstone c1,Gemstone c2){//实现宝石交换位置 147 this.gameObject.GetComponent<AudioSource> ().PlayOneShot (swapClip); 148 SetGemstone (c1.rowIndex, c1.columIndex, c2); 149 SetGemstone (c2.rowIndex, c2.columIndex, c1); 150 //交换c1,c2的行号 151 int tempRowIndex; 152 tempRowIndex = c1.rowIndex; 153 c1.rowIndex = c2.rowIndex; 154 c2.rowIndex = tempRowIndex; 155 //交换c1,c2的列号 156 int tempColumIndex; 157 tempColumIndex = c1.columIndex; 158 c1.columIndex = c2.columIndex; 159 c2.columIndex = tempColumIndex; 160 161 //c1.UpdatePosition (c1.rowIndex, c1.columIndex); 162 //c2.UpdatePosition (c2.rowIndex, c2.columIndex); 163 c1.TweenToPostion (c1.rowIndex, c1.columIndex); 164 c2.TweenToPostion (c2.rowIndex, c2.columIndex); 165 }
为GameController添加声音源文件和Gemstone脚本
Gemstone.cs脚本
1 using System.Collections; 2 3 public class Gemstone : MonoBehaviour { 4 5 public float xOffset = -4.5f;//x方向的偏移 6 public float yOffset = -2.0f;//y方向的偏移 7 public int rowIndex = 0; 8 public int columIndex = 0; 9 public GameObject[] gemstoneBgs;//宝石数组 10 public int gemstoneType;//宝石类型 11 private GameObject gemstoneBg; 12 private GameController gameController; 13 private SpriteRenderer spriteRenderer; 14 public bool isSelected{ 15 set{ 16 if(value){ 17 spriteRenderer.color=Color.red; 18 }else{ 19 spriteRenderer.color=Color.white; 20 } 21 } 22 } 23 // Use this for initialization 24 void Start () { 25 gameController = GameObject.Find ("GameController").GetComponent<GameController> (); 26 spriteRenderer = gemstoneBg.GetComponent<SpriteRenderer> (); 27 } 28 29 // Update is called once per frame 30 void Update () { 31 32 } 33 public void UpdatePosition(int _rowIndex,int _columIndex){//宝石的位置 34 rowIndex = _rowIndex; 35 columIndex = _columIndex; 36 this.transform.position = new Vector3 (columIndex + xOffset, rowIndex + yOffset, 0); 37 } 38 public void TweenToPostion(int _rowIndex,int _columIndex){//调用iTween插件实现宝石滑动效果 39 rowIndex = _rowIndex; 40 columIndex = _columIndex; 41 iTween.MoveTo (this.gameObject, iTween.Hash ("x", columIndex + xOffset, "y", rowIndex + yOffset, "time", 0.5f)); 42 } 43 public void RandomCreateGemstoneBg(){//随机的宝石类型 44 if (gemstoneBg != null) 45 return; 46 gemstoneType = Random.Range (0, gemstoneBgs.Length); 47 gemstoneBg = Instantiate (gemstoneBgs [gemstoneType])as GameObject; 48 gemstoneBg.transform.parent = this.transform; 49 } 50 public void OnMouseDown(){ 51 gameController.Select (this); 52 } 53 public void Dispose(){ 54 Destroy (this.gameObject); 55 Destroy (gemstoneBg.gameObject); 56 gameController = null; 57 }
为Gemstone预设体添加消除素材图片
最后在MainCamera添加AudioSource组件来播放背景音乐
运行效果