多人Java 2D平台游戏: ObjectInputStream.readObject()会导致程序停止运行?

3

我和我的朋友正在学校做一个Java的2D平台游戏。游戏本身运行良好,但我们在多人游戏方面遇到了一些问题。

我们的游戏相当简单,只有一个小人和一些敌人。

我以前没有编写过Java中两台电脑之间的连接,所以我基于YouTube上关于聊天应用程序的一些教程来编写“连接”代码。连接工作正常,但问题是程序只读取socket输入,不再运行游戏。

我设法通过将其从while(true)循环中删除来解决这个问题,但现在我又有了另一个无法解决的问题。

在开始多人游戏时,您可以选择是创建游戏(服务器)还是加入游戏(客户端)。

当您创建游戏时,它将等待连接(客户端)以在开始前进行连接。但现在整个游戏应该开始时它却“卡住”了。实际上并没有真正卡住。假设你是服务器,你的朋友作为客户端连接到你的服务器。他加入了你的游戏,在两台计算机上游戏都开始了,但你停留在菜单界面。只有当你的朋友(客户端)按下一个按钮,你屏幕上的游戏(服务器端)才会移动(每次你的朋友按下一个按钮,游戏就会向前移动一点),如果你按下一个按钮,你朋友的游戏也会移动。如果服务器和客户端都一直按住按钮(左、右、跳跃、射击......),游戏将运行得很完美,但这显然不是最好的做法。

我认为问题在于这行代码:

if(ServerState.server == true){
        try {                   
            Server.clientMessage = (String) Server.serverInput.readObject();
            System.out.println(Server.clientMessage);   
        }   
        catch (ClassNotFoundException e) {
            System.out.println("Data type not found");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    if(ClientState.client == true){
        try {               
            Client.serverMessage = (String) Client.clientInput.readObject();
            System.out.println(Client.serverMessage);
        }
        catch(ClassNotFoundException e){
            System.out.println("Data type not found");
            e.printStackTrace();
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
    }

serverInputclientInput都是ObjectInputStreams

变量serverState.serverClientState.client只是用来判断你是服务器还是客户端的booleans

这段代码实现在“在线关卡”的代码中。

如果我注释掉这段代码,游戏可以运行,但是“connectedPlayer”不会移动(服务器/客户端没有从客户端/服务器获取任何信息)。

我的问题是:这行代码:

Server.clientMessage = (String) Server.serverInput.readObject();

等待输入,当它得到输入后程序才能继续吗?如果没有输入,整个程序会停止吗? 如果我的解释足够清楚,您有解决这个问题的任何想法吗?

提前感谢您!

PS:抱歉我的英语不好:s


我的意思是说,学校指的是大学,不知道这是否会有所改变?但我认为对于学生来说,编写任何类型的游戏都不太困难,证明游戏可以运行,只是我在多人游戏方面遇到了一些麻烦,因为我对此没有任何经验。 - Allinone51
请尝试使用KryoNet而不是这种类型的序列化。http://stackoverflow.com/a/24452428/2413303 - EpicPandaForce
好的,谢谢,我会看一下的。 - Allinone51
1
如果有一件事情我应该作为建议注意的话:如果你从别处复制粘贴代码,请确保它能够正常工作,更重要的是,如果你想在自己的代码中使用它,一定要确保你理解它的作用。有时候,理解库的内部工作原理是不必要的,你只需要知道如何使用它 - 但是你必须知道你的代码在做什么,如果它出现问题,你也必须知道如何调试出错的确切行,并根据此确定错误。 - EpicPandaForce
1个回答

2
readObject 方法会阻塞直到有输入可用,然后在输入到达时返回该输入。您需要创建一个新线程来读取输入并将输入传递给游戏的其他部分。
为了向游戏传递信息,您可能需要在ServerClient类中创建不同的方法以处理不同的消息。您可以使用switchif else if来根据对象中的字段或对象的类型(使用instanceof)决定使用哪个方法。

我实现了Runnable并启动了一个Thread,程序现在在run()方法中读取流,并且一切都运行良好!非常感谢! - Allinone51
@Allinone51 如果一个答案对您有用,接受它(点击复选标记)可以向所有人展示解决方案有效,并为我们两个赢得一点声誉。但您并不是必须这样做的。 - James Westman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接