【问题标题】:How to get real time for a game如何获得游戏的实时时间
【发布时间】:2015-02-20 16:08:46
【问题描述】:

我正在使用 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 上玩,数据会在玩家的电脑上。

提前致谢。

【问题讨论】:

  • 在内部运行您自己的时钟。比较你应该得到的时间。您实际得到的时间,如果有很大差异,请致电 shenaningans。
  • getReturnTime 没有给你服务器的时间,它给你本地机器接收到消息包的时间。(根据javadoc)。
  • 这就是getDelay()getOffset() 方法的用途吗?

标签: java time ntp


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    试试这个:

    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 类型的方法 connect(String) 未定义。
    • 抱歉,您使用的是不同的客户端...检查我的编辑! ;)
    • 说谢谢太少了 :) 效果很好!
    • 很高兴听到这个! ;)
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      相关资源
      最近更新 更多