我在使用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的扩展,因此,不应该一直存在投射问题。
我真的在这里碰了一堵砖墙,非常感谢任何帮助。如果您想查看任何其他代码,请告诉我,我很乐意帮忙。
非常感谢提前。