java - Libgdx 当屏幕更改时,套接字事件仍在前一个屏幕中运行

标签 java node.js socket.io libgdx

我正在 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/

相关文章:

JAVA - REGEX - 不只匹配空格

javascript - Socket.io.js 未加载

javascript - 在 socket.io 服务器之间切换

java - 一个简单的java客户端服务器程序

java - java环境是否改变NLS_DATE_FORMAT参数的值?

java - 无法获取某种使用 jsoup 解析 HTML 页面的链接

javascript - 尝试在 Node.js 中进行 REST GET 调用

node.js - Nodejs redis 方法 BLPOP 阻塞事件循环

node.js - NodeJS + MongoDB : find() where { 'value' : < 5 AND >1} - how?

javascript - 来自 ws 的 Node.js 和 Socket.io UTF8 验证类型错误