feat: 重构棋盘逻辑和游戏流程,将引擎版本提升至4.3

- 重构了 VirtualBoard 类,优化了棋盘操作和事件处理
- 重写了 ChessPiece 类,增加了事件处理和虚拟棋子逻辑
- 更新了 ChessGame 控制器,增加了结束回合功能和对话框
- 调整了场景布局和资源引用
- 清理了冗余代码和注释
This commit is contained in:
ZZY
2024-11-02 21:18:53 +08:00
parent abace89813
commit 7e2ca3948d
17 changed files with 2984 additions and 503 deletions

View File

@ -2,27 +2,19 @@
using Godot;
public partial class ChessBoard : Node2D {
VirtualBoard Board = null;
MoveRecords Records = null;
// Called when the node enters the scene tree for the first time.
public Vector2 selectedNodePos = Vector2.Inf;
public VirtualBoard board = null;
public Player playerSelf = null;
public delegate bool ChessMoveFunc(Vector2 toPos, Vector2 fromPos);
public Callable chessMoveFunc { get; set; }
public override void _Ready() {
Board = new VirtualBoard(this as Node);
Records = new MoveRecords(onUndoRecordCallback: (newNode, oldNode, newPos, oldPos) => {
GD.Print("Undo: ", newNode, "->", oldNode, ":", newPos, "->", oldPos);
ChessPiece newPiece = newNode as ChessPiece;
ChessPiece oldPiece = oldNode as ChessPiece;
Board.MoveNode(oldPos, newPos);
if (newPiece != null) {
Board.InsertNode(newPiece, newPos);
}
});
Board.InitChessBoard();
// this.AddChild();
board = new VirtualBoard(9, 10);
playerSelf = new Player(board);
board.OnRemove += OnRemove;
board.OnInsert += OnInsert;
board.OnMove += OnMove;
InitChessBoard();
}
public override void _Input(InputEvent @event) {
@ -31,85 +23,286 @@ public partial class ChessBoard : Node2D {
mouseEvent.ButtonIndex == MouseButton.Left) {
// HandleMouseClick(GetGlobalTransformWithCanvas().AffineInverse() * mouseButton.Position);
HandleMouseClick(GetLocalMousePosition());
// ActionPos(
// (PosTrans.transArrToPix.AffineInverse() *
// GetLocalMousePosition()).Round()
// );
}
}
public void ActionPos(Vector2 newPos) {
}
public void MoveAndRecord(Vector2 toPos, Vector2 fromPos) {
GD.Print($"{fromPos} move to {toPos}");
ChessPiece toChess = Board.GetNodeFromBoard(toPos) as ChessPiece;
ChessPiece fromChess = Board.GetNodeFromBoard(fromPos) as ChessPiece;
if (fromChess != null) {
fromChess.DeSelected();
}
Node NowNode;
if (toChess != null) {
GD.Print("nowchess", toChess);
NowNode = toChess.Duplicate();
Board.RemoveNode(toPos);
} else {
NowNode = toChess as Node;
}
Records.AddRecord(NowNode, fromChess, toPos, fromPos);
Board.MoveNode(toPos, fromPos);
selectedNodePos = Vector2.Inf;
}
public void Undo() {
Records.Undo();
}
public void ReInit() {
Records.Clear();
Board.Clear();
selectedNodePos = Vector2.Inf;
Board.InitChessBoard();
}
private void HandleMouseClick(Vector2 clickPosition) {
Vector2 newPos = (PosTrans.transArrToPix.AffineInverse() *
clickPosition).Round();
if (VirtualBoard.ArrPosOutOfRange(newPos)) return;
GD.Print($"{newPos} mouse clicked");
ChessPiece NowChess = Board.GetNodeFromBoard(newPos) as ChessPiece;
ChessPiece SelChess = Board.GetNodeFromBoard(selectedNodePos) as ChessPiece;
if (Vector2.Inf.Equals(selectedNodePos)) {
if (NowChess == null) {
return;
}
NowChess.Selected();
selectedNodePos = newPos;
} else if (selectedNodePos == newPos) {
if (SelChess != null) {
SelChess.DeSelected();
}
selectedNodePos = Vector2.Inf;
} else {
if (chessMoveFunc.Delegate != null) {
GD.Print("chessMoveFunc Move: ", selectedNodePos, "->", newPos);
if ((bool)chessMoveFunc.Call(newPos, selectedNodePos)) {
MoveAndRecord(newPos, selectedNodePos);
}
} else {
GD.Print("default MoveFunc Move: ", selectedNodePos, "->", newPos);
MoveAndRecord(newPos, selectedNodePos);
}
// MoveAndRecord(newPos, selectedNodePos);
// GD.Print($"End: {selectedNodePos} {SelChess} move to {clickArrPos} {NowChess}");
}
}
private void HandleMouseClick(Vector2 clickPosition) {
Vector2 clickBoardPos = (PosTrans.transArrToPix.AffineInverse() *
clickPosition).Round();
playerSelf.HandleBoardPosClick(clickBoardPos);
}
void OnMove(Vector2 from, Vector2 to) {
chessMoveFunc.Call(to, from);
}
void OnRemove(VirtualPiece piece) {
// (piece.data as Node).QueueFree();
if (piece?.data != null)
RemoveChild(piece.data as Node);
}
void OnInsert(VirtualPiece piece) {
ChessPiece chess = piece.data as ChessPiece;
AddChild(chess);
}
public void InsertNode(ChessPiece node, Vector2 arrayPos) {
AddChild(node);
VirtualPiece piece = node.GetVirtualPiece();
// piece.Move(vector);
board.SetPiecePos(piece, arrayPos);
}
// using Godot;
// public enum ChessType
// {
// Carriage,
// Horse,
// Elephant,
// Advisor,
// General,
// Cannon,
// Pawn
// }
// public class VirtualBoard
// {
// // ...其他原有成员变量...
// public VirtualBoard(Node root = null)
// {
// BoardRoot = root ?? GetTree().CurrentScene; // 如果未提供root默认为当前场景
// }
// public void InitChessBoard()
// {
// // 定义黑色和红色棋子的初始位置和类型
// var positions = new (Vector2 position, ChessType type)[]
// {
// // 黑方棋子初始化...
// // 示例省略具体位置和类型,你需要根据实际情况填写
// // (new Vector2(x, y), ChessType.Pawn),
// // 红方棋子初始化...
// // 同上
// };
// // 初始化棋子
// foreach (var (position, type) in positions)
// {
// var color = position.Y == 0 ? new Color("black") : new Color("red"); // 根据行判断颜色
// var piece = CreateChessPiece(type, color);
// InsertChess(piece, position);
// }
// }
// private ChessPiece CreateChessPiece(ChessType type, Color labelColor)
// {
// // 根据ChessType创建对应的棋子实例并设置Label和颜色
// // 这里需要你实现具体的逻辑例如switch case或映射表来决定创建哪种棋子
// // 返回创建的棋子实例
// }
// // ...其他原有方法...
// }
public void InitChessBoard() {
InsertNode(new ChessPiece
{
PieceLabel = "车",
LabelColor = new Color("black"),
}, new Vector2(0, 0));
InsertNode(new ChessPiece
{
PieceLabel = "马",
LabelColor = new Color("black"),
}, new Vector2(1, 0));
InsertNode(new ChessPiece
{
PieceLabel = "象",
LabelColor = new Color("black"),
}, new Vector2(2, 0));
InsertNode(new ChessPiece
{
PieceLabel = "士",
LabelColor = new Color("black"),
}, new Vector2(3, 0));
InsertNode(new ChessPiece
{
PieceLabel = "将",
LabelColor = new Color("black"),
}, new Vector2(4, 0));
InsertNode(new ChessPiece
{
PieceLabel = "士",
LabelColor = new Color("black"),
}, new Vector2(5, 0));
InsertNode(new ChessPiece
{
PieceLabel = "象",
LabelColor = new Color("black"),
}, new Vector2(6, 0));
InsertNode(new ChessPiece
{
PieceLabel = "马",
LabelColor = new Color("black"),
}, new Vector2(7, 0));
InsertNode(new ChessPiece
{
PieceLabel = "车",
LabelColor = new Color("black"),
}, new Vector2(8, 0));
InsertNode(new ChessPiece
{
PieceLabel = "炮",
LabelColor = new Color("black"),
}, new Vector2(1, 2));
InsertNode(new ChessPiece
{
PieceLabel = "炮",
LabelColor = new Color("black"),
}, new Vector2(7, 2));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("black"),
}, new Vector2(0, 3));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("black"),
}, new Vector2(2, 3));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("black"),
}, new Vector2(4, 3));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("black"),
}, new Vector2(6, 3));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("black"),
}, new Vector2(8, 3));
// -----------------------------------
InsertNode(new ChessPiece
{
PieceLabel = "车",
LabelColor = new Color("red"),
}, new Vector2(0, 9));
InsertNode(new ChessPiece
{
PieceLabel = "马",
LabelColor = new Color("red"),
}, new Vector2(1, 9));
InsertNode(new ChessPiece
{
PieceLabel = "象",
LabelColor = new Color("red"),
}, new Vector2(2, 9));
InsertNode(new ChessPiece
{
PieceLabel = "士",
LabelColor = new Color("red"),
}, new Vector2(3, 9));
InsertNode(new ChessPiece
{
PieceLabel = "将",
LabelColor = new Color("red"),
}, new Vector2(4, 9));
InsertNode(new ChessPiece
{
PieceLabel = "士",
LabelColor = new Color("red"),
}, new Vector2(5, 9));
InsertNode(new ChessPiece
{
PieceLabel = "象",
LabelColor = new Color("red"),
}, new Vector2(6, 9));
InsertNode(new ChessPiece
{
PieceLabel = "马",
LabelColor = new Color("red"),
}, new Vector2(7, 9));
InsertNode(new ChessPiece
{
PieceLabel = "车",
LabelColor = new Color("red"),
}, new Vector2(8, 9));
InsertNode(new ChessPiece
{
PieceLabel = "炮",
LabelColor = new Color("red"),
}, new Vector2(1, 7));
InsertNode(new ChessPiece
{
PieceLabel = "炮",
LabelColor = new Color("red"),
}, new Vector2(7, 7));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("red"),
}, new Vector2(0, 6));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("red"),
}, new Vector2(2, 6));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("red"),
}, new Vector2(4, 6));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("red"),
}, new Vector2(6, 6));
InsertNode(new ChessPiece
{
PieceLabel = "卒",
LabelColor = new Color("red"),
}, new Vector2(8, 6));
}
}

