Unity中基于Image对象的类井字棋游戏胜负判定实现问询
井字棋胜负判定实现方案
核心思路
通过给棋盘点位添加状态标识,维护全局棋盘状态数组,在棋子放置后检查横/竖方向的三连条件来判定胜负。
1. 给棋盘点位添加状态脚本
给每个黑色棋盘点位的Image挂载Slot脚本,用来记录点位坐标和占用状态:
public class Slot : MonoBehaviour { // 在Inspector手动设置:行、列(范围0-2) public int row; public int col; // 0=空,1=红方,2=蓝方 public int occupiedBy; public bool IsEmpty() => occupiedBy == 0; }
场景中给每个点位设置对应的row和col,比如左上角设(0,0),右下角设(2,2)
2. 全局游戏状态管理
创建GameManager单例,负责棋盘状态维护、轮次切换和胜负检查:
public class GameManager : MonoBehaviour { public static GameManager Instance; private int[,] boardState = new int[3,3]; private int currentPlayer = 1; // 1=红方,2=蓝方 private void Awake() { Instance = this; ResetBoard(); } public void ResetBoard() { for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) boardState[i,j] = 0; currentPlayer = 1; } // 尝试放置棋子,成功则返回true public bool PlacePiece(int row, int col, int player) { if (boardState[row,col] != 0 || player != currentPlayer) return false; boardState[row,col] = player; if (CheckWin(player)) { Debug.Log(player == 1 ? "红方获胜!" : "蓝方获胜!"); // 这里添加获胜后的逻辑(弹窗、重置等) } else { currentPlayer = currentPlayer == 1 ? 2 : 1; } return true; } // 检查指定玩家是否达成横/竖三连 private bool CheckWin(int player) { // 横向检查 for (int i = 0; i < 3; i++) { if (boardState[i,0] == player && boardState[i,1] == player && boardState[i,2] == player) return true; } // 纵向检查 for (int j = 0; j < 3; j++) { if (boardState[0,j] == player && boardState[1,j] == player && boardState[2,j] == player) return true; } // 若需要对角线判定,可取消下面注释 // if (boardState[0,0] == player && boardState[1,1] == player && boardState[2,2] == player) // return true; // if (boardState[0,2] == player && boardState[1,1] == player && boardState[2,0] == player) // return true; return false; } }
3. 修改拖拽代码,整合放置逻辑
更新你的棋子拖拽脚本,添加玩家标识,并在拖拽结束时验证放置合法性:
using UnityEngine; using UnityEngine.EventSystems; public class PieceDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public Image image; [HideInInspector] public Transform parentAfterDrag; // 红棋子设1,蓝棋子设2,在Inspector配置 public int playerId; public void OnBeginDrag(PointerEventData eventData) { parentAfterDrag = transform.parent; transform.SetParent(transform.root); transform.SetAsLastSibling(); image.raycastTarget = false; } public void OnDrag(PointerEventData eventData) { transform.position = Input.mousePosition; } public void OnEndDrag(PointerEventData eventData) { // 检查是否落在棋盘点位上 if (EventSystem.current.IsPointerOverGameObject()) { GameObject hitObj = eventData.pointerCurrentRaycast.gameObject; Slot targetSlot = hitObj.GetComponent<Slot>(); if (targetSlot != null && targetSlot.IsEmpty()) { // 放置棋子到目标点位 transform.SetParent(hitObj.transform); transform.localPosition = Vector3.zero; // 通知GameManager更新状态 if (GameManager.Instance.PlacePiece(targetSlot.row, targetSlot.col, playerId)) { this.enabled = false; // 禁用拖拽,防止重复移动 return; } } } // 未放置到合法位置,返回原位置 transform.SetParent(parentAfterDrag); transform.localPosition = Vector3.zero; image.raycastTarget = true; } }
4. 场景配置步骤
- 给每个棋盘点位的
Slot脚本设置正确的row和col值; - 红棋子的
PieceDrag脚本playerId设为1,蓝棋子设为2; - 在场景中添加一个空物体,挂载
GameManager脚本。
内容的提问来源于stack exchange,提问作者Leo Tran
相关产品推荐
相关产品推荐

