实现服务器端NPC(非玩家角色)

时间:2015-07-30 14:27:33

标签: java sockets udp multiplayer udpclient

我在使用Java制作的2D多人游戏中遇到了一些问题。这是我的第一场比赛,在很多教程的帮助下我已经走到了这一步,所以也许简单的事情就是逃避我。

当客户端登录时,它会向服务器发送一个登录数据包,该服务器会检查存储在数据包中的用户名与已连接的玩家。如果名称尚未存在,则将播放器添加到实体列表中。 (我知道我需要更好的验证来防止2个相同的用户名,但我专注于让所有事情都先工作)。完成此任务的代码如下:

public void addConnection(PlayerMP player, Packet00Login packet) {

        boolean alreadyConnected = false;
        int connectionAttempts = 0;

        for (PlayerMP p : connectedPlayers) {
            if (p.port == -1) {
                p.port = player.port;
            }

            if (player.getUsername().equalsIgnoreCase(p.getUsername())) {

                if (p.ipAddress == null) {
                    p.ipAddress = player.ipAddress;
                }

                if (p.port == -1) {
                    p.port = player.port;
                }
                alreadyConnected = true;        //if client is already connected, return true + do nothing

            } else {
                sendPacket(packet.getData(), p.ipAddress, p.port);  //send login packet with new player address and port if not already connected
                Packet00Login newPacket = new Packet00Login(p.getUsername(), p.x, p.y, p.getShortColour());     //+ colour?
                sendPacket(newPacket.getData(), player.ipAddress, player.port);     //sending new packet to update character position
            }

        }
        if (!alreadyConnected) {
            connectedPlayers.add(player);       //add new player data to connectedPlayers list if matching values aren't already present.
        }
    }

public void sendPacket(byte[] data, InetAddress ip, int prt) {                  //method to send data to a single client as byte array within datagram packet object.
        DatagramPacket p = new DatagramPacket(data, data.length, ip, prt);
        try {
            socket.send(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

添加的实体是PlayerMP类的实例,其中包括任何连接客户端的IP地址和端口(这是NPC出现困难的地方)。一旦添加到实体列表中,当任何客户端移动其玩家角色时,所有连接的客户端都会不断更新(这会导致将移动数据包发送到服务器),使用以下代码:

public void sendDataToAllClients(byte[] data) {                 //method to send packets to all connected players by looping through list and sending datagram packet to each stored address/port
        for (PlayerMP p : connectedPlayers) {
            sendPacket(data, p.ipAddress, p.port);
        }
    }

我可以通过再次比较用户名来省略此方法中的NPC,以确保服务器不会将数据发送到不存在的客户端(它没有ip / port),但是我似乎无法使用sendPacket(newPacket.getData(),player.ipAddress,player.port)注册NPC实体;在第一段代码中,当我尝试时,我得到空地址/端口超出范围异常。所以问题似乎是服务器不知道如何在没有地址的情况下注册实体。

我认为NPC发送全局登录数据包至关重要,或者它只会显示在本地客户端上,但我无法解决这个问题。我试图创建一个扩展我的Mob类(它是PlayerMP的超级类)的新类,但后来遇到了关于转换的问题,即使新创建的NPC类和PlayerMP都是Mob的扩展,它是Entity的扩展,因此,不应该一直存在投射问题。

我真的在这里碰了一堵砖墙,非常感谢任何帮助。如果您想查看任何其他代码,请告诉我,我很乐意帮忙。

非常感谢提前。

0 个答案:

没有答案