首先在网上找一张棋盘的图片(16x16),导入unity,图片类型设置为Sprite(2D and UI),作为背景;
新建 2D 物体 sprite 在Sprite Render 内的Sprite 中指定之前导入的图片。
通过Scale调整背景的大小 使得边界落子位置能够处在一个较为工整的坐标位置。
创建空物体 GameManager 用于挂载 GameManager。
创建空物体Gird 用于存放棋子。(坐标重置)
创建关于棋子的类 PointItem.cs
棋子类型分为空类型,白,黑。通过调节 color的rgba值来实现,游戏开始所有的棋子都为无色。
该类挂载在棋子预支体上
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using UnityEngine; 5 public enum PointType 6 { 7 Empty, 8 White, 9 Black 10 } 11 12 public class PointItem :MonoBehaviour 13 { 14 PointType pointType; 15 SpriteRenderer sr; 16 public int X, Y; 17 18 void Start() 19 { 20 sr = this.gameObject.GetComponent<SpriteRenderer>(); 21 } 22 23 public PointType PointType 24 { 25 get { return pointType; } 26 set 27 { 28 pointType = value; 29 if (pointType == PointType.White) 30 sr.color = new Color(1, 1, 1, 1); 31 if (pointType == PointType.Black) 32 sr.color = new Color(0, 0, 0, 1); 33 } 34 } 35 36 public PointItem(int x,int y) 37 { 38 this.X = x; 39 this.Y = y; 40 this.pointType = PointType.Empty; 41 } 42 }
预制体的创建只需要用基本图形创建圆形的2d sprite就可以了(初始设置为全透明) 设置好 tag 和 layer 即可
GameManager.cs如下 算法很烂 但是感觉思路应该问题不大
每次落子的时候(先进行横向匹配),先向左遍历,如果左边第一子与落子颜色相同,继续向左遍历,如果左边第二子颜色不同或为空,
则直接判断右边三子(3个)的颜色是否与落子相同,如果相同则落子胜 否则为不胜。
可以理解为左一同,则右三同可胜
左二同,则右二同可胜
。。。
同理可以做出纵向匹配和斜向匹配。(注意好索引溢出的问题就好了)
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { PointItem[,] points; public GameObject go; GameObject gird; private PointType State = PointType.White; void Start () { points = new PointItem[16,16]; gird = GameObject.FindGameObjectWithTag("Gird"); for (int i = 0; i < 16; i++) { for (int j = 0; j < 16; j++) { Vector3 position = new Vector3(-7.5f + Mathf.Floor(j), 7.5f - Mathf.Floor(i), 0f); GameObject goo = Instantiate(go,position,Quaternion.identity); goo.transform.SetParent(gird.transform); PointItem p = goo.transform.GetComponent<PointItem>(); p.X = j; p.Y = i; points[j,i] = p; } } } void Update() { if (Input.GetMouseButtonDown(0)) { //Debug.Log("点击了"); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; PointItem p; if(Physics.Raycast(ray,out hit)) { if (hit.transform.gameObject.tag == "trigger") { p = hit.transform.GetComponent<PointItem>(); Choose(p.X,p.Y); // Debug.Log(new Vector2(p.X, p.Y)); } } } } public void Choose(int x,int y) { if (points[x,y].PointType != PointType.Empty) return; points[x,y].PointType = State; Comfirm(x, y, State); if (State == PointType.White) State = PointType.Black; else State = PointType.White; } public void Comfirm(int x, int y, PointType p) { //横向匹配 if (x - 1 > -1 && points[x - 1, y].PointType == p) { if (x - 2 > -1 && points[x - 2, y].PointType == p) { if (x - 3 > -1 && points[x - 3, y].PointType == p) { if (x - 4 > -1 && points[x - 4, y].PointType == p) { Debug.Log(p + "赢了"); } else if (x + 1 < 16) { if (points[x + 1, y].PointType == p) Debug.Log(p + "赢了"); } } else if (x + 2 < 16) { if (points[x + 1, y].PointType == p && points[x + 2, y].PointType == p) Debug.Log(p + "赢了"); } } else if (x + 3 < 16) { if (points[x + 1, y].PointType == p && points[x + 2, y].PointType == p && points[x + 3, y].PointType == p) Debug.Log(p + "赢了"); } } else if (x + 4 < 16) { if (points[x + 1, y].PointType == p && points[x + 2, y].PointType == p && points[x + 3, y].PointType == p && points[x + 4, y].PointType == p) Debug.Log(p + "赢了"); } //纵向匹配 if (y - 1 > -1 && points[x, y - 1].PointType == p) { if (y - 2 > -1 && points[x, y - 2].PointType == p) { if (y - 3 > -1 && points[x, y - 3].PointType == p) { if (y - 4 > -1 && points[x, y - 4].PointType == p) { Debug.Log(p + "赢了"); } else if (y + 1 < 16) { if (points[x, y + 1].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 2 < 16) { if (points[x, y + 1].PointType == p && points[x, y + 2].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 3 < 16) { if (points[x, y + 1].PointType == p && points[x, y + 2].PointType == p && points[x, y + 3].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 4 < 16) { if (points[x, y + 1].PointType == p && points[x, y + 2].PointType == p && points[x, y + 3].PointType == p && points[x, y + 4].PointType == p) Debug.Log(p + "赢了"); } //左上右下匹配 if (y - 1 > -1 && x - 1 > -1 && points[x - 1, y - 1].PointType == p) { if (y - 2 > -1 && x - 2 > -1 && points[x - 2, y - 2].PointType == p) { if (y - 3 > -1 && x - 3 > -1 && points[x - 3, y - 3].PointType == p) { if (y - 4 > -1 && x - 4 > -1 && points[x - 4, y - 4].PointType == p) { Debug.Log(p + "赢了"); } else if (y + 1 < 16 && x + 1 < 16) { if (points[x + 1, y + 1].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 2 < 16 && x + 2 < 16) { if (points[x + 1, y + 1].PointType == p && points[x + 2, y + 2].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 3 < 16 && x + 3 < 16) { if (points[x + 1, y + 1].PointType == p && points[x + 2, y + 2].PointType == p && points[x + 3, y + 3].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 4 < 16 && x + 4 < 16) { if (points[x + 1, y + 1].PointType == p && points[x + 2, y + 2].PointType == p && points[x + 3, y + 3].PointType == p && points[x + 4, y + 4].PointType == p) Debug.Log(p + "赢了"); } //右上左下匹配 if (y - 1 > -1 && x + 1 < 16 && points[x + 1, y - 1].PointType == p) { if (y - 2 > -1 && x + 2 < 16 && points[x + 2, y - 2].PointType == p) { if (y - 3 > -1 && x + 3 < 16 && points[x + 3, y - 3].PointType == p) { if (y - 4 > -1 && x + 4 < 16 && points[x + 4, y - 4].PointType == p) { Debug.Log(p + "赢了"); } else if (y + 1 < 16 && x - 1 > -1) { if (points[x - 1, y + 1].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 2 < 16 && x - 2 > -1) { if (points[x - 1, y + 1].PointType == p && points[x - 2, y + 2].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 3 < 16 && x - 3 > -1) { if (points[x - 1, y + 1].PointType == p && points[x - 2, y + 2].PointType == p && points[x - 3, y + 3].PointType == p) Debug.Log(p + "赢了"); } } else if (y + 4 < 16 && x - 4 > -1) { if (points[x - 1, y + 1].PointType == p && points[x - 2, y + 2].PointType == p && points[x - 3, y + 3].PointType == p && points[x - 4, y + 4].PointType == p) Debug.Log(p + "赢了"); } } }
算法感觉很笨拙 而且即使前面胜利 后面的if语句还是会执行。
我的解决思路是将这4个匹配做成4个方法里 返回bool值
再通过或运算来得到结果。
不知道还有没有什么更好的办法。
感觉应该有更省事的写法,不知道有没有大神指点一下。