一个里程碑(可以联机了)

This commit is contained in:
2025-09-24 20:07:32 +08:00
parent 5f080713f8
commit 659827bcc3
20 changed files with 282 additions and 288 deletions

View File

@@ -1,18 +1,20 @@
package uno.mloluyu.network;
import com.badlogic.gdx.Gdx;
import java.util.ArrayList;
import java.util.List;
/**
* 网络管理器,协调服务器和客户端通信
*/
import java.util.HashMap;
import java.util.Map;
public class NetworkManager {
private static NetworkManager instance;
private ConnectServer server;
private ConnectClient client;
private boolean isHost = false;
private List<String> playerPositions = new ArrayList<>();
private String localPlayerId;
private String localCharacter;
private final Map<String, float[]> playerPositions = new HashMap<>();
private final Map<String, String> playerCharacters = new HashMap<>();
public static NetworkManager getInstance() {
if (instance == null) {
@@ -21,67 +23,91 @@ public class NetworkManager {
return instance;
}
/**
* 创建房间(作为主机)
*/
public void setLocalPlayerId(String id) {
this.localPlayerId = id;
}
public String getLocalPlayerId() {
return localPlayerId;
}
public void createRoom() {
isHost = true;
server = new ConnectServer(11455);
new Thread(server).start();
Gdx.app.log("Network", "间创建成功,等待其他玩家加入...");
Gdx.app.log("Network", "主模式:服务器已启动");
}
/**
* 加入房间(作为客户端)
*/
public void joinRoom(String ip) {
isHost = false;
client = new ConnectClient(ip, 11455);
Gdx.app.log("Network", "正在加入房间: " + ip);
Gdx.app.log("Network", "客户端模式:连接到房主 " + ip);
}
/**
* 发送玩家位置信息
*/
public void sendPosition(float x, float y) {
String msg = "POS:" + localPlayerId + "," + x + "," + y;
Gdx.app.log("Network", "发送位置消息: " + msg);
if (isHost && server != null) {
// 主机直接广播位置
broadcastMessage("POS:" + x + "," + y);
server.broadcastToOthers(null, msg);
receiveMessage(msg); // 房主自己也处理
} else if (client != null) {
// 客户端发送位置到服务器
client.sendMessage("POS:" + x + "," + y);
client.sendMessage(msg);
}
}
/**
* 广播消息(主机使用)
*/
private void broadcastMessage(String message) {
// 这里需要实现广播逻辑
Gdx.app.log("Network", "广播消息: " + message);
public void sendCharacterSelection(String character) {
this.localCharacter = character;
String msg = "SELECT:" + localPlayerId + "," + character;
Gdx.app.log("Network", "发送角色选择消息: " + msg);
if (isHost && server != null) {
server.broadcastToOthers(null, msg);
receiveMessage(msg);
} else if (client != null) {
client.sendMessage(msg);
}
}
/**
* 获取其他玩家位置
*/
public List<String> getOtherPlayerPositions() {
public void receiveMessage(String message) {
Gdx.app.log("Network", "收到消息: " + message);
if (message.startsWith("POS:")) {
String[] parts = message.substring(4).split(",");
if (parts.length == 3) {
String playerId = parts[0];
try {
float x = Float.parseFloat(parts[1]);
float y = Float.parseFloat(parts[2]);
playerPositions.put(playerId, new float[]{x, y});
Gdx.app.log("Network", "位置更新: " + playerId + " -> " + x + "," + y);
} catch (NumberFormatException e) {
Gdx.app.error("Network", "位置解析失败: " + message);
}
} else {
Gdx.app.error("Network", "位置消息格式错误: " + message);
}
} else if (message.startsWith("SELECT:")) {
String[] parts = message.substring(7).split(",");
if (parts.length == 2) {
String playerId = parts[0];
String character = parts[1];
playerCharacters.put(playerId, character);
Gdx.app.log("Network", "角色选择: " + playerId + " -> " + character);
} else {
Gdx.app.error("Network", "角色选择消息格式错误: " + message);
}
} else if (message.equals("READY")) {
Gdx.app.log("Network", "收到准备信号");
} else {
Gdx.app.log("Network", "未知消息类型: " + message);
}
}
public Map<String, float[]> getPlayerPositions() {
return playerPositions;
}
/**
* 断开连接
*/
public void disconnect() {
if (server != null) {
server.dispose();
server = null;
}
if (client != null) {
client.disconnect();
client = null;
}
playerPositions.clear();
Gdx.app.log("Network", "网络连接已断开");
public Map<String, String> getPlayerCharacters() {
return playerCharacters;
}
public boolean isHost() {
@@ -92,15 +118,17 @@ public class NetworkManager {
return server != null || client != null;
}
public void updatePlayerPosition(String positionData) {
// 简单实现:直接存储位置数据
playerPositions.add(positionData);
// 限制位置列表大小,避免内存泄漏
if (playerPositions.size() > 10) {
playerPositions.remove(0);
public void disconnect() {
if (server != null) {
server.dispose();
server = null;
}
Gdx.app.log("Network", "更新其他玩家位置: " + positionData);
if (client != null) {
client.disconnect();
client = null;
}
playerPositions.clear();
playerCharacters.clear();
Gdx.app.log("Network", "已断开连接");
}
}