Java 如何获得游戏的实时性

Java 如何获得游戏的实时性,java,time,ntp,Java,Time,Ntp,我在用Java做游戏。在这个游戏中,实时性是非常重要的一部分。 出于这个原因,我正试图使用Ntp获取实时数据 我在网上找到的是这个代码 import java.net.InetAddress; import java.util.Date; import org.apache.commons.net.ntp.NTPUDPClient; import org.apache.commons.net.ntp.TimeInfo; public class test{ public static

我在用Java做游戏。在这个游戏中,实时性是非常重要的一部分。 出于这个原因,我正试图使用Ntp获取实时数据

我在网上找到的是这个代码

import java.net.InetAddress;
import java.util.Date;
import org.apache.commons.net.ntp.NTPUDPClient; 
import org.apache.commons.net.ntp.TimeInfo;

public class test{
    public static void main(String args[]) throws Exception{
        String TIME_SERVER = "time-a.nist.gov";   
        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
        TimeInfo timeInfo = timeClient.getTime(inetAddress);

        long returnTime = timeInfo.getReturnTime();
        Date time = new Date(returnTime);

        System.out.println("Time from " + TIME_SERVER + ": " + time);
    }
}
我的问题是,使用它,系统仍然会得到system.currentMillis();因为它实际上会打印出本地机器收到时间信息的时间。因此,如果玩家将其桌面时间更改为将来,游戏时间也将更改

如果有人能帮助我,我将非常感激。 另外,我没有服务器,我的游戏将在Kongregate上玩,数据将在玩家电脑上


提前感谢。

只需在程序开始时通过NTP获取一次时间,然后使用System.nanoTime()获取之后的相对时间。它是完全单原子的,不会通过设置系统时间进行更改

试试这个:

String TIME_SERVER = "time-a.nist.gov";   
TimeTCPClient client = new TimeTCPClient();

try {
    client.connect(TIME_SERVER);
    System.out.println(client.getDate());
} finally {
    client.disconnect();
}

根据
NTPUDPClient
javadoc:

要使用该类,只需使用open打开本地数据报套接字并调用
getTime()
来检索时间。然后调用close以正确关闭连接。允许连续调用getTime,而无需重新建立连接

您的代码中缺少对
open()
的调用(从技术上讲也是
close()
的,但这不是问题的原因)

此外,在您的需求中,您声明您需要实时(而不是本地客户机可以设置的任何时间)。此数量不应直接获得,而是作为匹配本地时间到服务器(远程)时间所需的偏移量,通过方法
getOffset()
获得

如果获取实时是一个常见的过程,那么您可能希望在开始时只使用一次NTP,并在将来使用获得的偏移量来校正系统时间,从而减少检索实时时的延迟

这样的过程可以在类中描述为:

public class TimeKeeper{
    // Constant: Time Server
    private final String TIME_SERVER = "time-a.nist.gov";

    // Last time the time offset was retrieved via NTP
    private long last_offset_time = -1;

    // The real time, calculated from offsets, of when the last resync happened
    private long retrieve_time;

    private synchronized void resync(){
        NTPUDPClient timeClient = new NTPUDPClient();
        InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
        TimeInfo timeInfo = null;

        try{
            timeClient.open();
            timeInfo = timeClient.getTime(inetAddress);
        }catch(IOException ex){
            return;
        }finally{
            timeClient.close();
        }

        // Real time calculated from the offset time and the current system time.
        retrieve_time = System.currentTimeMillis() + timeInfo.getOffset();
        last_offset_time = System.nanoTime();
    }

    public long getRealTimeInMillis(){
        // Possible to set some resync criteria here
        if(last_offset_time == -1){
            resync();

            // Handle exception whilst retrieving time here
        }

        // Returns the system time, corrected with the offset
        return retrieve_time + Math.round((System.nanoTime() - last_offset_time) / 1000.0)
    }
}

在内部运行自己的时钟。比较您应该获得v.s.的时间和实际获得的时间,如果有巨大差异,请致电Shenanigans。
getReturnTime
不提供服务器的时间,而是提供本地机器接收消息包的时间。(根据javadoc)。这就是
getDelay()
getOffset()
方法的作用吗?它给了我这个信息。NTPUDPClient类型的方法connect(String)未定义。很抱歉,您正在使用不同类型的客户端。。。检查我的编辑!;)说谢谢太少了:)它工作得很好!很高兴听你这么说!;)