2009-04-27 11 views
14

Ich entwickle ein Spiel für Android. Es ist viel los, läuft aber einigermaßen reibungslos. Das heißt natürlich, bis der Benutzer den Bildschirm berührt.Warum zerstören Touch-Ereignisse meine Android-Framerate?

Während sie es sind zu berühren, wird onTouchEvent genannt (mit action = ACTION_MOVE, x = 0 und y = 0) etwa alle zehn Millisekunden an, was eine ziemlich hohe Priorität zu sein scheint, wie es unbedingt die Framerate auslöscht. Sobald die Berührung endet, kehrt die Framerate in ihren schönen Zustand zurück.

Ich habe versucht

  • onTouchEvent Griff Eingang für das Spiel, wie üblich
  • onTouchEvent Rückkehr mit true sofort
  • nicht onTouchEvent bei allen

implementiert, die das Problem weiterhin besteht in allen drei Situationen.

Hat jemand dies festgestellt? Gibt es eine Möglichkeit, die Geschwindigkeit zu reduzieren, mit der ACTION_MOVE Ereignisse generiert werden, oder um sicherzustellen, dass sie nur generiert werden, wenn es tatsächlich Bewegung gibt, oder verwenden Sie eine Abfragemethode, die nur den aktuellen Ort der Berührung erhält? Oder auch nur eine Möglichkeit, es komplett zu deaktivieren?

Antwort

12

Read dieser Thread. Grundsätzlich möchten Sie den Ereignis-Thread schlafen, da sonst das System viele Ereignisse (zwischen x, y und Druck gibt es immer etwas Bewegung) pumpen, die Sie behandeln müssen.

+0

Verbindung funktioniert nicht mehr. –

0

Vielleicht eine etwas offensichtliche Lösung, aber ... haben Sie versucht, nur etwa 1/10 von ihnen zu behandeln? Wenn Sie eine Verarbeitung durchführen, die alle 10 ms im UI-Thread ausgelöst wird, verlangsamt dies wahrscheinlich die Bildrate, ja. Was passiert also, wenn Sie stattdessen einfach einen Zähler ansammeln und nur einmal eine Verarbeitung durchführen, die einen minimalen Schwellenwert überschritten hat?

1

Ich habe versucht, alles, was ihr zu folgen habt zu sprechen, aber ich muß zugeben, dass nach dem Versuch von mehreren Möglichkeiten Umsetzung das, was Sie vorschlagen, ich habe immer noch nicht in der Lage gewesen, einen positiven zu erreichen Ergebnisse. Kann einer von Ihnen einen Beispielcode bereitstellen? Genauer gesagt, Ich würde gerne wissen, wie man den Haupt/UI-Thread schlafen gehen. Wenn es für meine Spiele anwendbar ist, wäre es auch schön zu wissen, wie ein Polling-Modell wie Jon implementiert wird.

So sieht mein Code aus. Auf dem UI-Thread:

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

und auf dem Spiel thread:

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

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

     // ... 
    } 
} 
0

Wenn Sie eine Lösung ohne Synchronisation Threads beschäftigen kann ich empfehlen die Handler-Schnittstelle mit dem Ereignis zu senden und relevant Daten, die eine Nachricht/ein Bundle zum Spielrendering-Thread verwenden. Die hier beschriebene Schlafumgehung gilt immer noch.

0

Im Allgemeinen werden Ereignisse mit einer Timestamp-Eigenschaft geliefert, sodass die Ereignisrate einfach berechnet und gedrosselt werden kann.

if (currentEventTimestamp - lastEventTimestamp > 500) { 
 

 
    lastEventTimestamp = currentEventTimestamp; 
 

 
    // do something 
 

 
}