init basic signal player chinese chess game

This commit is contained in:
ZZY
2024-06-15 18:07:20 +08:00
commit 9ba2e1af6b
71 changed files with 2752 additions and 0 deletions

View File

@ -0,0 +1,100 @@
// 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 override void _Ready() {
Board = new VirtualBoard(this as Node);
Records = new MoveRecords(onUndoRecordCallback: (newNode, oldNode, newPos, oldPos) => {
GD.Print("Undo: ", newNode, "->", newNode, ":", newPos, "->", oldPos);
ChessPiece newPiece = newNode as ChessPiece;
ChessPiece oldPiece = oldNode as ChessPiece;
Board.MoveNode(oldPos, newPos);
if (newPiece != null) {
Board.InsertNode(newPiece, newPos);
}
// if (oldPiece != null) {
// Board.RemoveNode(oldPos);
// }
});
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 clickArrPos) {
if (VirtualBoard.ArrPosOutOfRange(clickArrPos)) return;
GD.Print($"{clickArrPos} mouse clicked");
ChessPiece NowChess = Board.getNodeFromBoard(clickArrPos) as ChessPiece;
ChessPiece SelChess = Board.getNodeFromBoard(selectedNodePos) as ChessPiece;
if (Vector2.Inf.Equals(selectedNodePos)) {
if (NowChess == null) {
return;
}
NowChess.Selected();
GD.Print($"{clickArrPos} is selected");
selectedNodePos = clickArrPos;
} else if (selectedNodePos == clickArrPos) {
if (SelChess != null) {
SelChess.DeSelected();
}
GD.Print($"{selectedNodePos} is deselected");
selectedNodePos = Vector2.Inf;
} else {
GD.Print($"{selectedNodePos} move to {clickArrPos}");
if (SelChess != null) {
SelChess.DeSelected();
GD.Print($"{selectedNodePos} is deselected");
}
Node NowNode;
if (NowChess != null) {
NowNode = NowChess.Duplicate();
Board.RemoveNode(clickArrPos);
} else {
NowNode = NowChess as Node;
}
Records.AddRecord(NowNode, SelChess, clickArrPos, selectedNodePos);
Board.MoveNode(clickArrPos, selectedNodePos);
selectedNodePos = Vector2.Inf;
// GD.Print($"End: {selectedNodePos} {SelChess} move to {clickArrPos} {NowChess}");
}
}
public void undo() {
Records.Undo();
}
public void redo() {
Records.Clear();
Board.Clear();
Board.InitChessBoard();
}
private void HandleMouseClick(Vector2 clickPosition) {
// 如果有棋子被选中,则进行后续操作
// if (nowSelectedChess == null) {
// seletedNode = null;
// } else if (nowSelectedChess != null && seletedNode != null) {
// if (seletedNode is ChessPiece chessPiece) MoveChess(arrayPos, chessPiece.arrPos);
// }
}
}

View File

@ -0,0 +1,77 @@
// Chesspiece.cs
using Godot;
public partial class ChessPiece : Sprite2D {
// 文字内容
[Export]
public string PieceLabel { get; set; } = null;
// 文字颜色(可导出以编辑器调整)
[Export]
public Color LabelColor { get; set; } = new Color("black");
private Vector2 textureSize;
private Label labelOfChessName;
private Vector2 arrPos = new Vector2(); // 注意这个坐标的非像素坐标而是棋盘坐标
public void movePos(Vector2 newPos) {
this.arrPos = newPos;
this.Position = PosTrans.transArrToPix * newPos;
}
public Vector2 getPos() {
return arrPos;
}
// 是否被选中
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;
}
this.Transform *= transToSeleted;
this.isSelected = true;
}
public void DeSelected() {
if (!isSelected) {
return;
}
this.Transform *= transToSeleted.AffineInverse();
this.isSelected = false;
}
// Called when the node enters the scene tree for the first time.
public override void _Ready() {
InitLabel();
}
private void InitLabel() {
// this.Texture.ResourcePath = "res://Asserts/ChesspieceBase.tres";
this.Texture = (Texture2D)ResourceLoader.Load("res://Asserts/ChesspieceBase.tres");
textureSize = this.Texture.GetSize();
Vector2 labalPosition = new(
-textureSize.X / 2,
-textureSize.Y / 2);
labelOfChessName = new Label {
Text = PieceLabel,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Modulate = LabelColor,
Position = labalPosition,
Size = textureSize,
};
// labelOfChessName.SetAnchorsPreset(Control.LayoutPreset.FullRect);
AddChild(labelOfChessName);
}
interface IVarify {
bool CanMove(Vector2 newPosition);
}
}

View File

@ -0,0 +1,20 @@
// 帅/将 (General) - 代表双方的最高统帅。
// 子类名ChessGeneral
// 仕/士 (Advisor) - 保护帅/将的近身侍卫。
// 子类名ChessAdvisor
// 相/象 (Elephant) - 行动受限,走田字格,不能过河。
// 子类名ChessElephant
// 車/车 (Chariot) - 横竖移动,威力巨大。
// 子类名ChessChariot
// 馬/马 (Horse) - 走日字形,跳跃式移动。
// 子类名ChessHorse
// 砲/炮 (Cannon) - 需要隔子才能吃子,直线移动。
// 子类名ChessCannon
// 兵/卒 (Pawn) - 最基础的棋子,过河后可横移。
// 子类名ChessPawn