2016-07-19 10 views
0

Ich habe ein Problem, wo meine onFrame Methode die Position eines Objekts während paintComponent ändert. Da mein JPanel eine Szene relativ zur Position ihres focus Objekts rendert, bewirkt jede Verschiebung der Fokusposition während des Malens, dass ein Teil der Szene vom Rest der Szene übersetzt wird (dies ist für den Spieler als ein weißer Streifen sichtbar) der Bildschirm). Daher möchte ich verhindern, dass die focus während eines Teils der paintComponent geändert wird.Update während PaintComponent (Java) verhindern

Hier Lackkomponente:

@Override 
public void paintComponent(Graphics g) { 

    if (focus == null) { 
     return; 
    } 

    super.paintComponent(g); 
    synchronized (focus) { 
     universe.getCurrentWorld().render(this, g, true); //draws scene around focus 
    } 
    focus.getInventory().render(this, g); 
    focus.renderHealthBar(g); 

    if (dialogQ.peek() != null) { 
     dialogQ.peek().render(this, g); 
    } 

} 

Die Render-Methode aufgerufen wird:

public void render(FocusedWindow g, Graphics gr, boolean showOutlands) { 

    level.renderMap(g, gr, showOutlands); 
    col.renderAround(g, gr); 

    for (Detector p : colliders.toArray(new Detector[0])) { 
     p.renderAround(g, gr); 
    } 

} 

Die Level-Methode machen die focus tatsächlich verwendet:

public void renderMap(FocusedWindow g, Graphics gr, boolean renderOutside) { 
    int cushion = 4; 
    int scaleFactor = 2; 
    int minX = g.getFocus().getPos().getX()/Tile.WIDTH - g.getDimensions().getX()/Tile.WIDTH/scaleFactor - cushion; 
    int maxX = g.getFocus().getPos().getX()/Tile.WIDTH + g.getDimensions().getX()/Tile.WIDTH/scaleFactor + cushion; 
    int minY = g.getFocus().getPos().getY()/Tile.WIDTH - g.getDimensions().getY()/Tile.WIDTH/scaleFactor - cushion; 
    int maxY = g.getFocus().getPos().getY()/Tile.WIDTH + g.getDimensions().getX()/Tile.WIDTH/scaleFactor + cushion; 

    for (int i = minX; i < maxX; i++) { 
     for (int j = minY; j < maxY; j++) { 
      if (i >= 0 && i < map.length) { 
       if (j >= 0 && j < map[i].length) { 
        map[i][j].drawTile(g, gr, new Vector(i,j)); 
       } 
       else if (renderOutside) { 
        map[0][0].drawTile(g, gr, new Vector(i,j)); 
       } 
      } 
      else if (renderOutside) { 
       map[0][0].drawTile(g, gr, new Vector(i,j)); 
      } 
     } 
    } 

} 
+0

Ich sehe nicht, 'focus' in Ihrem' synchronization' Block verwendet wird. Ich sehe, dass es direkt unter verwendet wird. Verschieben Sie den Synchronisierungsblock zu diesen Anweisungen –

+0

Um eine bessere Hilfe zu erhalten, veröffentlichen Sie ein [MCVE] oder [Short, Self Contained, Correct Example] (http://www.sscce.org/). –

+0

@VinceEmigh Die Methode 'universum.getCurrentWorld(). Render' verwendet den Fokus aus dem übergebenen Fenster (in diesem Fall' this') –

Antwort

0

Ah, ich brauche auch Synchronisieren Sie den Code in onFrame, der die Welt aktualisiert. Nach der Zugabe von zwei synchronisierten Blöcke, es funktioniert gut:

@Override 
protected void onFrame() { 

    long time = getTimestamp(); 
    double deltaTime = (time - lastTime)/1000000000d; 
    lastTime = time; 

    if (deltaTime > 0.2) { //this is shitty 
     Main.log("high delta time detected (" + deltaTime + " sec)"); 
    } 

    if (dialogQ != null && dialogQ.peek() != null && dialogQ.peek().update(deltaTime)) { 
     dialogQ.poll(); 
    } 

    if (isPaused() || isEditingInventory()) { 
     return; 
    } 

    if (!hasDied && focus != null && focus.isDead()) { 
     hasDied = true; 
     Main.setOverlay(new DeathOverlay()); 
    } 

    if (universe == null || universe.getCurrentWorld() == null) { 
     return; 
    } 

    repaint(); 
    synchronized (this) { 
     universe.getCurrentWorld().update(deltaTime); 
    } 

} 

@Override 
public void paintComponent(Graphics g){ 

    if (focus == null) { 
     return; 
    } 

    super.paintComponent(g); 
    synchronized (this) { 
     universe.getCurrentWorld().render(this, g, true); 
    } 
    focus.getInventory().render(this, g); 
    focus.renderHealthBar(g); 

    if (dialogQ.peek() != null) { 
     dialogQ.peek().render(this, g); 
    } 

} 
Verwandte Themen