# onDraw Canvas jede Millisekunde aufrufen?



## bruce85 (6. Okt 2012)

Hallo,
der Titel sagt schon alles, wie kann ich ambesten die Methode onDraw jede Millisekunde aufrufen?
Ich möchte ein Paar animationen im Spiel laufen lassen, nur weiss ich nicht, wie ich das ambesten anstellen soll.

Wie könnte man das machen?

Ich bedanke mich schonmal im Voraus.

MfG


----------



## Network (6. Okt 2012)

Jede Millisekunde ist schonmal viel zu viel Leistung die du da reinstecken willst.
Unser Auge kann nur eine maximale Framerate wahrnehmen und Bildschirme können auch nur eine bestimmte Framerate darstellen.

Jede Millisekunde ist zu viel, mach alle 10 Millisekunden daraus oder mehr, da sparst du schonmal 10mal mehr Leistung.
Unser Gehirn berechnet die Lücken dazwischen.

Animationen werden niemals über Zeichenmethoden verwaltet. Vieleicht habe ich das bei dir auch falsch verstanden.

Schlussendlich: Was ist daran so schwer die Methode onDraw() aufzurufen? Du holst dir das Canvas übergibst es und lässt zeichnen.
Ohne deine eigenen Ansätze/Code/Überlegungen kann man nur schwer raten was du genau wissen wills.

Gruß
Net


----------



## Marco13 (6. Okt 2012)

1000 FPS?! :autsch: Fang' mal mit 30 an


----------



## bruce85 (6. Okt 2012)

Vielen Dank für die antwort.

z.B. Spieler bewegungen oder andere objekte, die sich im Spiel bewegen, deshalb möchte ich die onDraw Methode mit postInvalidate(); jede Paar Millisekunde neu Zeichnen, damit die bewegungen auch aktualisiert werden.

Wie könnte man das ambesten machen?

MfG


----------



## Bernd Hohmann (6. Okt 2012)

Normalerweise hält man im Hintergrund zwei Images. Wärend man das erste Image löscht und neu bemalt wird das zweite angezeigt. Danach tauscht man einfach den Zähler für das aktuelle Bild von 1 auf 0 und malt auf Image 1 herum.

Den Wechsel zwischen den Bildern stimmt man so ab, dass ca. 30 Wechsel in der Sekunde stattfinden (sofern das Backend mithalten kann).

Nach jeder Teilbewegung bereits neu anzuzeigen ist nicht so glücklich weil die Übergabe des Images (letztendlich nur ein byte-Array) an die Hardware in Java relativ träge ist.

Bernd


----------



## bruce85 (6. Okt 2012)

Danke Dir.

Das ist mir ein bisschen zu kompliziert, gibt es Vielleicht gute Tutorials, indem man in Android 2D Spiele Programmieren lernt oder wo Programmiert man ambesten 2D Spiele für Android?

Ich benutze derzeit Eclipse mit Android-SDK.

Danke schonmal.

MfG


----------



## Marco13 (6. Okt 2012)

Da war mal ein Google I/O 2009 - Writing Real-Time Games for Android - YouTube - könnte ein Anfang sein.


----------



## s4ke (6. Okt 2012)

Kleiner Tipp:

Schau dir den Aufbau von Engines die auf OpenGL basieren an oder sonstiges. AndEngine hat mir ziemlich dabei geholfen, da reinzukommen.

https://github.com/nicolasgramlich/AndEngine (ist halt eine Engine für Android)


----------



## bruce85 (7. Okt 2012)

Danke Dir.

Ich werd das mal versuchen.

MfG


----------



## bruce85 (12. Okt 2012)

Hallo nochmal,
ich hab das mal so gemacht:

```
public class Panel extends View implements OnTouchListener {
		public Panel(Context context) {
            super(context);

            myTimer = new Timer();
    		myTimer.schedule(new TimerTask() {			
    			@Override
    			public void run() {
    				TimerMethod();
    			}
    			
    		}, 0, 50);
        }
		
		private void TimerMethod() {
			postInvalidate();
		}
```

Das funktioniert, aber irgendwann an einer bestimmten Zeitpunkt, beendet sich die App einfach ohne irgendwelche fehlermeldung.

Ist das eigentlich Sinnvoll, das mit dem Timer so zu machen?
Oder wie könnte man das ambesten anders lösen?

MfG


----------



## bruce85 (13. Okt 2012)

Ich hab das Problem gelöst.

Es lag daran, dass ich in onDraw Methode einen Font geladen habe und bei jedem aufruf von onDraw die Font erneut geladen wurde, deshalb hat sich das Spiel nach einer gewissen zeit beendet.

Ich hab das jetzt mit Thread gelöst, dass er nach jede 75 Millisekunde die Methode onDraw aufruft bzw. neu zeichnet:

```
public Panel(Context context) {
            super(context);
            myFont1 = Typeface.createFromAsset(getAssets(),"fonts/Comic Sans MS.ttf");
            paint.setAntiAlias(true);
            
            new Thread(new Runnable() {
                public void run() {
                    while(true){
                        try {
                            Thread.sleep(75);
                            postInvalidate();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
              }).start();
        }
```
nun funktioniert das.

Trotzdem vielen Dank für die Hilfe.

MfG


----------



## s4ke (14. Okt 2012)

Wie schauts mit einem Executor aus? Da spart man sich das Erstellen eines Threads bei jedem Aufruf der Methode (der Garbagecollector wird sich freuen).


----------



## Marco13 (14. Okt 2012)

So wie ich das sehe ist das ein Konstruktor, und der Thread wird nur EINmal gestartet. Aber nie beendet, das sollte man vielleicht nochmal reviewen


----------

