feat: 重构棋盘逻辑和游戏流程,将引擎版本提升至4.3
- 重构了 VirtualBoard 类,优化了棋盘操作和事件处理 - 重写了 ChessPiece 类,增加了事件处理和虚拟棋子逻辑 - 更新了 ChessGame 控制器,增加了结束回合功能和对话框 - 调整了场景布局和资源引用 - 清理了冗余代码和注释
This commit is contained in:
parent
abace89813
commit
7e2ca3948d
17
.gitignore
vendored
17
.gitignore
vendored
@ -1,4 +1,19 @@
|
||||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
.*/
|
||||
|
||||
# Godot-specific ignores
|
||||
.import/
|
||||
export.cfg
|
||||
export_presets.cfg
|
||||
|
||||
# Imported translations (automatically generated from CSV files)
|
||||
*.translation
|
||||
|
||||
# Mono-specific ignores
|
||||
.mono/
|
||||
data_*/
|
||||
mono_crash.*.json
|
||||
|
||||
# MyProject specific ignores
|
||||
.vscode/
|
||||
bin/
|
@ -1,4 +0,0 @@
|
||||
[gd_resource type="Theme" format=3 uid="uid://c53fg2fg071yp"]
|
||||
|
||||
[resource]
|
||||
default_font_size = 30
|
2295
Asserts/defaultTheme.tres
Normal file
2295
Asserts/defaultTheme.tres
Normal file
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Godot.NET.Sdk/4.2.2">
|
||||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||
|
22
Main.tscn
22
Main.tscn
@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://boa4od72355o4"]
|
||||
|
||||
[ext_resource type="Script" path="res://Main.cs" id="1_h4cv2"]
|
||||
[ext_resource type="Theme" uid="uid://c53fg2fg071yp" path="res://Asserts/defalutTheme.tres" id="2_8jwne"]
|
||||
[ext_resource type="Theme" uid="uid://intlbeu8h82r" path="res://Asserts/defaultTheme.tres" id="2_afihr"]
|
||||
|
||||
[node name="Main" type="Node2D"]
|
||||
script = ExtResource("1_h4cv2")
|
||||
@ -9,7 +9,7 @@ script = ExtResource("1_h4cv2")
|
||||
[node name="Control" type="Control" parent="."]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
theme = ExtResource("2_8jwne")
|
||||
theme = ExtResource("2_afihr")
|
||||
|
||||
[node name="SignlePlayer" type="Button" parent="Control"]
|
||||
layout_mode = 0
|
||||
@ -29,21 +29,21 @@ text = "多人"
|
||||
|
||||
[node name="Label" type="Label" parent="Control"]
|
||||
layout_mode = 0
|
||||
offset_left = 210.0
|
||||
offset_top = 312.0
|
||||
offset_right = 520.0
|
||||
offset_bottom = 498.0
|
||||
offset_left = 191.0
|
||||
offset_top = 265.0
|
||||
offset_right = 501.0
|
||||
offset_bottom = 451.0
|
||||
theme_override_font_sizes/font_size = 48
|
||||
text = "中国象棋"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Setting" type="Button" parent="Control"]
|
||||
visible = false
|
||||
layout_mode = 0
|
||||
offset_left = 249.0
|
||||
offset_top = 1034.0
|
||||
offset_right = 432.0
|
||||
offset_bottom = 1201.0
|
||||
offset_left = 239.0
|
||||
offset_top = 967.0
|
||||
offset_right = 450.0
|
||||
offset_bottom = 1150.0
|
||||
text = "设置"
|
||||
|
||||
[connection signal="pressed" from="Control/SignlePlayer" to="." method="GoToSignlePlayer"]
|
||||
|
@ -1,7 +1,8 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://g40y10iaf7qb"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://g40y10iaf7qb"]
|
||||
|
||||
[ext_resource type="Script" path="res://Scripts/Controllers/ChessGame.cs" id="1_3x8ac"]
|
||||
[ext_resource type="PackedScene" uid="uid://b1tx7v3230wab" path="res://Scenes/Entities/Chessboard.tscn" id="1_yheur"]
|
||||
[ext_resource type="Theme" uid="uid://intlbeu8h82r" path="res://Asserts/defaultTheme.tres" id="3_rcfhx"]
|
||||
|
||||
[node name="ChessGame" type="Node2D"]
|
||||
script = ExtResource("1_3x8ac")
|
||||
@ -10,29 +11,47 @@ script = ExtResource("1_3x8ac")
|
||||
position = Vector2(360, 660)
|
||||
scale = Vector2(2.5, 2.5)
|
||||
|
||||
[node name="Undo" type="Button" parent="."]
|
||||
offset_left = 200.0
|
||||
offset_top = 50.0
|
||||
offset_right = 300.0
|
||||
offset_bottom = 150.0
|
||||
theme_override_font_sizes/font_size = 32
|
||||
text = "撤回"
|
||||
[node name="Control" type="Control" parent="."]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
theme = ExtResource("3_rcfhx")
|
||||
|
||||
[node name="ReInit" type="Button" parent="."]
|
||||
offset_left = 450.0
|
||||
offset_top = 50.0
|
||||
offset_right = 550.0
|
||||
offset_bottom = 150.0
|
||||
theme_override_font_sizes/font_size = 32
|
||||
text = "重开"
|
||||
[node name="Over" type="Button" parent="Control"]
|
||||
layout_mode = 0
|
||||
offset_left = 270.0
|
||||
offset_top = 1105.0
|
||||
offset_right = 449.0
|
||||
offset_bottom = 1209.0
|
||||
text = "结束回合
|
||||
(提示对方结束)"
|
||||
|
||||
[node name="Home" type="Button" parent="."]
|
||||
offset_left = 310.0
|
||||
offset_top = 1108.0
|
||||
offset_right = 412.0
|
||||
offset_bottom = 1226.0
|
||||
[node name="Home" type="Button" parent="Control"]
|
||||
layout_mode = 0
|
||||
offset_left = 55.0
|
||||
offset_top = 56.0
|
||||
offset_right = 157.0
|
||||
offset_bottom = 164.0
|
||||
text = "返回主页"
|
||||
|
||||
[connection signal="pressed" from="Undo" to="." method="Undo"]
|
||||
[connection signal="pressed" from="ReInit" to="." method="ReInit"]
|
||||
[connection signal="pressed" from="Home" to="." method="GoHome"]
|
||||
[node name="Undo" type="Button" parent="Control"]
|
||||
layout_mode = 0
|
||||
offset_left = 319.0
|
||||
offset_top = 58.0
|
||||
offset_right = 419.0
|
||||
offset_bottom = 158.0
|
||||
text = "撤回"
|
||||
|
||||
[node name="ReInit" type="Button" parent="Control"]
|
||||
layout_mode = 0
|
||||
offset_left = 578.0
|
||||
offset_top = 55.0
|
||||
offset_right = 678.0
|
||||
offset_bottom = 155.0
|
||||
text = "重开"
|
||||
|
||||
[connection signal="pressed" from="Control/Over" to="." method="BtnOver"]
|
||||
[connection signal="pressed" from="Control/Home" to="." method="GoHome"]
|
||||
[connection signal="pressed" from="Control/Undo" to="." method="Undo"]
|
||||
[connection signal="pressed" from="Control/ReInit" to="." method="ReInit"]
|
||||
|
@ -1,7 +1,7 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cl8nkm6j8s8jh"]
|
||||
|
||||
[ext_resource type="Script" path="res://Scripts/Controllers/Menu.cs" id="1_chiyi"]
|
||||
[ext_resource type="Theme" uid="uid://c53fg2fg071yp" path="res://Asserts/defalutTheme.tres" id="1_sg40w"]
|
||||
[ext_resource type="Theme" uid="uid://intlbeu8h82r" path="res://Asserts/defaultTheme.tres" id="1_mkeko"]
|
||||
|
||||
[node name="Menu" type="Control"]
|
||||
layout_mode = 3
|
||||
@ -10,7 +10,7 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme = ExtResource("1_sg40w")
|
||||
theme = ExtResource("1_mkeko")
|
||||
script = ExtResource("1_chiyi")
|
||||
metadata/_edit_horizontal_guides_ = [141.0]
|
||||
|
||||
@ -63,9 +63,10 @@ offset_bottom = 1198.0
|
||||
|
||||
[node name="ItemList" type="ItemList" parent="Server"]
|
||||
layout_mode = 0
|
||||
offset_top = 120.0
|
||||
offset_right = 663.0
|
||||
offset_bottom = 965.0
|
||||
offset_left = 15.0
|
||||
offset_top = 214.0
|
||||
offset_right = 678.0
|
||||
offset_bottom = 1059.0
|
||||
|
||||
[node name="ConnectServer" type="Button" parent="Server"]
|
||||
layout_mode = 0
|
||||
@ -113,10 +114,10 @@ size = Vector2i(200, 118)
|
||||
|
||||
[node name="URL" type="LineEdit" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 22.0
|
||||
offset_top = 1166.0
|
||||
offset_right = 662.0
|
||||
offset_bottom = 1247.0
|
||||
offset_left = 37.0
|
||||
offset_top = 290.0
|
||||
offset_right = 677.0
|
||||
offset_bottom = 371.0
|
||||
|
||||
[connection signal="pressed" from="Home" to="." method="goToHome"]
|
||||
[connection signal="pressed" from="Name/Button" to="." method="EnterName"]
|
||||
|
@ -5,7 +5,10 @@ public partial class ChessGame : Node2D
|
||||
{
|
||||
ChessBoard board;
|
||||
Global global;
|
||||
ConfirmationDialog dialog;
|
||||
private bool isSession = false;
|
||||
private Vector2 from;
|
||||
private Vector2 to;
|
||||
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
public override void _Ready()
|
||||
@ -13,11 +16,17 @@ public partial class ChessGame : Node2D
|
||||
// Init.Call();
|
||||
global = GetNode<Global>("/root/Global");
|
||||
board = GetNode<ChessBoard>("Chessboard");
|
||||
// GetNode<Button>("Undo").Connect("pressed", Callable.From(board.Undo));
|
||||
// GetNode<Button>("ReInit").Connect("pressed", Callable.From(board.ReInit));
|
||||
// GetNode<Button>("Home").Connect("pressed", Callable.From(this.GoHome));
|
||||
dialog = new ConfirmationDialog {
|
||||
DialogAutowrap = true,
|
||||
MinSize = new Vector2I(400, 200),
|
||||
Position = new Vector2I(200, 400),
|
||||
};
|
||||
AddChild(dialog);
|
||||
// GetNode<Button>("Undo").Connect("pressed", Callable.From(board.Undo));
|
||||
// GetNode<Button>("ReInit").Connect("pressed", Callable.From(board.ReInit));
|
||||
// GetNode<Button>("Home").Connect("pressed", Callable.From(this.GoHome));
|
||||
|
||||
if (!global.RPClient.GetIsConnected()) {
|
||||
if (!global.RPClient.GetIsConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -28,6 +37,11 @@ public partial class ChessGame : Node2D
|
||||
};
|
||||
board.Set("Hello", Callable.From(() => {GD.PrintErr("hello");}));
|
||||
board.Set("chessMoveFunc", Callable.From((Vector2 newPos, Vector2 fromPos) => {
|
||||
if (from.X == fromPos.X && from.Y == fromPos.Y && to.X == newPos.X && to.Y == newPos.Y) {
|
||||
return true;
|
||||
}
|
||||
from = fromPos;
|
||||
to = newPos;
|
||||
var res = global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
|
||||
{"type", "move"},
|
||||
{"from", fromPos},
|
||||
@ -50,25 +64,58 @@ public partial class ChessGame : Node2D
|
||||
}
|
||||
|
||||
private void SessionMsgHandle(Dictionary msg) {
|
||||
// GD.PrintErr($"session msg: {msg}");
|
||||
GD.PrintErr($"session msg: {msg}");
|
||||
switch (msg["type"].AsString()) {
|
||||
case "over":
|
||||
if (global.RPClient.GetUserId() == msg["id"].AsString()) {
|
||||
break;
|
||||
}
|
||||
dialog.Title = "Opponent Finished";
|
||||
dialog.DialogText = "Turn On You\n";
|
||||
dialog.Visible = true;
|
||||
break;
|
||||
case "move":
|
||||
Vector2 to = new(GD.StrToVar(msg["toX"].ToString()).AsInt32(),
|
||||
Vector2 _to = new(GD.StrToVar(msg["toX"].ToString()).AsInt32(),
|
||||
GD.StrToVar(msg["toY"].ToString()).AsInt32());
|
||||
|
||||
Vector2 from = new(GD.StrToVar(msg["fromX"].ToString()).AsInt32(),
|
||||
Vector2 _from = new(GD.StrToVar(msg["fromX"].ToString()).AsInt32(),
|
||||
GD.StrToVar(msg["fromY"].ToString()).AsInt32());
|
||||
board.MoveAndRecord(to, from);
|
||||
if (_to.X == to.X && _to.Y == to.Y && _from.X == from.X && _from.Y == from.Y) {
|
||||
return;
|
||||
}
|
||||
to = _to;
|
||||
from = _from;
|
||||
board.playerSelf.MoveAndRecord(to, from);
|
||||
break;
|
||||
case "undo":
|
||||
board.Undo();
|
||||
_Undo();
|
||||
break;
|
||||
case "reInit":
|
||||
board.ReInit();
|
||||
_ReInit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void _Undo() {
|
||||
board.playerSelf.Undo();
|
||||
}
|
||||
|
||||
private void _ReInit() {
|
||||
board.playerSelf.ReInit();
|
||||
board.InitChessBoard();
|
||||
}
|
||||
|
||||
private void BtnOver() {
|
||||
GD.PrintErr($"BtnOver {isSession}");
|
||||
if (isSession == false) {
|
||||
return;
|
||||
}
|
||||
global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
|
||||
{"type", "over"},
|
||||
{"id", global.RPClient.GetUserId()},
|
||||
});
|
||||
}
|
||||
|
||||
public void GoHome() {
|
||||
if (global.RPClient.IsOnline()) {
|
||||
global.RPClient.ExitServer();
|
||||
@ -79,9 +126,7 @@ public partial class ChessGame : Node2D
|
||||
public void Undo() {
|
||||
GD.PrintErr($"Undo {isSession}");
|
||||
if (isSession == false) {
|
||||
GD.PrintErr($"Undo ??");
|
||||
board.Undo();
|
||||
return;
|
||||
_Undo();
|
||||
}
|
||||
global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
|
||||
{"type", "undo"},
|
||||
@ -91,8 +136,7 @@ public partial class ChessGame : Node2D
|
||||
public void ReInit() {
|
||||
GD.PrintErr($"ReInit {isSession}");
|
||||
if (isSession == false) {
|
||||
board.ReInit();
|
||||
return;
|
||||
_ReInit();
|
||||
}
|
||||
global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
|
||||
{"type", "reInit"},
|
||||
|
127
Scripts/Controllers/Player.cs
Normal file
127
Scripts/Controllers/Player.cs
Normal file
@ -0,0 +1,127 @@
|
||||
using Godot;
|
||||
|
||||
public class Player
|
||||
{
|
||||
private VirtualBoard board;
|
||||
private SelectedPiece selectedNode;
|
||||
private MoveRecords<VirtualPiece> moveRecords;
|
||||
|
||||
public enum PlayerType {
|
||||
Human,
|
||||
AI
|
||||
}
|
||||
|
||||
public Player(VirtualBoard board, PlayerType type = PlayerType.Human)
|
||||
{
|
||||
this.board = board;
|
||||
this.selectedNode = new SelectedPiece(board);
|
||||
this.moveRecords = new MoveRecords<VirtualPiece>(onUndoRecordCallback: (newNode, oldNode, newPos, oldPos) => {
|
||||
GD.Print("Undo: ", newNode, "->", oldNode, ":", newPos, "->", oldPos);
|
||||
VirtualPiece newPiece = newNode;
|
||||
VirtualPiece oldPiece = oldNode;
|
||||
this.board.MovePiece(newPos, oldPos);
|
||||
if (newPiece != null) {
|
||||
this.board.InsertPiece(newPiece, newPos);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void HandleBoardPosClick(Vector2 clickPos) {
|
||||
if (board.ArrPosOutOfRange(clickPos)) return;
|
||||
GD.Print($"VirtualBoard {clickPos} clicked");
|
||||
VirtualPiece clickChess = board.GetPiece(clickPos);
|
||||
|
||||
if (!selectedNode.HasSelected()) {
|
||||
// Select piece
|
||||
if (clickChess == null) {
|
||||
// selectedNode.Clear();
|
||||
return;
|
||||
}
|
||||
selectedNode.SetPos(clickPos);
|
||||
} else if (clickChess == selectedNode.GetPiece()) {
|
||||
// Unselect piece
|
||||
selectedNode.Clear();
|
||||
} else {
|
||||
// Move piece
|
||||
GD.Print("default MoveFunc Move: ", selectedNode.GetPos(), "->", clickPos);
|
||||
MoveAndRecord(clickPos, selectedNode.GetPos());
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveAndRecord(Vector2 toPos, Vector2 fromPos) {
|
||||
GD.Print($"{fromPos} move to {toPos}");
|
||||
VirtualPiece toChess = board.GetPiece(toPos);
|
||||
VirtualPiece fromChess = board.GetPiece(fromPos);
|
||||
fromChess?.Selected(false);
|
||||
|
||||
VirtualPiece NowNode;
|
||||
if (toChess != null) {
|
||||
NowNode = toChess;
|
||||
board.RemovePiece(toPos);
|
||||
} else {
|
||||
NowNode = toChess;
|
||||
}
|
||||
moveRecords.AddRecord(NowNode, fromChess, toPos, fromPos);
|
||||
board.MovePiece(fromPos, toPos);
|
||||
|
||||
selectedNode.Clear();
|
||||
}
|
||||
|
||||
public void Undo() {
|
||||
// ChessPiece selected = selectedNode.GetPiece();
|
||||
// selected?.DeSelected();
|
||||
selectedNode.Clear();
|
||||
moveRecords.Undo();
|
||||
}
|
||||
|
||||
public void ReInit() {
|
||||
moveRecords.Clear();
|
||||
board.Clear();
|
||||
selectedNode.Clear();
|
||||
// board.InitChessBoard();
|
||||
}
|
||||
|
||||
private class SelectedPiece
|
||||
{
|
||||
// Called when the node enters the scene tree for the first time.
|
||||
private Vector2 selectedNodePos = Vector2.Inf;
|
||||
private VirtualPiece piece;
|
||||
private VirtualBoard board;
|
||||
|
||||
public SelectedPiece(VirtualBoard board)
|
||||
{
|
||||
this.board = board;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
if (selectedNodePos != Vector2.Inf) {
|
||||
selectedNodePos = Vector2.Inf;
|
||||
piece.Selected(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPos(Vector2 pos)
|
||||
{
|
||||
// piece = board.GetNodeFromBoard(pos) as VirtualPiece;
|
||||
selectedNodePos = pos;
|
||||
piece = board.GetPiece(selectedNodePos);
|
||||
piece.Selected(true);
|
||||
}
|
||||
|
||||
public VirtualPiece GetPiece()
|
||||
{
|
||||
return piece;
|
||||
}
|
||||
|
||||
public Vector2 GetPos()
|
||||
{
|
||||
return selectedNodePos;
|
||||
}
|
||||
|
||||
public bool HasSelected()
|
||||
{
|
||||
return selectedNodePos != Vector2.Inf;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -1,23 +1,25 @@
|
||||
// using System.Numerics;
|
||||
using Godot;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using Godot;
|
||||
using System.Linq;
|
||||
|
||||
public class MoveRecords {
|
||||
public class MoveRecords<T> {
|
||||
private readonly LinkedList<MoveRecord> records = new LinkedList<MoveRecord>(); // 使用队列替换栈
|
||||
private readonly int maxRecords; // 记录上限
|
||||
private Action<Node, Node, Vector2, Vector2> onAddRecordCallback; // 添加记录时的回调
|
||||
private Action<Node, Node, Vector2, Vector2> onUndoRecordCallback; // 撤销记录时的回调
|
||||
private Action<T, T, Vector2, Vector2> onAddRecordCallback; // 添加记录时的回调
|
||||
private Action<T, T, Vector2, Vector2> onUndoRecordCallback; // 撤销记录时的回调
|
||||
|
||||
public MoveRecords(
|
||||
Action<Node, Node, Vector2, Vector2> onAddRecordCallback = null,
|
||||
Action<Node, Node, Vector2, Vector2> onUndoRecordCallback = null,
|
||||
Action<T, T, Vector2, Vector2> onAddRecordCallback = null,
|
||||
Action<T, T, Vector2, Vector2> onUndoRecordCallback = null,
|
||||
int maxRecords = 32) {
|
||||
this.maxRecords = maxRecords;
|
||||
this.onAddRecordCallback = onAddRecordCallback;
|
||||
this.onUndoRecordCallback = onUndoRecordCallback;
|
||||
}
|
||||
|
||||
public void AddRecord(Node newNode, Node oldNode, Vector2 newPos, Vector2 oldPos) {
|
||||
public void AddRecord(T newNode, T oldNode, Vector2 newPos, Vector2 oldPos) {
|
||||
// 达到记录上限时,移除最远的记录(队首元素)
|
||||
if (records.Count >= maxRecords) {
|
||||
records.RemoveFirst();
|
||||
@ -42,16 +44,16 @@ public class MoveRecords {
|
||||
}
|
||||
|
||||
private class MoveRecord {
|
||||
public Node NewNode { get; }
|
||||
public Node OldNode { get; }
|
||||
public T NewNode { get; }
|
||||
public T OldNode { get; }
|
||||
public Vector2 NewPos { get; }
|
||||
public Vector2 OldPos { get; }
|
||||
|
||||
public MoveRecord(Node newNode, Node oldNode, Vector2 newPos, Vector2 oldPos) {
|
||||
this.NewNode = newNode;
|
||||
this.OldNode = oldNode;
|
||||
this.OldPos = oldPos;
|
||||
this.NewPos = newPos;
|
||||
public MoveRecord(T newNode, T oldNode, Vector2 newPos, Vector2 oldPos) {
|
||||
NewNode = newNode;
|
||||
OldNode = oldNode;
|
||||
OldPos = oldPos;
|
||||
NewPos = newPos;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,316 +1,74 @@
|
||||
// using System.Numerics;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
class VirtualBoard {
|
||||
private static readonly int boradRows = 9;
|
||||
private static readonly int boradCols = 10;
|
||||
private readonly Node BoardRoot;
|
||||
private readonly Node[,] nodesBorad = new Node[boradRows, boradCols];
|
||||
public class VirtualBoard {
|
||||
private readonly int Rows;
|
||||
private readonly int Cols;
|
||||
private readonly VirtualPiece[,] pieces;
|
||||
|
||||
public static bool ArrPosOutOfRange(Vector2 arrayPos) {
|
||||
return arrayPos.X < 0 || arrayPos.X >= boradRows || arrayPos.Y < 0 || arrayPos.Y >= boradCols;
|
||||
// <oldPiece, newPiece>
|
||||
public event Action<VirtualPiece, VirtualPiece> OnSetPiecePos;
|
||||
public event Action<VirtualPiece> OnInsert;
|
||||
public event Action<VirtualPiece> OnRemove;
|
||||
public event Action<Vector2, Vector2> OnMove;
|
||||
|
||||
public VirtualBoard(int Rows, int Cols) {
|
||||
this.Rows = Rows;
|
||||
this.Cols = Cols;
|
||||
pieces = new VirtualPiece[Rows, Cols];
|
||||
}
|
||||
|
||||
public Node GetNodeFromBoard(Vector2 arrayPos) {
|
||||
public bool ArrPosOutOfRange(Vector2 arrayPos) {
|
||||
return arrayPos.X < 0 || arrayPos.X >= Rows || arrayPos.Y < 0 || arrayPos.Y >= Cols;
|
||||
}
|
||||
|
||||
public VirtualPiece GetPiece(Vector2 arrayPos) {
|
||||
if (ArrPosOutOfRange(arrayPos)) return null;
|
||||
return nodesBorad[(int)arrayPos.X, (int)arrayPos.Y];
|
||||
return pieces[(int)arrayPos.X, (int)arrayPos.Y];
|
||||
}
|
||||
|
||||
public void SetNodeToBoard(Vector2 arrayPos, Node node) {
|
||||
if (ArrPosOutOfRange(arrayPos)) return;
|
||||
nodesBorad[(int)arrayPos.X, (int)arrayPos.Y] = node;
|
||||
public VirtualPiece SetPiecePos(VirtualPiece piece, Vector2 arrayPos) {
|
||||
VirtualPiece ret = null;
|
||||
if (ArrPosOutOfRange(arrayPos)) return ret;
|
||||
ret = pieces[(int)arrayPos.X, (int)arrayPos.Y];
|
||||
pieces[(int)arrayPos.X, (int)arrayPos.Y] = piece;
|
||||
OnSetPiecePos?.Invoke(ret, piece);
|
||||
piece?.Move(arrayPos);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public VirtualBoard(Node root = null) {
|
||||
//?? //GetTree().CurrentScene; // 如果未提供root,默认为当前场景
|
||||
BoardRoot = root;
|
||||
}
|
||||
|
||||
public bool MoveNode(Vector2 newPos, Vector2 oldPos) {
|
||||
if (ArrPosOutOfRange(newPos) || ArrPosOutOfRange(oldPos)) {
|
||||
return false;
|
||||
}
|
||||
if (GetNodeFromBoard(newPos) != null) {
|
||||
return false;
|
||||
}
|
||||
if (GetNodeFromBoard(oldPos) is ChessPiece chessPiece) {
|
||||
chessPiece.movePos(newPos);
|
||||
public bool InsertPiece(VirtualPiece piece, Vector2 arrayPos) {
|
||||
if (GetPiece(arrayPos) != null) {
|
||||
return false;
|
||||
}
|
||||
SetNodeToBoard(newPos, GetNodeFromBoard(oldPos));
|
||||
SetNodeToBoard(oldPos, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemoveNode(Vector2 arrayPos) {
|
||||
if (ArrPosOutOfRange(arrayPos)) return false;
|
||||
if (GetNodeFromBoard(arrayPos) is ChessPiece chessPiece) {
|
||||
chessPiece.QueueFree();
|
||||
}
|
||||
SetNodeToBoard(arrayPos, null);
|
||||
OnInsert?.Invoke(piece);
|
||||
SetPiecePos(piece, arrayPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void InsertNode(ChessPiece chess, Vector2 arrayPos) {
|
||||
chess.Position = PosTrans.transArrToPix * arrayPos;
|
||||
SetNodeToBoard(arrayPos, chess);
|
||||
BoardRoot.AddChild(chess);
|
||||
public bool MovePiece(Vector2 from, Vector2 to) {
|
||||
if (ArrPosOutOfRange(to) || ArrPosOutOfRange(from)) {
|
||||
return false;
|
||||
}
|
||||
if (GetPiece(to) != null) {
|
||||
return false;
|
||||
}
|
||||
OnMove?.Invoke(from, to);
|
||||
SetPiecePos(SetPiecePos(null, from), to);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool RemovePiece(Vector2 pos) {
|
||||
OnRemove?.Invoke(GetPiece(pos));
|
||||
return SetPiecePos(null, pos) != null;
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
foreach (var node in BoardRoot.GetChildren()) {
|
||||
if (node is ChessPiece chessPiece) {
|
||||
RemoveNode(chessPiece.getPos());
|
||||
chessPiece.QueueFree();
|
||||
for (int i = 0; i < Rows; i++) {
|
||||
for (int j = 0; j < Cols; j++) {
|
||||
RemovePiece(new Vector2(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
40
Scripts/Utilities/VirtualPiece.cs
Normal file
40
Scripts/Utilities/VirtualPiece.cs
Normal file
@ -0,0 +1,40 @@
|
||||
// using System.Numerics;
|
||||
using Godot;
|
||||
|
||||
using System;
|
||||
|
||||
public class VirtualPiece {
|
||||
private Vector2 pos; // 注意这个坐标的非像素坐标而是棋盘坐标
|
||||
|
||||
private string name;
|
||||
private bool isSelected;
|
||||
public object data;
|
||||
|
||||
public event Action<Vector2> OnMove;
|
||||
public event Action<bool> OnSelected;
|
||||
|
||||
public void Move(Vector2 pos) {
|
||||
this.pos = pos;
|
||||
OnMove?.Invoke(pos);
|
||||
}
|
||||
|
||||
public Vector2 Pos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
public void Selected(bool isSelected) {
|
||||
if (this.isSelected != isSelected) {
|
||||
OnSelected?.Invoke(isSelected);
|
||||
this.isSelected = isSelected;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
public VirtualPiece(string name = "", Vector2 pos = new Vector2()) {
|
||||
this.name = name;
|
||||
this.pos = pos;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
name="Windows Desktop"
|
||||
platform="Windows Desktop"
|
||||
runnable=false
|
||||
runnable=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
@ -185,7 +185,7 @@ permissions/install_location_provider=false
|
||||
permissions/install_packages=false
|
||||
permissions/install_shortcut=false
|
||||
permissions/internal_system_window=false
|
||||
permissions/internet=false
|
||||
permissions/internet=true
|
||||
permissions/kill_background_processes=false
|
||||
permissions/location_hardware=false
|
||||
permissions/manage_accounts=false
|
||||
|
@ -12,7 +12,7 @@ config_version=5
|
||||
|
||||
config/name="Chinese_Chess"
|
||||
run/main_scene="res://Main.tscn"
|
||||
config/features=PackedStringArray("4.2", "C#", "Mobile")
|
||||
config/features=PackedStringArray("4.3", "C#", "Mobile")
|
||||
config/icon="res://Asserts/icon.svg"
|
||||
|
||||
[autoload]
|
||||
@ -23,7 +23,6 @@ Global="*res://Scripts/Global.cs"
|
||||
|
||||
window/size/viewport_width=720
|
||||
window/size/viewport_height=1280
|
||||
window/size/always_on_top=true
|
||||
window/stretch/mode="viewport"
|
||||
window/handheld/orientation=1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user