代码之家  ›  专栏  ›  技术社区  ›  Eric Falsken

编写实时多人游戏代码的最佳方法

  •  1
  • Eric Falsken  · 技术社区  · 14 年前

    n个 每秒资源。这样的城市可能有一千个。奖励所有玩家城市的最佳方式是什么?

    foreach(City c in AllCities){
      if(c.lastTouched < DateTime.Now.AddSeconds(-10)){
        c.resources += (DateTime.Now-c.lastTouched).Seconds * c.resourcesPerSecond;
        c.lastTouched = DateTime.Now;
        c.saveChanges();
      }
    }
    
    2 回复  |  直到 14 年前
        1
  •  5
  •   Guy Sirton    14 年前

    我不认为你想要无限循环,因为那样会浪费很多CPU周期。这基本上是一种常见的模拟情况 Wikipedia Simulation Software 我可以想到一些方法:

    1. 一种离散时间方法,在这种方法中,时钟按固定时间递增,然后重新计算系统的状态。这与上面的方法类似,只是定期进行计算并删除10秒if子句。
    2. 一种离散事件方法,其中有一个中心事件队列,每个队列都有一个时间戳,按时间排序。你睡觉直到下一个事件到期,然后发送它。E、 这个事件可能意味着增加一个资源。 Wikipedia Discrete Event Simulation
    3. 每当有人要求资源数量时,请根据速率、初始时间和当前时间计算它。当查询的数量相对于城市的数量和经过的时间来说很小时,这是非常有效的。
        2
  •  1
  •   Jeff Gates    14 年前

    虽然您可以存储每个对象上一次标记的时间(如您的示例),但通常更容易使用全局时间步

    while(1) {
      currentTime = now();
      dt = currentTime - lastUpdateTime;
    
      foreach(whatever)
         whatever.update(dt);
    
      lastUpdateTime = currentTime;
    }
    

    while(1) {
      currentTime = now();
      dt = currentTime - lastUpdateTime;
    
      subsystem.timer += dt
      while (subsystem.timer > subsystem.updatePeriod)  {// need to be careful
           subsystem.timer -= subsystem.updatePeriod;    // that the system.update()
           subsystem.update(subsytem.updatePeriod);      // is faster than the 
      }                                                  // system.period
    
      // ...
    }
    

    (你会注意到你在每个城市做的事情)

    另一个问题是,在不同的子系统时钟速率下,可能会出现重叠(即勾选多个子系统的同一帧),导致帧时间不一致,这有时可能是一个问题。