2017-10-20 14 views
0

JavaFXGraphicsContext으로 게임을 시작했습니다. 특히 클리핑 부분은 저에게 흥미 롭습니다. JavaFX 클리핑에서 '복권 스크래치 티켓'생성 - 효과

그래서 일부 그래픽을 생성하고

(주변에 이동하는 간단한 사각형) 그것에 대한 클리핑 마스크를 만들려고하지만 난이 버그 또는 잘못된 때문입니다 있는지 확실하지 않습니다 그것은 몇 가지 이상한 행동을 (발견 코드 사용)

아래에서 문제를 보여주는 예제 응용 프로그램을 찾을 수 있습니다.

난 내 코드에서 기대했던

설명 : (가에서 그려지는하지만) 마젠타 위에서만 볼 텍스트와 마젠타 사각형,

은 실제로 당신이 처음를 참조 정확히와 흰색 캔버스 !

응용 프로그램 창을 이동하면 MAGENTA 사각형이 (예상대로) 이동합니다! ANTIQUEWHITE 채우기가 표시됩니다 (나는 결코 예상하지 못함). 그리고 MAGENTA로 덮여 있던 모든 영역이 이제 표시됩니다 (클리핑 없음)

ANTIQUEWHITE 및 MAGENTA 항목은 잘못된 것이 더 분명하게 보이도록하기 위해 사용됩니다. 전체 캔버스가 처음에 지워지고 하나의 클리핑 만 수행되면 다시 칠하는 데 문제가 없어야합니다 (또는 오래된 그림 위에 페인트 칠하는 경우)

응용 프로그램을 시작한 후 '추첨 티켓' documentation for restore()에서

public class ClippingExampleApp extends Application { 

    private boolean clip = true; 
    private static Bounds clippingArea = new BoundingBox(100, 50, 300, 300); 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle("Clipping Test App"); 
     primaryStage.setX(100); 
     primaryStage.setY(50); 

     Group root = new Group(); 
     Canvas canvas = new Canvas(640, 480); 
     root.getChildren().add(canvas); 
     primaryStage.setScene(new Scene(root)); 

     ChangeListener<Number> updateBounds = new ChangeListener<Number>() { 

      @Override 
      public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) { 
       clippingArea = new BoundingBox(primaryStage.getX(), primaryStage.getY(), 300, 300); 
       draw(canvas, clip); 
      } 
     }; 
     primaryStage.yProperty().addListener(updateBounds); 
     primaryStage.xProperty().addListener(updateBounds); 
     primaryStage.widthProperty().addListener(updateBounds); 
     primaryStage.heightProperty().addListener(updateBounds); 

     primaryStage.show(); 
     clippingArea = new BoundingBox(primaryStage.getX(), primaryStage.getY(), 300, 300); 
     draw(canvas, clip); 
    } 

    private static void draw(Canvas canvas, boolean clip) { 
     GraphicsContext gc = canvas.getGraphicsContext2D(); 
     // CLEAR THE COMPLETE CANVAS 
     gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); 
     gc.save(); 
     if (clip) { 
      // clipping rect 
      gc.rect(clippingArea.getMinX(), clippingArea.getMinY(), clippingArea.getWidth(), clippingArea.getHeight()); 
      gc.clip(); 

      // fill the whole background (this should only affect the clipped 
      // area 
      gc.setFill(Color.ANTIQUEWHITE); 
      gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); 
      // this should overlap the Color.ANTIQUEWHITE - so no ANTIQUEWHITE is visible 
      gc.setFill(Color.MAGENTA); 
      gc.fillRect(clippingArea.getMinX(), clippingArea.getMinY(), clippingArea.getWidth(), clippingArea.getHeight()); 

      // finally fill the text, which sould only be visible where the magenta rect is... 
      String text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."; 
      gc.setFill(Color.BLACK); 
      gc.fillText(text, 50, 100); 
     } 
     gc.restore(); 
    } 
} 
+0

무엇이 당신의 질문입니까? – Sedrick

+0

분명히 질문은이 이상한 행동을 고치고 MAGENTA – lumo

답변

2

영향 : 현재 경로가 복원되지 않습니다

하는 것으로.

따라서 모든 gc.rect() 호출은 클립으로 사용되는 단일 경로로 누적됩니다. 당신이 if (clip) 블록의 시작 부분에 경로를 취소

gc.beginPath(); 

를 추가하는 경우

, 당신은 당신이 예상하는 생각 동작을 참조하십시오.

+0

덕분에 영역을 잘라내는 방법입니다! 사실 나는 그 경로가 각 페인트 후에 지워 졌다고 생각했고 beginPath는 필요하지 않습니다. – lumo