2008-09-15 3 views
2

Ich schreibe ein Handy-Spiel mit j2me. In diesem Spiel verwende ich mehrere Canvas-Objekte. Zum Beispiel ist das Spielmenü ein Canvas-Objekt und das eigentliche Spiel ist auch ein Canvas-Objekt. Ich habe festgestellt, dass auf einigen Geräten, wenn ich von einem Canvas zu einem anderen, z. B. vom Hauptmenü zum Spiel wechseln, der Bildschirm "flackert". Ich benutze mein eigenes doppelt gepuffertes Canvas.j2me Bildschirm flimmern, wenn zwischen den Leinwänden

Gibt es trotzdem, um dies zu vermeiden?

Antwort

0

Verwenden Sie doppelte Pufferung? Wenn das Gerät selbst keine Doppelpufferung unterstützt, sollten Sie einen Offscreen-Puffer (Image) definieren und zuerst darauf malen und dann das Endergebnis auf den realen Bildschirm malen. Tun Sie dies für jede Ihrer Leinwände. Hier ein Beispiel:

public class MyScreen extends Canvas { 
    private Image osb; 
    private Graphics osg; 
    //... 

    public MyScreen() 
    { 
     // if device is not double buffered 
     // use image as a offscreen buffer 
     if (!isDoubleBuffered()) 
     { 
      osb = Image.createImage(screenWidth, screenHeight); 
      osg = osb.getGraphics(); 
      osg.setFont(defaultFont); 
     } 
    } 

    protected void paint(Graphics graphics) 
    { 
     if (!isDoubleBuffered()) 
     { 
     // do your painting on off screen buffer first 
     renderWorld(osg); 

     // once done paint it at image on the real screen 
     graphics.drawImage(osb, 0, 0, Tools.GRAPHICS_TOP_LEFT); 
     } 
     else 
     { 
     osg = graphics; 
     renderWorld(graphics); 
     } 
    } 
} 
+0

Ich verwende die doppelte Pufferung, indem ich einen Offscreen-Puffer mit einer ähnlichen Methode wie Ihre definiere. Das Flackern tritt immer auf, wenn der Hauptthread des neuen Canvas gestartet wird. – Dimitris

0

Eine mögliche Lösung ist, durch den Schalter Synchronisieren über Display.callSerially(). Das Flimmern wird wahrscheinlich dadurch verursacht, dass die App versucht, auf den Bildschirm zu zeichnen, während der Wechsel des Canvas noch andauert. callSerial() soll warten, bis das Repaint beendet ist, bevor versucht wird, run() erneut aufzurufen.

Aber das hängt ganz vom Telefon ab, da viele Geräte callSerial() nicht implementieren, geschweige denn die in der offiziellen Dokumentation aufgeführte Implementierung. Die einzigen Geräte, von denen ich wusste, dass sie mit callSerial() funktionieren, waren Siemens-Telefone.

Ein weiterer möglicher Versuch wäre, eine Thread.sleep() von etwas wie 1000 ms zu setzen, um sicherzustellen, dass Sie Ihre setCurrent() Methode vorher aufgerufen haben. Auf diese Weise kann das Gerät die Änderung vor den anzeigbaren Versuchen zum Zeichnen vornehmen.

Das wahrscheinlichste Problem ist, dass es ein Geräteproblem ist und die garantierte Lösung für das Flimmern ist einfach - verwenden Sie ein Canvas. Wahrscheinlich nicht, was du hören wolltest. :)

+0

Ich folgte Ihrem Rat und legte einen langen Thread.sleep() in den Code. Ich habe festgestellt, dass das Flimmern tatsächlich nach dem ersten repaint() in meiner Canvas-Methode run() auftritt. Irgendwelche Gedanken? – Dimitris

6

Ich würde sagen, dass die Verwendung mehrerer Leinwände in der Regel schlechtes Design ist. Bei manchen Handys wird es sogar abstürzen. Der beste Weg wäre eine Leinwand mit Tracking-Status der Anwendung zu verwenden. Und dann in Farbe Methode würden Sie

protected void paint(final Graphics g) { 
    if(menu) { 
    paintMenu(g); 
    } else if (game) { 
    paintGame(g); 
    } 
} 

Es gibt bessere Möglichkeiten Anwendungszustand mit Bildobjekten zu handhaben, die das Design sauberer machen würde, aber ich glaube, Sie auf die Idee gekommen :)

/JaanusSiim

0

Es könnte eine gute Idee sein, die GameCanvas-Klasse zu verwenden, wenn Sie ein Spiel schreiben. Es ist viel besser für diesen Zweck und bei richtiger Anwendung sollte es Ihr Problem lösen.

+0

Ich habe ursprünglich GameCanvas-Objekte verwendet.Ich habe das gleiche "Flicker" Verhalten bei dieser Implementierung beobachtet. – Dimitris

+0

Dies liegt daran, dass einige Telefone sogar für GameCanvas Back-Buffering nicht implementiert sind. – Honza

0

Hypothetisch, 1 Leinwand mit einem Sate Machine Code für Ihre Anwendung zu verwenden ist eine gute Idee. Allerdings stürzt das einzige Gerät, auf dem ich Anwendungen testen muss (MOTO v3) beim Laden der Ressourcen ab, nur weil zu viel Code in 1 GameCanvas geladen wird (nicht mit Canvas probiert). Es ist so schmerzhaft wie es real ist und ich habe keine Lösung für das Problem gefunden. Wenn Sie Glück haben, eine gute Anzahl von Geräten zum Testen zu haben, lohnt es sich beide Ansätze implementiert zu haben und ziemlich viele Versionen Ihres Spiels für jedes Gerät zu erstellen.

+0

OMG, wow, ich habe es gerade gefunden ... Im Grunde habe ich zuerst eine introCanvas, eine loadingCanvas und eine gameOverCanvas verwendet, die wir in der neuen Version (alle in 1 Canvas/State Machine) überhaupt nicht benutzen. Es stellte sich heraus, dass das Löschen der Dateien aus dem Ordner src das Anwendungsfehlerproblem löste :). Tolle!! –