2017-02-11 4 views
0

Je développe un jeu qui consiste en quelques vues sur l'écran qui sont déplacées et que vous pouvez interagir avec eux.Quand repeindre toute l'interface utilisateur d'un jeu (sans le ralentir sur les appareils bas)

Je modifie le x, y et la largeur et la hauteur de ces vues en utilisant ObjectAnimator.

J'ajoute plus de vues et je supprime certaines vues et je les rajoute toutes les X secondes avec de nouvelles coordonnées et de nouvelles échelles.

Pour mettre à jour l'écran j'invalidant toutes les 10 millisecondes ensemble de la collection d'éléments à l'écran avec cette méthode d'exécution sur un fil:

public void run() { 
     while(!backgroundThread.interrupted()) { 
      synchronized(this){  
       wait(10);    
       doSomeStuffInOtherThread(); //like adding more items or moving them, etc... 
       allMyObjects.invalidateInOtherThread(); //this is just pseudocode for simplify the sample 
      } 
     } 
    } 

Il fonctionne sur des appareils puissants les articles sont repeints chaque 10 ms et il donne à l'utilisateur une sensation de framerate lisse. Le problème est que lorsque je teste le jeu sur des appareils bas, le jeu est très lent. Je pense que c'est parce que les méthodes doSomeStuffInOtherThread() et allMyObjects.invalidate() InOtherThread prennent trop de choses à exécuter sur les périphériques bas, plus de 10ms, et sur les périphériques haut de gamme, c'est fait instantanément (en moins de 10ms).

Il existe une meilleure façon de repeindre l'écran sans perdre de la vitesse de jeu? Si le jeu est en perte de vitesse, ce n'est pas un problème. Le problème est que c'est une perte de vitesse.

Merci

+0

Que voulez-vous dire "perdre de la vitesse"? Peut-être que l'utilisation du temps écoulé depuis la dernière image dans vos calculs le ferait. – Zouch

+0

@Zouch Je veux dire que si je déplace les objets sur un appareil puissant, ils se déplacent très rapidement, si je les déplace dans un appareil bas de gamme, ils se déplacent très lentement. Je suis assez sûr que le problème est que dans les appareils inférieurs 10ms n'est pas suffisant pour calculer le contenu de ces deux fonctions. S'il vous plaît, expliquez votre proposition, je ne peux pas comprendre ce que vous essayez de me dire – NullPointerException

+0

Vous devriez [lire ceci] (http://gafferongames.com/game-physics/fix-your-timestep/). Je vais élaborer plus tard! – Zouch

Répondre

0

Fondamentalement, votre problème est que vous comptez sur le temps que votre appareil pour traiter votre genre de choses. Cela pourrait être illustré par quelque chose de similaire

struct Ball { 
    float pos_x, pos_y; 
    float vel_x, vel_y; 
}; 

int main() { 
    Ball b{ 0.f, 0.f, 10.f, 10.f }; 

    for (;;) { 
     DosomethingThatMightTakeAWhile(); 
     b.pos_x += b.vel_x; 
     b.pos_y += b.vel_y; 
    } 
} 

En regardant ce simple morceau de code, vous pouvez facilement voir que tout ordinateur prendra 10 étapes pour aller (0, 0)-(100, 100), mais en fonction du temps DoSomethingThatMightTakeAWhile() prend pour terminer sur un ordinateur particulier, ces 10 étapes pourraient être achevées en 10 millisecondes ainsi que dans 10 secondes. Et ceci est votre problème ici. Vous ne prenez pas le temps réel passé à faire les calculs pour calculer combien vos éléments se déplacent.

Pour résoudre ce problème, il suffit de prendre en compte le temps écoulé depuis la dernière image (et peut-être de dormir un peu pour économiser la batterie). Alors maintenant, votre code ressemblera à ceci

int main() { 
    Ball b{ 0.f, 0.f, vel_x, vel_y }; // vel_x and vel_y are the new velocities, 
             // tweaked to match the speed you want 

    int64_t t0, t1; // In milliseconds here 
    t0 = GetTimeSinceStartup(); 

    for (;;) { 
     DoSomethingThatMightTakeAWhile(); 

     t1 = GetTimeSinceStartup(); 
     float dt = (t1 - t0)/1000.f; // Time elapsed in seconds 
     t0 = t1; 

     b.pos_x += b.vel_x * dt; 
     b.pos_y += b.vel_y * dt; 
    } 
} 

Vous pouvez voir que le code est beaucoup plus compliqué, mais la différence est que, maintenant, vous prenez effectivement le temps écoulé en compte lorsque vous calculez votre nouveau poste. Cela signifie que le temps DoSomethingThatMightTakeAWhile() n'a plus vraiment d'importance, si vous voulez que votre balle prenne une seconde pour se déplacer de 100 pixels, vous réglez sa vitesse sur 100 pixels par seconde, et cela prendra 1 seconde.