2015-12-08 1 views
3

Je suis nouveau sur javafx, et je suis en train de programmer un jeu en utilisant ses fonctions de rendu, en particulier, GraphicsContext.fillArc() et similaire dans eclipse.Comment appliquer l'antialiasing aux méthodes javafx comme GraphicsContext.fillArc()?

Ceci est mon code actuel:

 BorderPane root = new BorderPane(); 

     Scene scene = new Scene(root, 400, 400); 
     primaryStage.setScene(scene); 
     scene.getStylesheets() 
       .add(getClass().getResource("application.css").toExternalForm()); 

     Canvas canvas = new Canvas(400, 400); 
     root.getChildren().add(canvas); 

     GraphicsContext gc = canvas.getGraphicsContext2D(); 
     new AnimationTimer() 
     { 
      public void handle(long currentNanoTime) 
      { 
       gc.setFill(Color.BLUE); 
       gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND); 
      } 
     }.start(); 
     primaryStage.show(); 

Cependant la méthode fillArc() rend une forme sur mon écran avec les bords déchiquetés. Je veux que l'antialiasing soit appliqué pour que les bords soient lissés. Cependant, je ne trouve aucune méthode associée dans la classe GraphicsContext, et la modification de l'instanciation de scene en new Scene(root, 400, 400, false, SceneAntialiasing.BALANCED); n'a aucun effet. Donc, ma question est de savoir comment atteindre antialiasing sur GraphicsContext.fillArc() ou si c'est fondamentalement possible?

En outre, je suis très nouveau pour javafx et cgi en général, donc toutes les suggestions et recommandations sont les bienvenues.

Mise à jour:

Comme le suggère @jewelsea, lorsque le bloc de code gc.setFill(Color.BLUE); gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND); est placé à l'extérieur de la sous-classe anonyme de AnimationTimer, l'image rendue est anti-crénelé. Aucun de nous ne peut comprendre pourquoi à partir de maintenant. FYI.

+2

Curieusement, si vous commentez le minuteur d'animation et que vous dessinez l'arc sans lui, l'arc est bien anti-aliasé. Je ne sais pas pourquoi. – jewelsea

+0

@jewelsea c'est très intéressant. Je vais regarder dans les propriétés de la classe 'AnimationTimer'. – cyqsimon

Répondre

2

J'ai rencontré un problème similaire en jouant avec Canvas et AnimationTimer. Une clé importante pour la solution est le comment posted by @jewelsea:

« ... si vous commentez le minuteur d'animation et juste dessiner l'arc sans elle, l'arc est bien ... anti-crénelé »

Cela signifie fondamentalement, si nous dessinons l'arc une fois il est anti-aliasé. Mais si nous le dessinons dans la méthode handle() du AnimationTimer, il est dessiné 60 fois par seconde. Les résultats peuvent être mieux vus après avoir ajouté un long sommeil à la méthode handle(). La première fois, le cercle est rendu sur un fond blanc et a l'apparence souhaitée. La deuxième fois, un cercle bleu est rendu au-dessus du cercle bleu précédent. Les pixels qui étaient partiellement colorés en bleu à cause de l'anti-crénelage deviennent plus foncés. La même chose se produit lorsque le cercle est dessiné la troisième fois, et ainsi de suite. L'image suivante montre une partie agrandie de l'arc après 1, 2, 3, 4, 5, 10 et 50 itérations:

arcs

Une solution simple à ce problème consiste à remplir la toile avec le fond couleur, avant de rendre quoi que ce soit:

public void handle(long currentNanoTime) { 
    gc.setFill(Color.WHITE); 
    gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); 

    gc.setFill(Color.BLUE); 
    gc.fillArc(150, 150, 100, 100, 0, 240, ArcType.ROUND); 
} 
+1

@jewelsea Mystère résolu. ;) – Sleafar