feat: 重构多人游戏界面和代码,使用文件存储游戏配置,重构底层代码
This commit is contained in:
0
Scripts/Src/ChineseChess/ChessAdvisor.cs
Normal file
0
Scripts/Src/ChineseChess/ChessAdvisor.cs
Normal file
0
Scripts/Src/ChineseChess/ChessCannon.cs
Normal file
0
Scripts/Src/ChineseChess/ChessCannon.cs
Normal file
0
Scripts/Src/ChineseChess/ChessChariot.cs
Normal file
0
Scripts/Src/ChineseChess/ChessChariot.cs
Normal file
0
Scripts/Src/ChineseChess/ChessElephant.cs
Normal file
0
Scripts/Src/ChineseChess/ChessElephant.cs
Normal file
0
Scripts/Src/ChineseChess/ChessGeneral.cs
Normal file
0
Scripts/Src/ChineseChess/ChessGeneral.cs
Normal file
0
Scripts/Src/ChineseChess/ChessHorse.cs
Normal file
0
Scripts/Src/ChineseChess/ChessHorse.cs
Normal file
0
Scripts/Src/ChineseChess/ChessPawn.cs
Normal file
0
Scripts/Src/ChineseChess/ChessPawn.cs
Normal file
20
Scripts/Src/ChineseChess/ChessTypes.cs
Normal file
20
Scripts/Src/ChineseChess/ChessTypes.cs
Normal file
@ -0,0 +1,20 @@
|
||||
// 帅/将 (General) - 代表双方的最高统帅。
|
||||
// 子类名:ChessGeneral
|
||||
|
||||
// 仕/士 (Advisor) - 保护帅/将的近身侍卫。
|
||||
// 子类名:ChessAdvisor
|
||||
|
||||
// 相/象 (Elephant) - 行动受限,走田字格,不能过河。
|
||||
// 子类名:ChessElephant
|
||||
|
||||
// 車/车 (Chariot) - 横竖移动,威力巨大。
|
||||
// 子类名:ChessChariot
|
||||
|
||||
// 馬/马 (Horse) - 走日字形,跳跃式移动。
|
||||
// 子类名:ChessHorse
|
||||
|
||||
// 砲/炮 (Cannon) - 需要隔子才能吃子,直线移动。
|
||||
// 子类名:ChessCannon
|
||||
|
||||
// 兵/卒 (Pawn) - 最基础的棋子,过河后可横移。
|
||||
// 子类名:ChessPawn
|
0
Scripts/Src/ChineseChess/ChineseChess.cs
Normal file
0
Scripts/Src/ChineseChess/ChineseChess.cs
Normal file
125
Scripts/Src/ChineseChess/Player.cs
Normal file
125
Scripts/Src/ChineseChess/Player.cs
Normal file
@ -0,0 +1,125 @@
|
||||
using Vector2 = Godot.Vector2;
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
public class Player {
|
||||
private readonly VirtualBoard board;
|
||||
private readonly SelectedPiece selectedNode;
|
||||
private readonly MoveRecords<VirtualPiece> moveRecords;
|
||||
public EventHandler<VirtualBoard.MoveEventArgs> OnMove;
|
||||
public ArrayList pieces = new();
|
||||
|
||||
public enum PlayerType {
|
||||
Human,
|
||||
AI
|
||||
}
|
||||
|
||||
public Player(VirtualBoard board, PlayerType type = PlayerType.Human)
|
||||
{
|
||||
this.board = board;
|
||||
this.selectedNode = new SelectedPiece(board);
|
||||
this.moveRecords = new MoveRecords<VirtualPiece>(onUndoRecordCallback: (newNode, oldNode, newPos, oldPos) => {
|
||||
// GD.Print("Undo: ", newNode, "->", oldNode, ":", newPos, "->", oldPos);
|
||||
VirtualPiece newPiece = newNode;
|
||||
VirtualPiece oldPiece = oldNode;
|
||||
this.board.MovePiece(newPos, oldPos);
|
||||
if (newPiece != null) {
|
||||
this.board.InsertPiece(newPiece, newPos);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void HandleBoardPosClick(Vector2 clickPos) {
|
||||
if (board.ArrPosOutOfRange(clickPos)) return;
|
||||
// GD.Print($"VirtualBoard {clickPos} clicked");
|
||||
VirtualPiece clickChess = board.GetPiece(clickPos);
|
||||
|
||||
if (!selectedNode.HasSelected()) {
|
||||
// Select piece
|
||||
if (clickChess == null) {
|
||||
// selectedNode.Clear();
|
||||
return;
|
||||
}
|
||||
selectedNode.SetPos(clickPos);
|
||||
} else if (clickChess == selectedNode.GetPiece()) {
|
||||
// Unselect piece
|
||||
selectedNode.Clear();
|
||||
} else {
|
||||
// Move piece
|
||||
// GD.Print("default MoveFunc Move: ", selectedNode.GetPos(), "->", clickPos);
|
||||
MoveAndRecord(clickPos, selectedNode.GetPos());
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveAndRecord(Vector2 toPos, Vector2 fromPos) {
|
||||
// GD.Print($"{fromPos} move to {toPos}");
|
||||
VirtualPiece toChess = board.GetPiece(toPos);
|
||||
VirtualPiece fromChess = board.GetPiece(fromPos);
|
||||
fromChess?.Selected(false);
|
||||
|
||||
VirtualPiece NowNode;
|
||||
if (toChess != null) {
|
||||
NowNode = toChess;
|
||||
board.RemovePiece(toPos);
|
||||
} else {
|
||||
NowNode = toChess;
|
||||
}
|
||||
moveRecords.AddRecord(NowNode, fromChess, toPos, fromPos);
|
||||
|
||||
OnMove?.Invoke(this, new VirtualBoard.MoveEventArgs { From = fromPos, To = toPos });
|
||||
board.MovePiece(fromPos, toPos);
|
||||
|
||||
selectedNode.Clear();
|
||||
}
|
||||
|
||||
public void Undo() {
|
||||
// ChessPiece selected = selectedNode.GetPiece();
|
||||
// selected?.DeSelected();
|
||||
selectedNode.Clear();
|
||||
moveRecords.Undo();
|
||||
}
|
||||
|
||||
public void ReInit() {
|
||||
moveRecords.Clear();
|
||||
board.Clear();
|
||||
selectedNode.Clear();
|
||||
// board.InitChessBoard();
|
||||
}
|
||||
|
||||
private class SelectedPiece {
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
private Vector2 selectedNodePos = Vector2.Inf;
|
||||
private VirtualPiece piece;
|
||||
private readonly VirtualBoard board;
|
||||
|
||||
public SelectedPiece(VirtualBoard board) {
|
||||
this.board = board;
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
if (selectedNodePos != Vector2.Inf) {
|
||||
selectedNodePos = Vector2.Inf;
|
||||
piece.Selected(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPos(Vector2 pos) {
|
||||
// piece = board.GetNodeFromBoard(pos) as VirtualPiece;
|
||||
selectedNodePos = pos;
|
||||
piece = board.GetPiece(selectedNodePos);
|
||||
piece.Selected(true);
|
||||
}
|
||||
|
||||
public VirtualPiece GetPiece() {
|
||||
return piece;
|
||||
}
|
||||
|
||||
public Vector2 GetPos() {
|
||||
return selectedNodePos;
|
||||
}
|
||||
|
||||
public bool HasSelected() {
|
||||
return selectedNodePos != Vector2.Inf;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user