Tiếp phần trước hôm nay mình sẽ hướng dẫn các bạn xử lý lượt chơi và kết thúc ván cờ.
1. Xử lý lượt chơi
Để xử lý lượt chơi, mình sẽ đưa logic này vào GameManager.
.... private ChessPiece _selectedChessPiece; public Action OnMoved; .... private void InitGame() { .... OnMoved += OnOnePlayerMoved; .... } private void StartGame() { _currentGameTurn = ChessSkin.White; } .... private void EndGame(ChessSkin chessSkin) { .... OnMoved -= OnOnePlayerMoved; } private void OnPlayerClickOnCell(Vector2 currentChessPiecePos, ChessPiece chessPiece, Action<ChessPiece> suggestWaysForMove) { if (!LegitToSelect(chessPiece)) { _cellSelectedObj.SetActive(false); return; } .... } private bool LegitToSelect(ChessPiece chessPiece) { if (chessPiece.Skin != _currentGameTurn) return false; if (chessPiece.Skin != _currentGameTurn) return false; return true; } private void OnOnePlayerMoved() { _currentGameTurn = _currentGameTurn == ChessSkin.White ? ChessSkin.Black : ChessSkin.White; _selectedChessPiece = null; _cellSelectedObj.SetActive(false); }
Ở logic update này mình tạo thêm biến chứa lượt chơi hiện tại là của quân trắng hay đen, và trong hàm OnPlayerClickCell và kiểm tra xem xem nếu chọn quân cờ đen nhưng nếu đang ở lượt bên trắng hoặc ngược lại thì sẽ không cho chọn.
Tiếp theo là hàm OnOnePlayedMoved là hàm này mình sẽ dùng để xử lý sau khi người chơi đi 1 bước sẽ chuyển lượt qua cho người khác.
Tiếp theo mình sẽ gọi action OnMoved từ hàm ClickToMoveChessPieceTo trong hàm ChessBoardCell khi người chơi click vào ô cờ và di chuyển quân cờ.
private void ClickToMoveChessPieceTo() { if (_cellCanMove.activeSelf) { ..... _boardManager.GameManager.OnMoved?.Invoke(); } }
Lúc này khi ra editor play thử các bạn sẽ thấy quân trắng đi trước quân đen đi sau, và cứ lần lượt đổi lượt, vậy là logic xử lý lượt chơi đến đây là xong, mình sẽ tiếp tục hướng dẫn các bạn logic kết thúc trò chơi.
Logic Kết thúc ván cờ
Chơi thì sẽ có thắng thua, mà đối với cờ vua, mất vua là thua, nên mình sẽ xử lý logic này bằng cách kiểm tra khi mà vua 1 bên mất thì bên kia sẽ thắng.
Trước tiên mình cần phải update logic ăn quân trước. Mình sẽ update logic này trong script ChessBoardCell
..... private void OnMouseDown() { if (_currentChessPiece != null) { if (CanSelected()) { _boardManager.ResetAllBoardCell(); _boardManager.GameManager.OnClickOnCell?.Invoke(_cellPos, _currentChessPiece, _boardManager.SuggestWayForChessPiece); } } ClickToMoveChessPieceTo(); } private bool CanSelected() { var selectedChessPiece = _boardManager.GameManager.SelectedChessPiece; if (selectedChessPiece != null) { if (_currentChessPiece.Skin != selectedChessPiece.Skin) { return false; } } return true; } private void ClickToMoveChessPieceTo() { if (_cellCanMove.activeSelf) { _cellCanMove.SetActive(false); var chessPiece = _boardManager.GameManager.SelectedChessPiece; var selectedChessPieceTransform = chessPiece.transform; Occupied(chessPiece); _boardManager.RemoveChessPieceFromCell(chessPiece); _currentChessPiece = chessPiece; chessPiece.Move(new Vector2Int((int)_cellPos.x, (int)_cellPos.y)); selectedChessPieceTransform.parent = this.gameObject.transform; _boardManager.GameManager.OnMoved?.Invoke(); _boardManager.ResetAllBoardCell(); } } private void Occupied(ChessPiece newChessPiece) { if (_currentChessPiece != null) { if (newChessPiece.Skin != _currentChessPiece.Skin) { Destroy(_currentChessPiece.gameObject); } } } .....
Logic trong đây là khi quân cờ mới được đặt xuống ô cờ, mình sẽ kiểm tra 1 lần nữa là quân trong ô cờ đó khác màu với quân vừa được đặt xuống, mình sẽ gọi hàm Destroy để hủy gameobject quân cờ của ô cờ hiện tại, sau đó tiếp tục set quân cờ mới đặt tới vào ô cờ hiện tại.
Tiếp theo mình update trong script GameManager thêm như sau:
.... private void EndGame(ChessSkin chessSkin) { if (chessSkin == ChessSkin.White) Debug.Log("Black win"); else Debug.Log("White win"); .... } ..... public void KillOpponentKing(ChessPiece chessPiece) { var king = chessPiece.GetComponent<King>(); if (king != null) { EndGame(king.Skin); } }
Logic ở đây là khi có 1 quân cờ bị ăn thì sẽ gọi tới hàm KillOpponentKing để kiểm tra xem có phải quân bị ăn là quân vua không, nếu phải thì gọi tới hàm EndGame, và truyền vào đây màu của quân vua, nếu là vua màu trắng thì bên thắng là bên đen sẽ log ra màn hình console, nếu vua màu đen thì là bên thắng là bên trắng.
Tiếp theo mình lại vào hàm Occupied trong ChessBoardCell gọi hàm KillOpponentKing này
private void Occupied(ChessPiece newChessPiece) { if (_currentChessPiece != null) { if (newChessPiece.Skin != _currentChessPiece.Skin) { _boardManager.GameManager.KillOpponentKing(_currentChessPiece); Destroy(_currentChessPiece.gameObject); } } }
Sau khi hoàn thành mình sẽ lại vào editor play game và thử cho 1 bên ăn vua bên kia.
Sau khi quân trắng ăn được vua bên đen thì log đã log ra thông báo bên trắng đã thắng.
Tác giả: Nguyễn Minh Thuận & Nguyễn Văn Khánh