2010-10-11 8 views
1

Je ne suis pas sûr si le terme temps réel est mal utilisé ici, mais l'idée est que de nombreux joueurs sur un serveur ont une ville produisant n ressources par seconde. Il pourrait y avoir un millier de ces villes. Quelle est la meilleure façon de récompenser toutes les villes de joueurs?Meilleure façon de coder un jeu multijoueur en temps réel

Est-ce la meilleure façon de faire une boucle comme celle-ci dans une boucle infinie quand le jeu est "live"? (S'il vous plaît ignorer les défauts évidents avec cette logique simpliste)

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

Répondre

5

Je ne pense pas que vous voulez une boucle infinie car cela perdre beaucoup de cycles CPU. Ceci est essentiellement une situation de simulation commune Wikipedia Simulation Software et il y a quelques approches que je peux penser:

  1. Une approche de temps discret où vous incrémenter l'horloge par un temps fixe et recalculées l'état de votre système. Ceci est similaire à votre approche ci-dessus sauf faire le calcul périodiquement et supprimer la clause 10 secondes if.
  2. Une approche d'événement discret où vous avez une file d'attente d'événements centrale, chacun avec un horodatage, triés par heure. Vous dormez jusqu'à ce que l'événement suivant arrive, puis envoyez-le. Par exemple. l'événement pourrait signifier l'ajout d'une seule ressource. Wikipedia Discrete Event Simulation
  3. Chaque fois que quelqu'un demande le nombre de ressources, calculez-le en fonction du débit, de l'heure initiale et de l'heure actuelle. Cela peut être très efficace lorsque le nombre de requêtes devrait être faible par rapport au nombre de villes et au temps écoulé.
+0

2. est particulièrement agréable lorsque vous avez un bon support d'événement dans la langue de votre choix. 3. peut être un peu difficile quand il y a des facteurs externes qui peuvent parfois changer le taux de production, bien que l'on puisse pousser les facteurs à une pile et ensuite recalculer dans le temps quand on le demande. –

1

pendant que vous pouvez stocker la dernière fois cochée par objet, comme votre exemple, il est souvent plus facile d'avoir juste un timestep global

while(1) { 
    currentTime = now(); 
    dt = currentTime - lastUpdateTime; 

    foreach(whatever) 
    whatever.update(dt); 

    lastUpdateTime = currentTime; 
} 

si vous avez des systèmes différents qui ne nécessitent pas de mises à jour fréquentes :

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 

    // ... 
} 

(que vous remarquerez est à peu près ce que vous faisiez sur une base par ville)

une autre gotcha est qu'avec des rythmes d'horloge de sous-systèmes différents, vous pouvez obtenir des chevauchements (c'est-à-dire cocher de nombreux sous-systèmes avec la même trame), conduisant à des temps de trame incohérents qui peuvent parfois poser problème.

Questions connexes