我正在用Java创建一个简单的网络游戏,玩家可以使用键盘键移动块。游戏将在本地服务器上运行,并具有基本规则:
Each block will move automatically at 1 FPS rate, but the **user can send several move
commands** in this 1 second interval, thus updating the block position.
代码几乎完成,但是在服务器和客户端之间同步时却遇到了麻烦。以下是我需要更好理解的一些代码/描述:
class Server{
ServerSocket server = new ServerSocket(port);
while (listening) {
Socket client = server.accept();
new Thread(new ClientHandler(client)).start();
}
}
class Game implements Runnable {
public void run() {
while (! gameOver)
tick();
}
}
class ClientHandler implements Runnable
{
Game game;
public ClientHandler(Socket client)
{
this.client = client;
//start game which runs at 1 FPS
long FPS = 1000L;
Timer timer = new Timer();
timer.schedule(new Game(FPS), 0L, FPS);
}
public void run()
{
/** Game is already running, needs to:
*
* 1 - Take any GameInput object from the user and update the game
* 2 - Send a GameState object to the user
* 3 - Client will receive it and render on screen,
* (hopefully in a synch state with the server)
*/
while ( ! game.gameOver)
{
//ObjectInputStream ois = ...;
// Line A
GameInput command = ois.readObject();
// Line B
//GameState state = game.update(command);
//ObjectOutputStream oos = ...;
// Line C
oos.writeObject(state);
}
}
}
我需要更好地理解的是如何处理Line A
,Line B
和Line C
。
更确切地说:
1 - 以安全的方式更新游戏线程的好方法是什么?
2 - 我如何处理多个命令?一个队列可能吗?
2 - 我如何确保客户端和服务器同步?
我是网络编程的新手,所以感谢您的帮助!
答案 0 :(得分:1)
当您编程任何类型的服务器时,队列绝对是您的朋友。如果我们假设一个基本的客户端 - 服务器模型,游戏服务器的每个循环都应该执行以下操作:
同样,客户端还应该有一个来自服务器的命令队列,允许它们更新自己的状态。通过合理的延迟,服务器和客户端应保持合理的同步。总是会出现一点点的去同步,并且有不同的处理方式。 (阅读:client-side interpolation)。
对于游戏的每个循环,游戏基本上应该清空命令队列并根据需要应用它们。
答案 1 :(得分:0)
网络同步的可能解决方案:您可以首先使用NTP服务器将所有客户端和服务器同步到相同的日期/时间(如果延迟非常不同,或者如果存在大量抖动,则无法自己实现从服务器)。然后按照与必须执行的时间相关的一秒的帧发送数据,客户端等待帧中指示的时间并执行/更新命令。将总是存在延迟,(可能在LAN上<几毫秒)。希望这会有所帮助。