2016-07-19 2 views
0

J'ai un problème où ma méthode onFrame modifie la position d'un objet pendant paintComponent. Parce que mon JPanel rend une scène relative à la position de son objet focus, tout décalage de la position de mise au point pendant la peinture fait en sorte qu'une partie de la scène soit traduite du reste de la scène (visible par le joueur l'écran). Par conséquent je voudrais empêcher le focus d'être modifié pendant la partie de paintComponent.Empêche la mise à jour pendant paintComponent (Java)

composant de peinture est ici:

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

} 

La méthode render appelée:

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

} 

Le niveau de rendu méthode qui utilise en fait focus:

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

Je ne vois pas l'utilisation de 'focus' dans votre bloc' synchronization'. Je vois qu'il est utilisé juste en dessous. Déplacez votre bloc de synchronisation vers ces instructions –

+0

Pour une meilleure aide plus rapidement, postez un [MCVE] ou [Short, Self Contained, Example correct] (http://www.sscce.org/). –

+0

@VinceEmigh la méthode 'universe.getCurrentWorld(). Render' prend le focus de la fenêtre qui est passée (dans ce cas,' this') –

Répondre

0

Ah, je dois aussi synchroniser le code dans onFrame qui met à jour le monde. Après avoir ajouté deux blocs synchronisés, cela fonctionne correctement:

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

}