// 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}"); } } }