2011-11-09 5 views
3

Je travaille sur un petit jeu Java, s'appuyant sur les astéroïdes classiques.Comment gérer la mise à jour périodique de nombreux objets?

Dans ce jeu il y a une tonne d'objets qui doivent être mis à jour dans certains intervalles de temps:

Chaque cadre: Les objets qui se déplacent ou pivotent.
Chaque seconde: la minuterie de jeu.
Toutes les quelques secondes: IA ennemie, engeance de l'ennemi
Chaque seconde: tirer une nouvelle balle de l'arme du vaisseau.

Actuellement, je suis la manipulation comme ceci:

//This method is called by a timer that is run every 30 milliseconds 
//It will iterate through all objects that require periodic updates and call their 
//update method every 30ms. 
public void frameUpdateLoop(){ 
    for(Updating u : allObjectsThatNeedPeriodicUpdates){ 
     u.update(); 
    } 
} 

public class EnemySpawner implements Updating{ 
    private static final int SPAWN_TRESHOLD=500; 
    private int timeUntilNewEnemySpawns=SPAWN_TRESHOLD; 

    //This method is called by frameUpdateLoop() 
    //It is only supposed to do work once every 500ms, but is called every 
    //30ms nonetheless. 
    public void update(){ 
     timeUntilNewEnemySpawns -= 30; //Subtract time since last update 
     if(timeUntilNewEnemySpawns <= 0){ 
      SpawnNewEnemy(); 
      timeUntilNewEnemySpawns = SPAWN_TRESHOLD; 
     } 
    } 
} 

Bien sûr, cela est seulement un exemple de la façon dont je l'utilise, alors j'ai enlevé les parties inutiles.

Ma question est: Est-ce le bon (= un bon moyen) de mettre en œuvre un tel système de mise à jour? Lors de la lecture, j'ai remarqué que la plupart du temps, une minuterie est utilisée pour une telle tâche.

Mais cela m'obligerait à avoir des douzaines de minuteurs fonctionnant en même temps (un pour chaque objet qui nécessite une mise à jour). Si je comprends bien chaque instance d'un Timer crée également un nouveau thread, donc je crains que cela puisse devenir un problème à un moment donné (la perte de performance de gestion de threads surpasse mon système actuel - ou le nombre de threads devient trop grand).

Je suis un peu nouveau sur Java, donc je ne sais pas si mes peurs sont sans fondement ou si c'est vraiment une mauvaise idée d'avoir autant de Timers.

Merci beaucoup pour vos suggestions, conseils et corrections sur ce sujet!

Répondre

0

J'aime vraiment votre design avec l'interface Updating qui résume les détails de ce qui doit être mis à jour. Bien sûr, votre implémentation actuelle n'est pas très élégante. Peut-être que vous devriez créer plusieurs méthodes comme updateEveryFrame(), updateEverySecond(), etc? Chaque objet n'implémente que les méthodes dont il a besoin pour fonctionner, laissant les autres non-ops.

Timer est en fait un bon choix ici as well:

Cette balance classe à un grand nombre de tâches en même temps que prévu (en milliers doivent présenter aucun problème)

Cependant, je recommande le fractionnement allObjectsThatNeedPeriodicUpdates en: allObjectsThatNeedUpdateEveryFrame, allObjectsThatNeedUpdateEverySecond, etc. Créez une tâche périodique pour la première collecte, une autre (avec un intervalle différent) pour l'autre.

0

Votre méthode semble bien, c'est ce que fait Half-Life. La seule différence est que Half-Life (et beaucoup d'autres, y compris les vôtres) envoie un Delta Time à la fonction de mise à jour afin que vous n'ayez pas à coder en dur 30ms dans chaque fonction de mise à jour. Alors:

public void update(int deltaTime){ 
    timeUntilNewEnemySpawns -= deltaTime; //Subtract the delta time 
    if(timeUntilNewEnemySpawns <= 0){ 
     SpawnNewEnemy(); 
     timeUntilNewEnemySpawns = SPAWN_TRESHOLD; 
    } 
} 

en utilisant un temps delta comme celui-ci vous permettra de modifier l'intervalle de mise à jour si vous avez toujours voulu/nécessaire pour. Et oui, vous pouvez et aurez un tas de guichets qui suivront les différents événements du jeu.

Je pourrais également changer deltaTime et timeUntilNewEnemySpawns à l'équivalent java d'un TimeSpan afin que vous puissiez accéder à certaines méthodes utiles comme TotalSeconds et autres. Ce n'est pas nécessaire cependant.

+0

C'est aussi une bonne idée de passer un deltaTime car le rendu du frame peut prendre plusieurs millisecondes à compléter, et vos équations physiques doivent savoir combien de temps s'est écoulé. Dans une période lente, laissez-les prendre des sauts plus longs, etc. – Karl

+0

@Karl, C'est vrai dans beaucoup de cas, mais il y a une grande discussion sur les pas de temps fixes vs variables qui vaut la peine d'être lues ici: http: //gamedev.stackexchange. com/questions/1589/temps-fixe-étape-vs-variable-temps-étape –

Questions connexes