add 新增远程连接,实现多人游戏

This commit is contained in:
ZZY
2024-06-27 15:02:57 +08:00
parent d892cd6c0e
commit 9a79bef410
23 changed files with 1167 additions and 211 deletions

View File

@ -0,0 +1,101 @@
using Godot;
using Godot.Collections;
public partial class ChessGame : Node2D
{
ChessBoard board;
Global global;
private bool isSession = false;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
// 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));
if (!global.RPClient.GetIsConnected()) {
return;
}
isSession = true;
GD.Print("ws is connected");
global.RPClient.OnPRCSessionExit += (cmd, code) => {
GoHome();
};
board.Set("Hello", Callable.From(() => {GD.PrintErr("hello");}));
board.Set("chessMoveFunc", Callable.From((Vector2 newPos, Vector2 fromPos) => {
var res = global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
{"type", "move"},
{"from", fromPos},
{"to", newPos},
{"fromX", fromPos.X},
{"fromY", fromPos.Y},
{"toX", newPos.X},
{"toY", newPos.Y},
});
GD.Print($"chessMoveFunc Callback {fromPos} -> {newPos} {res}");
return false;
}));
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) {
}
private void SessionMsgHandle(Dictionary msg) {
// GD.PrintErr($"session msg: {msg}");
switch (msg["type"].AsString()) {
case "move":
Vector2 to = new(GD.StrToVar(msg["toX"].ToString()).AsInt32(),
GD.StrToVar(msg["toY"].ToString()).AsInt32());
Vector2 from = new(GD.StrToVar(msg["fromX"].ToString()).AsInt32(),
GD.StrToVar(msg["fromY"].ToString()).AsInt32());
board.MoveAndRecord(to, from);
break;
case "undo":
board.Undo();
break;
case "reInit":
board.ReInit();
break;
}
}
public void GoHome() {
if (global.RPClient.IsOnline()) {
global.RPClient.ExitServer();
}
global.GotoScene("res://Main.tscn");
}
public void Undo() {
GD.PrintErr($"Undo {isSession}");
if (isSession == false) {
GD.PrintErr($"Undo ??");
board.Undo();
return;
}
global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
{"type", "undo"},
});
}
public void ReInit() {
GD.PrintErr($"ReInit {isSession}");
if (isSession == false) {
board.ReInit();
return;
}
global.RPClient.SendSessionToAll(global.sessionId, new Dictionary{
{"type", "reInit"},
});
}
}

136
Scripts/Controllers/Menu.cs Normal file
View File

@ -0,0 +1,136 @@
using Godot;
using Godot.Collections;
public partial class Menu : Control
{
Global global = null;
ItemList lists = null;
ConfirmationDialog dialog = null;
LineEdit nameLineEdit = null;
LineEdit urlLineEdit = null;
ColorRect colorRect = null;
Timer timer = null;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
global = GetNode<Global>("/root/Global");
nameLineEdit = GetNode<LineEdit>("Name/LineEdit");
urlLineEdit = GetNode<LineEdit>("URL");
urlLineEdit.Text = global.URL;
urlLineEdit.Set("text_submitted", Callable.From(()=>{
global.URL = urlLineEdit.Text;
}));
lists = GetNode<ItemList>("Server/ItemList");
dialog = GetNode<ConfirmationDialog>("Dialogs/ConfirmationDialog");
colorRect = GetNode<ColorRect>("Server/ColorRect");
dialog.DialogAutowrap = true;
dialog.MinSize = new Vector2I(400, 200);
dialog.Canceled += () => {
if (dialog.Title == "Session Created")
global.RPClient.SessionAckCreate(dialog.GetMeta("sessionId").ToString(), false);
};
dialog.Confirmed += () => {
// GD.PrintErr("confirm", dialog.GetLabel().Text);
// goToSignle();
if (dialog.Title == "Session Created")
global.RPClient.SessionAckCreate(dialog.GetMeta("sessionId").ToString(), true);
};
global.RPClient.RegSessionAckCreateCallback((
sessionId,
res,
reqUserId,
reqUserName) => {
if (reqUserId != null) {
dialog.Title = "Session Created";
dialog.SetMeta("reqUserName", reqUserName);
dialog.SetMeta("reqUserId", reqUserId);
dialog.SetMeta("sessionId", sessionId);
// dialog.GetLabel==>Text = $"{sessdata["reqUserName"]}";
dialog.DialogText = $"username: {reqUserName}\n" +
$"reqUserId: {reqUserId}\n";
dialog.Visible = true;
} else {
if (res) {
global.sessionId = sessionId;
global.GotoScene("res://Scenes/ChessGame.tscn");
} else {
dialog.Title = "Failed";
dialog.DialogText = $"session create failed";
dialog.Visible = true;
}
}
return true;
});
timer = new Timer();
AddChild(timer);
timer.Connect("timeout", Callable.From(() => {
if (global.RPClient.GetIsConnected()) {
colorRect.Color = Colors.Green;
} else {
colorRect.Color = Colors.Red;
}
}));
timer.Start(1);
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta) {
}
private void OnItemSelected(int index) {
Dictionary item = lists.GetItemMetadata(index).AsGodotDictionary();
GD.Print($"Item {index} selected, {item}");
string[] strings = { item["id"].ToString() };
global.RPClient.SessionCreate(strings);
}
private void FlushData()
{
global.RPClient.RegionInspect("server", (data) => {
GD.Print(data);
lists.Clear();
foreach (Dictionary<string, string> user in data) {
string userId = user["id"].ToString();
string userName = user["name"].ToString();
if (userId == global.RPClient.GetUserId()) {
lists.SetItemDisabled(
lists.AddItem($"Name: {userName}"),
true);
continue;
}
var idx = lists.AddItem($"Name: {userName}");
lists.SetItemMetadata(idx, user);
lists.SetItemTooltip(idx, $"User ID: {userId}");
}
return true;
});
}
public void Connect()
{
GD.Print("Connect");
global.RPClient.ExitServer();
global.RPClient.ConnectToUrlEx(urlLineEdit.Text);
global.SetProcess(true);
}
public void EnterName() {
var newLine = nameLineEdit.Text;
global.RPClient.UserRename(newLine);
nameLineEdit.Text = newLine;
}
private void goToHome() {
global.RPClient.ExitServer();
global.GotoScene("res://Main.tscn");
}
// private void OnItemListItemClicked(int index, Vector2 atPosition, int mouse_button_index)
// {
// GD.Print($"Item {index} clicked at {atPosition} with mouse button index {mouse_button_index}");
// }
}