//移动棋子 public void ChessmanMoveTo() { //AStarFindPath._astar.FindingPath(Selected01, Selected02); //List<GridScr> _path = AStarFindPath._astar.path; GameObject obj = Selected01.chessmanObj.gameObject; Vector3 sele01 = GetGridVector(Selected01); Vector3 sele02 = GetGridVector(Selected02); obj.transform.DOMove(sele02, 0.1f); Selected02.changeParentGrid(Selected01); Selected01.RemoveChessman(); //将选择的网格置为空 Selected01 = null; Selected02 = null; //判断是否可以消除 if (!wipeBall(Selected01)) { //不能消除 //创建新棋子 DropChessman(); NextChessmanCreate(); } }
//随机位置放置棋子 public void DropChessman() { //有足够位置 if (NowChessmanNum < GridTotal - NewChessmanNum) { for (int i = 0; i < NewChessmanNum; i++) //取决于游戏难度(每次产生数) { int weizhi = Random.Range(0, GridTotal); GridScr scr = GridScrTransform[weizhi % MaxRowNum, weizhi / MaxColNum]; if (scr.chessmanObj == null) //网格中没有棋子 { int color = NextGridScrTransform[i].chessmanObj.GetChessmanColor(); //创建新棋子 ChessmanInstant(color, scr); //创建新预览棋子 NextChessmanCreate(); Debug.Log("不重复" + i); } else { i -= 1; //不清楚这里会不会出错 Debug.Log("重复的" + i); } } NowChessmanNum += NewChessmanNum; } else { //无法创建时,游戏结束 GameManager._gameManager.GameOver(); } }
//寻路方法 public void FindingPath(GridScr select01, GridScr select02) { StarScr = select01; EndScr = select02; openSet.Add(StarScr); while (openSet.Count > 0) { GridScr curNode = openSet[0]; for (int i = 0, max = openSet.Count; i < max; i++) { if (openSet[i].fCost <= curNode.fCost && openSet[i].hCost < curNode.hCost) { curNode = openSet[i]; } } openSet.Remove(curNode); closeSet.Add(curNode); //找到目标点 if (curNode == EndScr) { generatePath(StarScr, EndScr); return; } //判断周围节点,选择一个最好的 foreach (var item in getNeibourHood(curNode)) { //如果是墙,或者已经在关闭列表中 if (item.chessmanObj != null || closeSet.Contains(item)) { continue; } //计算当前相邻节点与开始节点的距离 int newCost = curNode.gCost + getDistanceGrid(curNode, item); // 如果距离更小,或者原来不在开始列表中 if (newCost < item.gCost || !openSet.Contains(item)) { // 更新与开始节点的距离 item.gCost = newCost; // 更新与终点的距离 item.hCost = getDistanceGrid(item, EndScr); // 更新父节点为当前选定的节点 item.parent = curNode; // 如果节点是新加入的,将它加入打开列表中 if (!openSet.Contains(item)) { openSet.Add(item); } } } } generatePath(StarScr, null); }
//获取两个节点之间的距离 int getDistanceGrid(GridScr start, GridScr end) { int x = Mathf.Abs(start.Gridx - end.Gridx); int y = Mathf.Abs(start.Gridy + end.Gridy); //曼哈顿估价 return(x * 14 + y * 14); }
//获得网格的三维向量 Vector3 GetGridVector(GridScr scr) { Vector3 vec = new Vector3(); vec.x = scr.Gridx; vec.y = scr.Gridy; return(vec); }
void ChessmanInstant(int color, GridScr scr) { //实例化棋子 GameObject obj = Instantiate(ChessmanObj); scr.chessmanObj.SetChessman(color, obj); obj.transform.parent = scr.gameObject.transform; obj.transform.localPosition = new Vector2(0, 0); }
void NextInstant(int row, GameObject parent) { GameObject obj = Instantiate(GridController._gridcontroller.NextGrid); obj.transform.parent = parent.transform; obj.transform.localPosition = new Vector2(row, 0); GridScr scr = obj.GetComponent <GridScr>(); NextGridScrTransform[row] = scr; }
// 生成路径 void generatePath(GridScr startNode, GridScr endNode) { if (endNode != null) { GridScr temp = endNode; while (temp != startNode) { path.Add(temp); temp = temp.parent; } // 反转路径 path.Reverse(); } }
void GridInstant(int row, int col, GameObject parent) { //实例化网格 GameObject obj = Instantiate(GridObj); obj.transform.parent = parent.transform; obj.transform.localPosition = new Vector2(row, col); //添加到二维网格 GridScr scr = obj.GetComponent <GridScr>(); GridScrTransform[row, col] = scr; scr.SetGrid(row, col); }
//获取周围的网格 public List <GridScr> getNeibourHood(GridScr scr) { List <GridScr> list = new List <GridScr>(); for (int i = -1; i < 1; i++) { for (int j = -1; j < 1; j++) { //是自己则跳过 if (i == 0 && j == 0) { continue; } int x = scr.Gridx + i; int y = scr.Gridy + j; //判断是否过界,未过界则记录在列表中 if (x < GridController._gridcontroller.MaxRowNum && x >= 0 && y < GridController._gridcontroller.MaxColNum && y >= 0) { list.Add(GridController._gridcontroller.GridScrTransform[x, y]); } } } return(list); }
public void changeParentGrid(GridScr scr) { this.chessmanObj = scr.chessmanObj; chessmanObj.transform.parent = this.transform; }
bool wipeBall(GridScr scr) { int x = scr.Gridx; int y = scr.Gridy; int color = scr.chessmanObj.GetChessmanColor(); //思路就是当一个棋子移动时,判断它八个方向相同颜色的棋子,相同时就消除 bool[] jieshu = new bool[MaxRowNum]; int[] tongseshu = new int[MaxRowNum]; for (int i = 0; i < MaxRowNum; i++) { jieshu[i] = false; tongseshu[i] = 0; } //从scr向八方向开始辐射 //寻找4次,因为大于4的情况已经判断过了(在上回合) for (int i = 0; i < 5; i++) { for (int j = 0; j < MaxRowNum; j++) { if (j == 4 || jieshu[j]) { continue; } int tx = x + (j / 3 - 1) * i; int ty = y + (j % 3 - 1) * i; if (tx >= 0 && tx < 9 && ty >= 0 && ty < 9) { if (color == GridScrTransform[tx, ty].chessmanObj.GetChessmanColor()) { tongseshu[j]++; } else { jieshu[j] = true; } } else { jieshu[j] = true; } } } //将同一条线上的同色数相加 int zongshu = 0; for (int i = 0; i < 4; i++) { int temi = tongseshu[i] + tongseshu[MaxRowNum - 1 - i]; if (temi >= 4) { //那么可以消除 zongshu += temi; //像两个方向延伸消除 for (int j = 0; j < tongseshu[i]; j++) { int tx = x + (i / 3 - 1) * j; int ty = y + (i % 3 - 1) * j; GridScrTransform[tx, ty].chessmanObj.SetChessmanColor(0); } for (int j = 1; j <= tongseshu[MaxRowNum - 1 - i]; j++) { int tx = x + ((8 - i) / 3 - 1) * j; int ty = y + ((8 - i) % 3 - 1) * j; GridScrTransform[tx, ty].chessmanObj.SetChessmanColor(0); } } } zongshu++; if (zongshu > 4) { //加分处理 GridScrTransform[x, y].chessmanObj.SetChessmanColor(0); NowChessmanNum -= zongshu; GameManager._gameManager.SetScore(); return(true); } else { return(false); } }