我正在 libgdx 中制作在线游戏。我正在使用 socket.io 作为服务器,并且正在使用房间。但是我在屏幕更改方面遇到问题。我有两个屏幕类,我仅连接到服务器一次来自城镇类(玩家从城镇开始)。当玩家去武器店时,我向玩家发出 getPlayers 方法。但是 getPlayers 方法在城镇和武器店中调用。当玩家在武器店类中时,我不想在城镇类中调用 getPlayers 方法。
我的套接字变量在 Multiplayer 类中定义,以便随处访问:
public class Multiplayer extends Game {
public static Socket socket;
...
@Override
public void create () {
game = this;
try {
socket = IO.socket("http://localhost:8080");
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
@Override
public void render () {
super.render();
}
}
城镇等级:
public Town() {
...
connectToRoom();
configSocketEvents();
}
private void connectToRoom() {
try {
if (!socket.connected())
socket.connect();
JSONObject data = new JSONObject();
try {
data.put("newroom", "town");
socket.emit("joinRoom", data);
} catch (JSONException e) {
Gdx.app.log("SOCKET.IO", "Error sending update data!");
}
} catch(Exception e) {
System.out.println(e);
}
}
private void configSocketEvents() {
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Gdx.app.log("SocketIO", "Connected");
}
}).on("getPlayers", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("gs getPlayers");
JSONArray objects = (JSONArray) args[0];
try {
for (int i = 0; i < objects.length(); i++) {
FriendlyPlayer coopPlayer = new FriendlyPlayer(playerTex, world, game, 1220, 1100, 24, 32);
Vector2 position = new Vector2();
Float vx, vy;
Float bx, by;
position.x = ((Double) objects.getJSONObject(i).getDouble("x")).floatValue();
position.y = ((Double) objects.getJSONObject(i).getDouble("y")).floatValue();
vx = ((Double) objects.getJSONObject(i).getDouble("vx")).floatValue();
vy = ((Double) objects.getJSONObject(i).getDouble("vy")).floatValue();
bx = ((Double) objects.getJSONObject(i).getDouble("bx")).floatValue();
by = ((Double) objects.getJSONObject(i).getDouble("by")).floatValue();
String username = objects.getJSONObject(i).getString("username");
Integer level = objects.getJSONObject(i).getInt("level");
coopPlayer.setPosition(position.x, position.y);
coopPlayer.vx = vx;
coopPlayer.vy = vy;
coopPlayer.bx = bx;
coopPlayer.by = by;
coopPlayer.username = username;
coopPlayer.level = level;
friendlyPlayers.put(objects.getJSONObject(i).getString("id"), coopPlayer);
coopPlayer.update(Gdx.graphics.getDeltaTime());
}
} catch (JSONException e) {
}
}
});
}
武器商店类别:
public WeaponShop() {
...
connectToRoom();
configSocketEvents();
}
private void connectToRoom() {
try {
JSONObject data = new JSONObject();
try {
data.put("newroom", "weaponshop");
socket.emit("joinRoom", data);
} catch (JSONException e) {
Gdx.app.log("SOCKET.IO", "Error sending update data!");
}
} catch(Exception e){
System.out.println(e);
}
}
private void configSocketEvents() {
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Gdx.app.log("SocketIO", "Connected");
}
}).on("getPlayers", new Emitter.Listener() {
@Override
public void call(Object... args) {
System.out.println("ws getPlayers");
JSONArray objects = (JSONArray) args[0];
try {
for (int i = 0; i < objects.length(); i++) {
FriendlyPlayer coopPlayer = new FriendlyPlayer(playerTex, world, game, 56, 195, 24, 32);
Vector2 position = new Vector2();
Float vx, vy;
Float bx, by;
String username;
position.x = ((Double) objects.getJSONObject(i).getDouble("x")).floatValue();
position.y = ((Double) objects.getJSONObject(i).getDouble("y")).floatValue();
vx = ((Double) objects.getJSONObject(i).getDouble("vx")).floatValue();
vy = ((Double) objects.getJSONObject(i).getDouble("vy")).floatValue();
bx = ((Double) objects.getJSONObject(i).getDouble("bx")).floatValue();
by = ((Double) objects.getJSONObject(i).getDouble("by")).floatValue();
username = objects.getJSONObject(i).getString("username");
coopPlayer.setPosition(position.x, position.y);
coopPlayer.vx = vx;
coopPlayer.vy = vy;
coopPlayer.bx = bx;
coopPlayer.by = by;
coopPlayer.username = username;
friendlyPlayers.put(objects.getJSONObject(i).getString("id"), coopPlayer);
coopPlayer.update(Gdx.graphics.getDeltaTime());
}
} catch (JSONException e) {
}
}
});
}
以及我在服务器中的 joinRoom 方法:
socket.on('joinRoom', function(data) {
oldRoom = socket.room;
socket.room = data.newroom;
socket.leave(oldRoom);
socket.join(socket.room);
socket.emit("createPlayer");
socket.to(oldRoom).emit('playerDisconnected', { id: socket.id });//socket.broadcast.to(oldRoom).emit('playerDisconnected', { id: socket.id });
socket.to(socket.room).emit('newPlayer', { id: socket.id });//socket.broadcast.to(socket.room).emit('newPlayer', { id: socket.id });
if(oldRoom == 'town') {
for(var i = 0; i < players.length; i++) {
if(players[i].id == socket.id) {
players.splice(i, 1);
}
}
}
if(oldRoom == 'weaponshop') {
for(var i = 0; i < weaponshopPlayers.length; i++) {
if(weaponshopPlayers[i].id == socket.id) {
weaponshopPlayers.splice(i, 1);
}
}
}
if(oldRoom == 'potionshop') {
for(var i = 0; i < potionshopPlayers.length; i++) {
if(potionshopPlayers[i].id == socket.id) {
potionshopPlayers.splice(i, 1);
}
}
}
if(socket.room == 'town') {
socket.emit('getPlayers', players);
socket.emit('getMonsters', monsters);
players.push(new player(socket.id, "", 0, "town", 1220 / 100, 1100 / 100, 0, 0, 0, 0));
}
if(socket.room == 'weaponshop') {
socket.emit('getPlayers', weaponshopPlayers);
weaponshopPlayers.push(new player(socket.id, "", 0, "weaponshop", 56 / 100, 195 / 100, 0, 0, 0, 0));
}
if(socket.room == 'potionshop') {
socket.emit('getPlayers', potionshopPlayers);
potionshopPlayers.push(new player(socket.id, "", 0, "potionshop", 56 / 100, 195 / 100, 0, 0, 0, 0));
}
console.log("Player (" + socket.id + ") switched room");
});
最佳答案
问题的关键在于,无论您做什么,您都无法控制消息何时到达套接字。
玩家可能刚刚从一个房间换到另一个房间,但来自服务器的消息可能已经在路上。
您可以做的一件事是与服务器建立单个连接并通过它发送所有请求。如果消息到达,您需要检查它对于当前状态(您也在客户端维护)是否仍然有效。如果是,则将其转发到正确的实现,如果不是,则丢弃它。
这取决于您对游戏的不同方面进行适当的分离。所以基本上它是一个代码设计问题。
对不同的事物使用相同格式的消息可能也不是一个好方法。如果您无法区分消息的上下文是什么,那么您最终必然会传达无意的内容。
关于java - Libgdx 当屏幕更改时,套接字事件仍在前一个屏幕中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59414531/