View File

@ -11,42 +11,38 @@ public partial class ChessPiece : Sprite2D {
private Vector2 textureSize;
private Label labelOfChessName;
private VirtualPiece piece;
private Vector2 arrPos = new Vector2(); // 注意这个坐标的非像素坐标而是棋盘坐标
public void movePos(Vector2 newPos) {
this.arrPos = newPos;
this.Position = PosTrans.transArrToPix * newPos;
public VirtualPiece GetVirtualPiece() {
return piece;
}
public Vector2 getPos() {
return arrPos;
private void OnMove(Vector2 newPos) {
Position = PosTrans.transArrToPix * new Vector2(newPos.X, newPos.Y);
}
public void OnSelected(bool isSelected) {
if (isSelected) {
GD.Print($"{piece.Pos()} is selected");
Transform *= transToSeleted;
} else {
GD.Print($"{piece.Pos()} is deselected");
Transform *= transToSeleted.AffineInverse();
}
}
// 是否被选中
public bool isSelected = false;
Transform2D transToSeleted = new Transform2D(
new Vector2(1.2f, 0),
new Vector2(0, 1.2f),
new Vector2(0, 0)
);
public void Selected() {
if (isSelected) {
return;
}
GD.Print($"{arrPos} is selected");
this.Transform *= transToSeleted;
this.isSelected = true;
}
public void DeSelected() {
if (!isSelected) {
return;
}
GD.Print($"{arrPos} is deselected");
this.Transform *= transToSeleted.AffineInverse();
this.isSelected = false;
public ChessPiece(string name = "", Vector2 pos = new Vector2()) {
PieceLabel = name;
piece = new VirtualPiece(name, pos);
piece.OnMove += OnMove;
piece.OnSelected += OnSelected;
piece.data = this;
}
// Called when the node enters the scene tree for the first time.
@ -56,8 +52,8 @@ public partial class ChessPiece : Sprite2D {
private void InitLabel() {
// this.Texture.ResourcePath = "res://Asserts/ChesspieceBase.tres";
this.Texture ??= (Texture2D)ResourceLoader.Load("res://Asserts/ChesspieceBase.tres");
textureSize = this.Texture.GetSize();
Texture ??= (Texture2D)ResourceLoader.Load("res://Asserts/ChesspieceBase.tres");
textureSize = Texture.GetSize();
Vector2 labalPosition = new(
-textureSize.X / 2,
-textureSize.Y / 2);
@ -72,8 +68,4 @@ public partial class ChessPiece : Sprite2D {
// labelOfChessName.SetAnchorsPreset(Control.LayoutPreset.FullRect);
AddChild(labelOfChessName);
}
interface IVarify {
bool CanMove(Vector2 newPosition);
}
}