java - 在服务器和客户端同步游戏逻辑

标签 java multithreading sockets networking

我正在用 Java 创建一个简单的网络游戏,玩家可以在其中使用键盘键移动方 block 。游戏将在本地服务器上运行,并有一个基本规则:

每个 block 将以 1 FPS 的速率自动移动,但**用户可以发送多个移动 命令**在这 1 秒的间隔内,从而更新 block 位置。

代码几乎完成了,但我在服务器和客户端之间同步时遇到了问题。这是我需要更好地理解的一些代码/描述:

基础课

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 ALine BLine C。 更准确地说:

1 - 安全更新游戏线程的好方法是什么?

2 - 我如何处理多个命令?也许是一个队列?

2 - 如何确保客户端和服务器同步?

我是网络编程的新手,非常感谢您的帮助!

最佳答案

当您编写任何类型的服务器时,队列绝对是您的 friend 。如果我们假设一个基本的客户端-服务器模型,您的游戏服务器的每个循环都应该执行如下操作:

  1. 从命令队列中获取所有命令。
  2. 处理命令。
  3. 向所有连接的客户端发送更新,然后客户端将更新应用到执行相同操作的自己的队列。

同样,客户端也应该有一个来自服务器的命令队列,允许它们更新自己的状态。在合理的延迟下,服务器和客户端应该保持合理的同步。总是会出现一点点不同步,并且有不同的方法来处理它。 (阅读:client-side interpolation)。

对于游戏的每个循环,游戏基本上应该清空命令队列并根据需要应用它们。

关于java - 在服务器和客户端同步游戏逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18471047/

相关文章:

java - 在java中匹配 "."

Java 执行器 : how can I stop submitted tasks?

C# 在使用 ThreadPool 时,我可以将多个数据传递到我的目标方法吗?

c++ - 连接超时与 Alarm()

java - Hibernate:将属性字段设置为静态最终对象实例

java - JPanel 位于选项卡后的可用空间上

ios - Swift GCD 中的持久线程

sockets - 如何彻底关闭 Zeromq DEALER/ROUTER inproc 连接

c# - 如何在.NET中将StreamWriter的源设置为多个?

java - JPA 和新手的关系映射问题