2009-04-27 17 views
14

Rozwijam grę dla Androida. Wiele się dzieje, ale działa dość sprawnie. To znaczy, oczywiście, dopóki użytkownik nie dotknie ekranu.Dlaczego wydarzenia dotykowe niszczą moją ilość klatek na sekundę w systemie Android?

Chociaż oni dotykania go, onTouchEvent nazywa (z action = ACTION_MOVE, x = 0 i y = 0) w przybliżeniu raz na dziesięć milisekund na to, co wydaje się być dość wysoki priorytet, ponieważ absolutnie likwidujący framerate. Po zakończeniu dotknięcia, szybkość klatek powraca do stanu dobrego.

Próbowałem

  • mający wejście onTouchEvent uchwyt do gry jak zwykle
  • mający onTouchEvent zwrot true razu
  • nie mając onTouchEvent realizowane na wszystkich

problem nie ustąpi we wszystkich trzech sytuacjach.

Czy ktoś to napotkał? Czy istnieje sposób na zmniejszenie szybkości generowania zdarzeń lub zapewnienie, że są one generowane tylko w przypadku rzeczywistego ruchu, lub używają metody odpytywania, która właśnie pobiera bieżącą lokalizację dotyku? A może po prostu sposób na wyłączenie go w całości?

Odpowiedz

12

Read ten wątek. Zasadniczo chcesz przespać wątek zdarzenia, ponieważ w przeciwnym razie system będzie pompował wiele zdarzeń (między x, y i presją zawsze zachodzi jakiś ruch), które musisz obsłużyć.

+0

link już nie działa. –

0

Być może jest to dość oczywiste rozwiązanie, ale ... czy próbowałeś obsługiwać tylko 1/10 z nich? Jeśli przetwarzanie jest uruchamiane co 10ms w wątku interfejsu użytkownika, prawdopodobnie spowolni to szybkość klatek, tak. A co jeśli zamiast tego po prostu zgromadzisz trochę kontrę i dokonasz tylko przetwarzania, gdy minie jakiś minimalny próg?

1

Próbowałem śledzić wszystko, co faceci mówili temat, ale muszę przyznać, że po wypróbowaniu kilku sposobów realizacji co sugeruje, że wciąż jeszcze nie były w stanie osiągnąć jakikolwiek pozytywny wyniki. Czy któryś z was mógłby podać przykładowy kod? W szczególności, Chciałbym wiedzieć, jak sprawić, aby wątek główny/UI spał. Jeśli dotyczy moich gier, dobrze byłoby wiedzieć, jak ustawić model odpytywania, taki jak Jon.

Oto, jak wygląda mój kod. Na wątku UI:

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

i na gwincie gra:

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

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

     // ... 
    } 
} 
0

Jeśli chcesz rozwiązanie bez konieczności zajmowania się synchronizacji wątków mogę polecić użyciu interfejsu Handler wysłać zdarzenie i istotne dane za pomocą wiadomości/pakietu do wątku renderowania gry. Obowiązujące tutaj obejście snu nadal obowiązuje.

0

Ogólnie rzecz biorąc, wydarzenie ma właściwość timestamp, dzięki czemu można łatwo obliczyć i zmniejszyć częstotliwość zdarzeń.

if (currentEventTimestamp - lastEventTimestamp > 500) { 
 

 
    lastEventTimestamp = currentEventTimestamp; 
 

 
    // do something 
 

 
}