2014-01-24 1 views
2

JavaFX에서 사각형 모양의 왼쪽으로 오른쪽 이동을 구현하려고합니다. 내가 아니라 지속적으로 (내가 몇 번 동안 유지, 즉 I 키를 공개하지 않음) 중 좌/우 키를 지속적으로 사각형 이동을 누르면 다음javaFX에서 KeyPress 이벤트로 부드러운 애니메이션을 얻는 방법은 무엇입니까?

public void start(Stage primaryStage) throws Exception { 
    AnchorPane ancPane = new AnchorPane();  
    final Rectangle rect = new Rectangle(); 
    rect.setHeight(50); 
    rect.setWidth(50); 
    ancPane.getChildren().add(rect); 
    Scene scene = new Scene(ancPane, 400, 200, Color.GREEN); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 


    scene.setOnKeyPressed(new EventHandler<KeyEvent>() { 

     @Override 
     public void handle(KeyEvent keyEvent) { 
      System.out.println("hello"); 

      if(keyEvent.getCode().toString() == "RIGHT"){ 
       System.out.println("Move Right"); 
       TranslateTransition translateTransitionRight = new TranslateTransition(); 
       translateTransitionRight.setDuration(Duration.millis(200)); 
       translateTransitionRight.setNode(rect); 
       translateTransitionRight.setFromX(rect.getTranslateX()); 
       translateTransitionRight.setToX(rect.getTranslateX()+30); 
       translateTransitionRight.play(); 
      } 

      if(keyEvent.getCode().toString() == "LEFT"){ 
       System.out.println("Move Left"); 
       TranslateTransition translateTransitionRight = new TranslateTransition(); 
       translateTransitionRight.setDuration(Duration.millis(200)); 
       translateTransitionRight.setNode(rect); 
       translateTransitionRight.setFromX(rect.getTranslateX()); 
       translateTransitionRight.setToX(rect.getTranslateX()-30); 
       translateTransitionRight.play(); 
      }    
     } 
    }); 

} 

: 다음은 내 코드입니다. 애니메이션이 시작된 직후에 잠깐 멈 춥니 다. 일시 중지 후 애니메이션이 부드럽게 계속됩니다.

KeyEvents로 애니메이션 일시 중지를 제거하려면 어떻게해야합니까?

나는 사각형을 이동에 대한 AnimationTimer을 사용하고, 단지 해제 키를 누르거나 키에 속도를 나타내는 속성을 업데이트 할

답변

4

:

final Rectangle rect = ... ; 

final double rectangleSpeed = 100 ; // pixels per second 
final double minX = 0 ; 
final double maxX = 800 ; // whatever the max value should be.. can use a property and bind to scene width if needed... 
final DoubleProperty rectangleVelocity = new SimpleDoubleProperty(); 
final LongProperty lastUpdateTime = new SimpleLongProperty(); 
final AnimationTimer rectangleAnimation = new AnimationTimer() { 
    @Override 
    public void handle(long timestamp) { 
    if (lastUpdateTime.get() > 0) { 
     final double elapsedSeconds = (timestamp - lastUpdateTime.get())/1_000_000_000.0 ; 
     final double deltaX = elapsedSeconds * rectangleVelocity.get(); 
     final double oldX = rect.getTranslateX(); 
     final double newX = Math.max(minX, Math.min(maxX, oldX + deltaX)); 
     rect.setTranslateX(newX); 
    } 
    lastUpdateTime.set(timestamp); 
    } 
}; 
rectangleAnimation.start(); 

scene.setOnKeyPressed(new EventHandler<KeyEvent>() { 
    @Override 
    public void handle(KeyEvent event) { 
    if (event.getCode()==KeyCode.RIGHT) { // don't use toString here!!! 
     rectangleVelocity.set(rectangleSpeed); 
    } else if (event.getCode() == KeyCode.LEFT) { 
     rectangleVelocity.set(-rectangleSpeed); 
    } 
    } 
}); 

scene.setOnKeyReleased(new EventHandler<KeyEvent>() { 
    @Override 
    public void handle(KeyEvent event) { 
    if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT) { 
     rectangleVelocity.set(0); 
    } 
    } 
}); 

UPDATE :

AnimationTimer 한 번 핸들의 메소드를 실행 각을 프레임이 JavaFX 메커니즘에 의해 렌더링되는 시간. 핸들 메소드에 오랫동안 전달 된 시간은 렌더링 프레임의 타임 스탬프 (나노초 단위)입니다.

이것이 작동하는 방식은 우리가 마지막 업데이트 시간을 추적한다는 것입니다. handle (...) 메서드는 마지막 업데이트 이후의 경과 시간을 계산하고, 사각형의 속도로 곱하고, 그 양만큼 사각형의 translateX를 업데이트합니다. AnimationTimer는 항상 실행되지만 처음에는 속도가 0으로 설정되어 사각형이 움직이지 않습니다.

keyPressed 처리기는 오른쪽으로 이동하는 경우 양수 값으로, 왼쪽으로 이동하면 음수 값으로 간단히 속도를 변경합니다. keyReleased 핸들러는 속도를 다시 0으로 설정합니다.

+0

이 접근법의 좋은 점은 하나의 직사각형 속도를 프로그래밍 방식으로 완벽하게 제어한다는 것입니다. 키보드 반복 속도와 같은 OS 레벨 설정에 의해 결정되지 않습니다. –

+0

안녕하세요 제임스, 왼쪽/오른쪽 키를 번갈아 누르면 애니메이션 시작 부분에 약간의 일시 중지 효과가 있습니다. 또한 여기에서 구현하는 논리에 대한 설명을 제공해주십시오. – Angom

+0

일부 분석을 통해 나는 논리를 이해할 수 있습니다. 또한 scene.setOnKeyReleased() 내에서 작은 수정을 만들었습니다. LEFT/RIGHT 키를 놓을 때만 rectangleVelocity를 0으로 설정합니다. 그렇지 않으면 애니메이션에서 일시 중지 효과가 발생합니다. 감사. – Angom

관련 문제