简体   繁体   English

如何获得游戏的实时时间

[英]How to get real time for a game

i am working with Java and i am making a game. 我正在使用Java,我正在制作游戏。 In this game the real time is very essensial part. 在这个游戏中,实时是非常重要的一部分。 For this reason i am trying to get the real time using Ntp. 出于这个原因,我试图使用Ntp获得实时。

What i found in the web is this code. 我在网上找到的是这段代码。

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);
    }
}

My problem is that using this, the system is still getting the System.currentMillis(); 我的问题是使用这个,系统仍然得到System.currentMillis(); because it actually prints you the time that your local machine got the time message. 因为它实际上会打印出本地机器获取时间消息的时间。 For this reason if the player changes his Desktop time to the future, the game time will also change. 因此,如果玩家将桌面时间改为未来,游戏时间也会发生变化。

If someone could help in order to have the real time i would be very thankful. 如果有人可以帮忙以获得实时我会非常感激。 PS i dont have a server, my game will be playing on Kongregate and the data will be on the players computer. PS我没有服务器,我的游戏将在Kongregate上播放,数据将在播放器计算机上。

Thanks in advance. 提前致谢。

Just get the time once via NTP at the start of your program and then use System.nanoTime() to get the relative time after that. 只需在程序开始时通过NTP获取一次,然后使用System.nanoTime()获取之后的相对时间。 It is completely monotomic and will not be changed via the setting of the system time. 它完全是单调的,不会通过设置系统时间来改变。

As per the NTPUDPClient javadoc: 根据NTPUDPClient javadoc:

To use the class, merely open a local datagram socket with open and call getTime() to retrieve the time. 要使用该类,只需打开一个打开的本地数据报套接字并调用getTime()来检索时间。 Then call close to close the connection properly. 然后调用close以正确关闭连接。 Successive calls to getTime are permitted without re-establishing a connection. 在不重新建立连接的情况下,允许连续调用getTime。

You are missing a call to open() in your code (technically close() as well, but that's not the reason for your issue). 您在代码中缺少对open()的调用(技术上也是close() ,但这不是您的问题的原因)。

Also, in your requirements, you state you needed the real time (and not whatever time the local client can set). 此外,在您的要求中,您声明您需要实时(而不是本地客户端可以设置的任何时间)。 This quantity should not be obtained directly but as an offset required to match local time to server (remote) time, obtained by the method getOffset() . 此数量不应直接获得,而应作为匹配本地时间与服务器(远程)时间所需的偏移量,通过方法getOffset()

If getting the real time is a common procedure, you may want to only use NTP once at the start and use the offset obtained to correct system time in the future, reducing the latency when retrieving real time. 如果获得实时是一个常见的过程,您可能只想在开始时使用NTP一次,并使用获得的偏移来纠正未来的系统时间,从而减少检索实时时的延迟。

Such a process can be described in a class as such: 这样的过程可以在类中描述:

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)
    }
}

Try this: 试试这个:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM