116 lines
3.3 KiB
C#

// Chessboard.cs
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 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();
}
public override void _Input(InputEvent @event) {
if (@event is InputEventMouseButton mouseEvent &&
mouseEvent.Pressed &&
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}");
}
}
}