feat: 重构棋盘逻辑和游戏流程,将引擎版本提升至4.3
- 重构了 VirtualBoard 类,优化了棋盘操作和事件处理 - 重写了 ChessPiece 类,增加了事件处理和虚拟棋子逻辑 - 更新了 ChessGame 控制器,增加了结束回合功能和对话框 - 调整了场景布局和资源引用 - 清理了冗余代码和注释
This commit is contained in:
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user