2009-04-27 5 views
14

Je développe un jeu pour Android. Il se passe beaucoup de choses mais fonctionne assez bien. C'est, bien sûr, jusqu'à ce que l'utilisateur touche l'écran.Pourquoi les événements tactiles détruisent-ils mon framerate Android?

Pendant qu'ils le toucher, onTouchEvent est appelé (avec action = ACTION_MOVE, x = 0 et y = 0) à peu près une fois toutes les dix millisecondes à ce qui semble être une priorité assez élevée, car il oblitère absolument le framerate. Dès que le toucher se termine, le framerate revient à son état agréable.

J'ai essayé

  • ayant entrée onTouchEvent de poignée pour le jeu comme d'habitude
  • ayant onTouchEvent retour true immédiatement
  • ne pas avoir onTouchEvent mis en œuvre à tous

Le problème persiste dans les trois situations.

Quelqu'un at-il rencontré cela? Existe-t-il un moyen de réduire le taux de génération des événements ACTION_MOVE ou de s'assurer qu'ils ne sont générés qu'en cas de mouvement réel ou d'utiliser une méthode d'interrogation qui obtient uniquement l'emplacement actuel du contact? Ou même juste un moyen de le désactiver entièrement?

Répondre

12

Read ce fil. Fondamentalement, vous voulez dormir le fil de l'événement, sinon le système va pomper beaucoup d'événements (entre x, y et la pression, il y a toujours du mouvement) que vous devez gérer.

+0

lien ne fonctionne plus. –

0

Peut-être une solution quelque peu évidente, mais ... avez-vous essayé de ne traiter que 1/10 d'entre eux? Si vous effectuez un traitement qui est déclenché toutes les 10ms sur le thread de l'interface utilisateur, cela va probablement ralentir le framerate, oui. Alors, que se passe-t-il si vous accumulez simplement un compteur à la place et que vous ne faites que du traitement une fois que vous avez franchi un seuil minimal?

1

J'ai essayé de suivre tout les gars vous avez parlé au sujet, mais je dois admettre que après avoir essayé plusieurs façons de mettre en œuvre ce que vous suggérez, je n'ai toujours pas été en mesure d'obtenir une positif résultats. L'un d'entre vous pourrait-il fournir un exemple de code? Plus précisément, Je voudrais savoir comment faire pour que le thread principal/interface utilisateur sommeil. Si il est applicable à mes jeux, il serait également bon de savoir comment mettre jusqu'à un modèle de sondage comme Jon mis en œuvre.

Voici à quoi ressemble mon code. Sur le fil de l'interface utilisateur:

public boolean onTouchEvent(MotionEvent event) { 
    // Store event somewhere the game thread can see it: 
    // ... 

    synchronized (someObject) { 
     try { 
      someObject.wait(1000L); 
     } catch (InterruptedException e) { 
     } 
    } 

    return true; 
} 

et sur le fil du jeu:

void myGame() { 
    while (!stopping) { 
     // ... 

     // Get a touch event: 
     synchronized (someObject) { 
      someObject.notify(); 
     } 
     Thread.yield(); 

     // ... 
    } 
} 
0

Si vous voulez une solution sans avoir à traiter avec des fils de synchronisation je peux vous recommandons d'utiliser l'interface gestionnaire pour envoyer l'événement et pertinent des données en utilisant un Message/Bundle pour le fil de rendu du jeu. La solution de contournement du sommeil indiquée ici s'applique toujours.

0

En général, les événements sont accompagnés d'une propriété d'horodatage, ce qui facilite le calcul et la limitation du débit d'événements.

if (currentEventTimestamp - lastEventTimestamp > 500) { 
 

 
    lastEventTimestamp = currentEventTimestamp; 
 

 
    // do something 
 

 
}

Questions connexes