【问题标题】:Libgdx when screen changed, socket events still running in previous screen屏幕更改时的Libgdx,套接字事件仍在前一个屏幕中运行
【发布时间】:2019-12-19 17:41:12
【问题描述】:

我正在 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 node.js socket.io libgdx


    【解决方案1】:

    问题的症结在于,无论你做什么,你都无法控制消息何时到达套接字。

    玩家可能刚从一个房间换到另一个房间,但来自服务器的消息可能已经在路上了。

    您可以做的一件事是与服务器建立一个连接并通过它发送所有请求。如果消息到达,您需要检查它对于当前状态是否仍然有效(您也在客户端维护)。如果是,则将其转发给正确的实现,如果不是,则丢弃它。

    这取决于您在游戏的不同方面之间是否有适当的分离。所以基本上它是一个代码设计问题。

    对不同的事物使用相同格式的消息可能也不是一个好方法。如果你不能区分消息的上下文是什么,你最终必然会传达一些无意的东西。

    【讨论】:

    • 其实我的问题,当玩家在武器商店类,城镇类的configSocketMethods还在运行。我必须停止在城镇类运行configSocketMethods。我该怎么做?
    • 我认为您无法做到 100% 准确。您可以尝试使用off 取消注册您的回调,但如果回调已经在后台运行,这可能对您没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-08
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 2021-04-21
    • 2015-06-03
    相关资源
    最近更新 更多