diff --git a/Scenes/ChessGame.tscn b/Scenes/ChessGame.tscn index 8d641f5..aece1f0 100644 --- a/Scenes/ChessGame.tscn +++ b/Scenes/ChessGame.tscn @@ -8,7 +8,7 @@ script = ExtResource("1_3x8ac") [node name="Chessboard" parent="." instance=ExtResource("1_yheur")] -position = Vector2(360, 600) +position = Vector2(360, 650) scale = Vector2(2.5, 2.5) [node name="Control" type="Control" parent="."] @@ -19,41 +19,69 @@ offset_right = 720.0 offset_bottom = 1280.0 theme = ExtResource("3_rcfhx") -[node name="MarginContainer" type="MarginContainer" parent="Control"] +[node name="VBoxContainer" type="VBoxContainer" parent="Control"] layout_mode = 1 anchors_preset = 10 anchor_right = 1.0 -offset_bottom = 81.0 +offset_bottom = 133.0 grow_horizontal = 2 -[node name="HBoxContainer" type="HBoxContainer" parent="Control/MarginContainer"] +[node name="MarginContainer" type="MarginContainer" parent="Control/VBoxContainer"] layout_mode = 2 -[node name="MarginContainer" type="MarginContainer" parent="Control/MarginContainer/HBoxContainer"] +[node name="HBoxContainer" type="HBoxContainer" parent="Control/VBoxContainer/MarginContainer"] +layout_mode = 2 + +[node name="MarginContainer" type="MarginContainer" parent="Control/VBoxContainer/MarginContainer/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 -[node name="Home" type="Button" parent="Control/MarginContainer/HBoxContainer/MarginContainer"] +[node name="Home" type="Button" parent="Control/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer"] layout_mode = 2 text = "返回主页" -[node name="MarginContainer2" type="MarginContainer" parent="Control/MarginContainer/HBoxContainer"] +[node name="MarginContainer2" type="MarginContainer" parent="Control/VBoxContainer/MarginContainer/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 -[node name="Undo" type="Button" parent="Control/MarginContainer/HBoxContainer/MarginContainer2"] +[node name="Undo" type="Button" parent="Control/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2"] layout_mode = 2 size_flags_vertical = 4 text = "撤回" -[node name="MarginContainer3" type="MarginContainer" parent="Control/MarginContainer/HBoxContainer"] +[node name="MarginContainer3" type="MarginContainer" parent="Control/VBoxContainer/MarginContainer/HBoxContainer"] layout_mode = 2 size_flags_horizontal = 3 -[node name="ReInit" type="Button" parent="Control/MarginContainer/HBoxContainer/MarginContainer3"] +[node name="ReInit" type="Button" parent="Control/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer3"] layout_mode = 2 text = "重开" +[node name="MarginContainer3" type="MarginContainer" parent="Control/VBoxContainer"] +layout_mode = 2 + +[node name="HFlowContainer" type="HFlowContainer" parent="Control/VBoxContainer/MarginContainer3"] +layout_mode = 2 + +[node name="Label" type="Label" parent="Control/VBoxContainer/MarginContainer3/HFlowContainer"] +layout_mode = 2 +text = "You Are +" + +[node name="LineEdit" type="LineEdit" parent="Control/VBoxContainer/MarginContainer3/HFlowContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +editable = false + +[node name="Label2" type="Label" parent="Control/VBoxContainer/MarginContainer3/HFlowContainer"] +layout_mode = 2 +text = "Turns On" + +[node name="LineEdit2" type="LineEdit" parent="Control/VBoxContainer/MarginContainer3/HFlowContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +editable = false + [node name="MarginContainer2" type="MarginContainer" parent="Control"] layout_mode = 1 anchors_preset = 12 @@ -69,7 +97,7 @@ layout_mode = 2 text = "结束回合 (提示对方结束)" -[connection signal="pressed" from="Control/MarginContainer/HBoxContainer/MarginContainer/Home" to="." method="GoHome"] -[connection signal="pressed" from="Control/MarginContainer/HBoxContainer/MarginContainer2/Undo" to="." method="Undo"] -[connection signal="pressed" from="Control/MarginContainer/HBoxContainer/MarginContainer3/ReInit" to="." method="ReInit"] +[connection signal="pressed" from="Control/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer/Home" to="." method="GoHome"] +[connection signal="pressed" from="Control/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer2/Undo" to="." method="Undo"] +[connection signal="pressed" from="Control/VBoxContainer/MarginContainer/HBoxContainer/MarginContainer3/ReInit" to="." method="ReInit"] [connection signal="pressed" from="Control/MarginContainer2/Over" to="." method="BtnOver"] diff --git a/Scenes/Menu.tscn b/Scenes/Menu.tscn deleted file mode 100644 index b5d3c8c..0000000 --- a/Scenes/Menu.tscn +++ /dev/null @@ -1,128 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://bc7w0h2x4bbdh"] - -[ext_resource type="Script" path="res://Scripts/Controllers/Menu.cs" id="1_chiyi"] -[ext_resource type="Theme" uid="uid://intlbeu8h82r" path="res://Asserts/defaultTheme.tres" id="1_mkeko"] - -[node name="Menu" type="Control"] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme = ExtResource("1_mkeko") -script = ExtResource("1_chiyi") -metadata/_edit_horizontal_guides_ = [141.0] -metadata/_edit_use_anchors_ = true - -[node name="Home" type="Button" parent="."] -layout_mode = 0 -offset_left = 49.0 -offset_top = 100.0 -offset_right = 171.0 -offset_bottom = 170.0 -text = "返回主页" - -[node name="Name" type="Control" parent="."] -anchors_preset = 0 -offset_left = 215.0 -offset_top = 109.0 -offset_right = 697.0 -offset_bottom = 168.0 - -[node name="Label" type="Label" parent="Name"] -layout_mode = 2 -offset_left = 2.0 -offset_top = 1.0 -offset_right = 80.0 -offset_bottom = 47.0 -text = "名字" -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="LineEdit" type="LineEdit" parent="Name"] -layout_mode = 2 -offset_left = 93.0 -offset_right = 320.0 -offset_bottom = 50.0 - -[node name="Button" type="Button" parent="Name"] -layout_mode = 0 -offset_left = 340.0 -offset_top = 3.0 -offset_right = 428.0 -offset_bottom = 55.0 -text = "确认修改 -" - -[node name="Server" type="Control" parent="."] -anchors_preset = 0 -offset_left = 19.0 -offset_top = 184.0 -offset_right = 705.0 -offset_bottom = 1198.0 - -[node name="ItemList" type="ItemList" parent="Server"] -layout_mode = 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 -offset_left = 297.0 -offset_top = 17.0 -offset_right = 517.0 -offset_bottom = 90.0 -text = "重连服务器" - -[node name="Flush" type="Button" parent="Server"] -layout_mode = 0 -offset_left = 535.0 -offset_top = 17.0 -offset_right = 652.0 -offset_bottom = 81.0 -text = "Flush" - -[node name="ColorRect" type="ColorRect" parent="Server"] -layout_mode = 0 -offset_left = 236.0 -offset_top = 35.0 -offset_right = 276.0 -offset_bottom = 75.0 - -[node name="Label" type="Label" parent="Server"] -layout_mode = 0 -offset_left = 19.0 -offset_top = 37.0 -offset_right = 229.0 -offset_bottom = 79.0 -text = "服务器连接状态" - -[node name="Dialogs" type="Control" parent="."] -anchors_preset = 0 - -[node name="AcceptDialog" type="AcceptDialog" parent="Dialogs"] -initial_position = 2 -size = Vector2i(100, 118) - -[node name="PopupMenu" type="PopupMenu" parent="Dialogs"] - -[node name="ConfirmationDialog" type="ConfirmationDialog" parent="Dialogs"] -initial_position = 2 -size = Vector2i(200, 118) - -[node name="URL" type="LineEdit" parent="."] -visible = false -layout_mode = 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"] -[connection signal="item_activated" from="Server/ItemList" to="." method="OnItemSelected"] -[connection signal="pressed" from="Server/ConnectServer" to="." method="Connect"] -[connection signal="pressed" from="Server/Flush" to="." method="FlushData"] diff --git a/Scenes/Setting.tscn b/Scenes/Setting.tscn index c080b06..46b5c9e 100644 --- a/Scenes/Setting.tscn +++ b/Scenes/Setting.tscn @@ -147,6 +147,7 @@ size_flags_horizontal = 3 text = "GetUserDataDir" [connection signal="pressed" from="BoxContainer/MarginContainer/Back" to="." method="OnBack"] +[connection signal="pressed" from="BoxContainer/MarginContainer7/Button" to="." method="OnSave"] [connection signal="text_changed" from="BoxContainer/MarginContainer2/Server/LineEdit" to="." method="OnServerUrlChanged"] [connection signal="text_changed" from="BoxContainer/MarginContainer3/Name/LineEdit" to="." method="OnNameChanged"] [connection signal="value_changed" from="BoxContainer/MarginContainer6/FontSizeBar" to="." method="OnFontSizeChanged"] diff --git a/Scripts/Controllers/ChessGame.cs b/Scripts/Controllers/ChessGame.cs index 082b5d3..0cfb266 100644 --- a/Scripts/Controllers/ChessGame.cs +++ b/Scripts/Controllers/ChessGame.cs @@ -1,8 +1,8 @@ +using System.Collections; using Godot; using Godot.Collections; -public partial class ChessGame : Node2D -{ +public partial class ChessGame : Node2D { ChessBoard board; Global global; ConfirmationDialog dialog; @@ -17,17 +17,14 @@ public partial class ChessGame : Node2D // Init.Call(); global = GetNode("/root/Global"); board = GetNode("Chessboard"); + isSession = global.RPClient.IsOnline(); playerSelf = new Player(board.board, Player.PlayerType.Human); playerOpponent = new Player(board.board, Player.PlayerType.Human); - - board.OnMouseClicked += (sender, clickPosition) => { - Vector2 clickBoardPos = (PosTrans.transArrToPix.AffineInverse() * - clickPosition).Round(); - - playerSelf.HandleBoardPosClick(clickBoardPos); - }; - + InitChessBoard(); + GetNode("Control/VBoxContainer/MarginContainer3/HFlowContainer/LineEdit") + .Text = global.GlobalData["player_color"].AsString(); + GD.PrintErr("ChessGame ", global.RPClient.GetUserId(), ":",global.GlobalData["player_color"]); dialog = new ConfirmationDialog { DialogAutowrap = true, @@ -36,37 +33,76 @@ public partial class ChessGame : Node2D }; AddChild(dialog); - if (!global.RPClient.GetIsConnected()) { - return; + board.OnPosClicked += (sender, pos) => { + if (isSession) { + var res = global.RPClient.SendSessionToAll(global.sessionId, new Dictionary { + {"type", "mouseClicked"}, + {"X", pos.X}, + {"Y", pos.Y}, + {"id", global.RPClient.GetUserId()} + }); + playerSelf.HandleBoardPosClick(pos); + } else { + playerSelf.HandleBoardPosClick(pos); + playerSelf.SetAllowedPieces(null); + } + }; + + if (isSession) { + GD.Print("ws is connected"); + + global.RPClient.OnPRCSessionExit += (cmd, code) => { + GoHome(); + }; + + global.RPClient.OnPRCSessionRecv += (msg) => { + SessionMsgHandle(msg["msg"].AsGodotDictionary()); + }; } - isSession = true; - GD.Print("ws is connected"); - - global.RPClient.OnPRCSessionExit += (cmd, code) => { - GoHome(); - }; - - board.OnMouseClicked += (sender, clickPosition) => { - Vector2 clickBoardPos = (PosTrans.transArrToPix.AffineInverse() * - clickPosition).Round(); - - var res = global.RPClient.SendSessionToAll(global.sessionId, new Dictionary { - {"type", "mouseClicked"}, - {"X", clickBoardPos.X}, - {"Y", clickBoardPos.Y}, - }); - // GD.Print($"chessMoveFunc Callback {fromPos} -> {newPos} {res}"); - }; - - global.RPClient.OnPRCSessionRecv += (msg) => { - SessionMsgHandle(msg["msg"].AsGodotDictionary()); - }; } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { } + public void InitChessBoard() { + ArrayList black = InitializePieces("black", 0, new[] { + ("车", 0, 0), ("马", 1, 0), ("象", 2, 0), + ("士", 3, 0), ("将", 4, 0), ("士", 5, 0), + ("象", 6, 0), ("马", 7, 0), ("车", 8, 0), + ("炮", 1, 2), ("炮", 7, 2), + ("卒", 0, 3), ("卒", 2, 3), ("卒", 4, 3), ("卒", 6, 3), ("卒", 8, 3) + }); + + ArrayList red = InitializePieces("red", 9, new[] { + ("车", 0, -0), ("马", 1, -0), ("象", 2, -0), + ("士", 3, -0), ("将", 4, -0), ("士", 5, -0), + ("象", 6, -0), ("马", 7, -0), ("车", 8, -0), + ("炮", 1, -2), ("炮", 7, -2), + ("卒", 0, -3), ("卒", 2, -3), ("卒", 4, -3), ("卒", 6, -3), ("卒", 8, -3) + }); + if (global.GlobalData["player_color"].AsString() == "red") { + playerSelf.SetAllowedPieces(red); + playerOpponent.SetAllowedPieces(black); + } else { + playerSelf.SetAllowedPieces(black); + playerOpponent.SetAllowedPieces(red); + } + } + + private ArrayList InitializePieces(string color, int baseY, (string label, int x, int y)[] positions) { + ArrayList list = new(); + foreach (var (label, x, y) in positions) { + ChessPiece piece = new ChessPiece { + PieceLabel = label, + LabelColor = new Color(color) + }; + list.Add(piece.GetVirtualPiece()); + board.InsertNode(piece, new Vector2(x, baseY + y)); + } + return list; + } + private void SessionMsgHandle(Dictionary msg) { GD.PrintErr($"session msg: {msg}"); switch (msg["type"].AsString()) { @@ -79,12 +115,18 @@ public partial class ChessGame : Node2D dialog.Visible = true; break; case "mouseClicked": + if (msg["id"].ToString() == global.RPClient.GetUserId()) { + break; + } Vector2 mouseClicked = new(GD.StrToVar(msg["X"].ToString()).AsInt32(), GD.StrToVar(msg["Y"].ToString()).AsInt32()); playerOpponent.HandleBoardPosClick(mouseClicked); break; case "undo": - _Undo(); + if (msg["id"].ToString() == global.RPClient.GetUserId()) { + break; + } + playerOpponent.Undo(); break; case "reInit": _ReInit(); @@ -92,13 +134,9 @@ public partial class ChessGame : Node2D } } - private void _Undo() { - playerSelf.Undo(); - } - private void _ReInit() { playerSelf.ReInit(); - board.InitChessBoard(); + InitChessBoard(); } private void BtnOver() { @@ -123,11 +161,13 @@ public partial class ChessGame : Node2D GD.Print($"Undo {isSession}"); if (isSession) { + playerSelf.Undo(); global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{ {"type", "undo"}, + {"id", global.RPClient.GetUserId()}, }); } else { - _Undo(); + playerSelf.Undo(); } } diff --git a/Scripts/Controllers/GameLobby.cs b/Scripts/Controllers/GameLobby.cs index e657a4d..bb7f53c 100644 --- a/Scripts/Controllers/GameLobby.cs +++ b/Scripts/Controllers/GameLobby.cs @@ -10,6 +10,7 @@ public partial class GameLobby : Control { string URL; string userName; + bool isAcceptedPart = false; // Called when the node enters the scene tree for the first time. public override void _Ready() { @@ -26,8 +27,11 @@ public partial class GameLobby : Control { global.RPClient.SessionAckCreate(dialog.GetMeta("sessionId").ToString(), false); }; dialog.Confirmed += () => { - if (dialog.Title == "Session Created") - global.RPClient.SessionAckCreate(dialog.GetMeta("sessionId").ToString(), true); + if (dialog.Title == "Session Created") { + // FIXME + isAcceptedPart = true; + global.RPClient.SessionAckCreate(dialog.GetMeta("sessionId").ToString(), true); + } }; global.RPClient.OnOpen += (string eventName, object[] args) => { @@ -56,7 +60,14 @@ public partial class GameLobby : Control { dialog.Visible = true; } else { if (res) { + // TODO FIXME global.sessionId = sessionId; + if (!isAcceptedPart) { + global.GlobalData["player_color"] = "red"; + } else { + global.GlobalData["player_color"] = "black"; + } + // GD.PrintErr("sessionId: ", reqUserId, "color: ", global.GlobalData["player_color"].AsString()); global.GotoScene("res://Scenes/ChessGame.tscn"); } else { dialog.Title = "Failed"; diff --git a/Scripts/Controllers/Setting.cs b/Scripts/Controllers/Setting.cs index 7756e95..383f0fe 100644 --- a/Scripts/Controllers/Setting.cs +++ b/Scripts/Controllers/Setting.cs @@ -33,9 +33,13 @@ public partial class Setting : Control } private void OnBack() { - global.SaveConfig(); global.GotoScene("res://Main.tscn", null); } + + private void OnSave() { + global.SaveConfig(); + // OS.Alert("Saved", "Setting"); + } void OnNameChanged(string Value) { diff --git a/Scripts/Entities/ChessBoard.cs b/Scripts/Entities/ChessBoard.cs index bfaea48..e3e337b 100644 --- a/Scripts/Entities/ChessBoard.cs +++ b/Scripts/Entities/ChessBoard.cs @@ -9,6 +9,7 @@ public partial class ChessBoard : Node2D { public delegate bool ChessMoveFunc(Vector2 toPos, Vector2 fromPos); // public Callable chessMoveFunc { get; set; } public event EventHandler OnMouseClicked; + public event EventHandler OnPosClicked; public override void _Ready() { board = new VirtualBoard(9, 10); @@ -29,8 +30,6 @@ public partial class ChessBoard : Node2D { // board.OnMove += (sender, args) => { // // chessMoveFunc.Call(args.To, args.From); // }; - - InitChessBoard(); } public override void _Input(InputEvent @event) { @@ -40,6 +39,8 @@ public partial class ChessBoard : Node2D { // HandleMouseClick(GetGlobalTransformWithCanvas().AffineInverse() * mouseButton.Position); OnMouseClicked?.Invoke(this, GetLocalMousePosition()); + OnPosClicked?.Invoke(this, (PosTrans.transArrToPix.AffineInverse() * + GetLocalMousePosition()).Round()); } } @@ -49,32 +50,4 @@ public partial class ChessBoard : Node2D { // piece.Move(vector); board.SetPiecePos(piece, arrayPos); } - - public void InitChessBoard() { - InitializePieces("black", 0, new[] { - ("车", 0, 0), ("马", 1, 0), ("象", 2, 0), - ("士", 3, 0), ("将", 4, 0), ("士", 5, 0), - ("象", 6, 0), ("马", 7, 0), ("车", 8, 0), - ("炮", 1, 2), ("炮", 7, 2), - ("卒", 0, 3), ("卒", 2, 3), ("卒", 4, 3), ("卒", 6, 3), ("卒", 8, 3) - }); - - InitializePieces("red", 9, new[] { - ("车", 0, -0), ("马", 1, -0), ("象", 2, -0), - ("士", 3, -0), ("将", 4, -0), ("士", 5, -0), - ("象", 6, -0), ("马", 7, -0), ("车", 8, -0), - ("炮", 1, -2), ("炮", 7, -2), - ("卒", 0, -3), ("卒", 2, -3), ("卒", 4, -3), ("卒", 6, -3), ("卒", 8, -3) - }); - } - - private void InitializePieces(string color, int baseY, (string label, int x, int y)[] positions) { - foreach (var (label, x, y) in positions) { - ChessPiece piece = new ChessPiece { - PieceLabel = label, - LabelColor = new Color(color) - }; - InsertNode(piece, new Vector2(x, baseY + y)); - } - } } diff --git a/Scripts/Entities/ChessPiece.cs b/Scripts/Entities/ChessPiece.cs index b63b716..81b8128 100644 --- a/Scripts/Entities/ChessPiece.cs +++ b/Scripts/Entities/ChessPiece.cs @@ -31,7 +31,7 @@ public partial class ChessPiece : Sprite2D { } } - Transform2D transToSeleted = new Transform2D( + Transform2D transToSeleted = new( new Vector2(1.2f, 0), new Vector2(0, 1.2f), new Vector2(0, 0) diff --git a/Scripts/Global.cs b/Scripts/Global.cs index 88e5df0..082881e 100644 --- a/Scripts/Global.cs +++ b/Scripts/Global.cs @@ -16,6 +16,10 @@ public partial class Global : Node {"user_name", "undefined"} }; + public Dictionary GlobalData = new() { + {"player_color", "red"}, + }; + // Called when the node enters the scene tree for the first time. public override void _Ready() { @@ -69,7 +73,7 @@ public partial class Global : Node public override void _Notification(int what) { if (what == NotificationWMCloseRequest) { - SaveConfig(); + // SaveConfig(); RPClient.Close(); GetTree().Quit(); // default behavior } diff --git a/Scripts/Lib/RPClient.cs b/Scripts/Lib/RPClient.cs index 4fe5715..3881fd0 100644 --- a/Scripts/Lib/RPClient.cs +++ b/Scripts/Lib/RPClient.cs @@ -15,7 +15,7 @@ public partial class RPClientBaseEDWS : EventDrivenWebSocket { public RPClientBaseEDWS() : base() { OnText += (text) => { - GD.Print($"response: {text}"); + // GD.Print($"response: {text}"); RPMessage msg = RPHelper.HandleIncomingMessage(text); if (msg.Code != "0000") { OnRPCError?.Invoke(msg.Code, msg.Type, msg.Cmd, msg.Data.ToString()); diff --git a/Scripts/Src/ChineseChess/Player.cs b/Scripts/Src/ChineseChess/Player.cs index d56ccd3..1ca3156 100644 --- a/Scripts/Src/ChineseChess/Player.cs +++ b/Scripts/Src/ChineseChess/Player.cs @@ -7,7 +7,7 @@ public class Player { private readonly SelectedPiece selectedNode; private readonly MoveRecords moveRecords; public EventHandler OnMove; - public ArrayList pieces = new(); + public enum PlayerType { Human, @@ -86,11 +86,16 @@ public class Player { // board.InitChessBoard(); } + public void SetAllowedPieces(ArrayList allowedPieces) { + selectedNode.allowedPieces = allowedPieces; + } + private class SelectedPiece { // Called when the node enters the scene tree for the first time. private Vector2 selectedNodePos = Vector2.Inf; private VirtualPiece piece; private readonly VirtualBoard board; + public ArrayList allowedPieces = null; public SelectedPiece(VirtualBoard board) { this.board = board; @@ -105,8 +110,11 @@ public class Player { public void SetPos(Vector2 pos) { // piece = board.GetNodeFromBoard(pos) as VirtualPiece; + piece = board.GetPiece(pos); + if (allowedPieces != null && allowedPieces.Contains(piece) == false) { + return; + } selectedNodePos = pos; - piece = board.GetPiece(selectedNodePos); piece.Selected(true); }