2017-08-29 15 views
1

私は卓球のようなゲームを作成しようとしています、と私はパドルの動きに関するいくつかのコードを実装し始めています。パドル自体の動きに関しては、すべてがうまく機能します。私は突然(Iが下方に上向きにパドルを移動直ちに切り替えると、より具体的には、その逆も同様)パドルの方向を変更するときしかし、問題が生じます。パドルは数秒間定位置に固定され、その後、所望の方向に進む。のJavaFX:取得長方形でキーボード結果と急に矩形を移動する「スタック」

私はcanvas.setOnKeyReleased(new KeyReleasedHandler());を削除するときに何が起こるか見て試してみましたが、その後、パドルは停止することなく、同じ方向に動きます。一度鍵を離すとパドルの動きを止めることができます。ここで

はMainApplicationです:ここでは

public class Pong2App extends Application { 
private static final double CANVAS_WIDTH = 900; 
private static final double CANVAS_HEIGHT = 500; 

private static final double ELAPSED_TIME_SPEED = 1.85; 

Ball testBall; 
Paddle leftPaddle; 

@Override 
public void start(Stage primaryStage) throws Exception { 
    Group root = new Group(); 
    Scene scene = new Scene(root); 
    primaryStage.setScene(scene); 

    Canvas canvas = new Canvas(CANVAS_WIDTH, CANVAS_HEIGHT); 
    Bounds canvasBounds = canvas.getBoundsInLocal(); 
    root.getChildren().add(canvas); 

    GraphicsContext gc = canvas.getGraphicsContext2D(); 

    // TODO: remove testBall and leftPaddle; Gives testBall random vX and vY 
    testBall = new Ball(CANVAS_WIDTH/2, CANVAS_HEIGHT/2.5, 30, 30, gc); 
    Random tempRand = new Random(); 
    testBall.setvX((tempRand.nextDouble() * 4) * (tempRand.nextBoolean() ? -1 : 1)); 
    testBall.setvY((tempRand.nextDouble() * 4) * (tempRand.nextBoolean() ? -1 : 1)); 

    leftPaddle = new Paddle(70, CANVAS_HEIGHT/2.5, 10, 100, "Left", gc); 

    canvas.setFocusTraversable(true); 
    canvas.setOnKeyPressed(new KeyPressedHandler()); 
    canvas.setOnKeyReleased(new KeyReleasedHandler()); 

    new AnimationTimer() { 

     @Override 
     public void handle(long currentTime) { 

      testBall.didCollideWithWalls(canvas); 

      if (leftPaddle.getY() <= canvasBounds.getMinY() + 5) 
       leftPaddle.setY(canvasBounds.getMinY() + 5); 

      if (leftPaddle.getY() >= canvasBounds.getMaxY() - 105) 
       leftPaddle.setY(canvasBounds.getMaxY() - 105); 

      if (leftPaddle.didCollideWith(testBall)) { 
       testBall.setvX(-testBall.getvX()); 
       testBall.setX(testBall.getX() + testBall.getvX()); 
      } 

      testBall.update(ELAPSED_TIME_SPEED); 

      leftPaddle.update(ELAPSED_TIME_SPEED); 

      gc.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); 

      testBall.render(gc); 

      leftPaddle.render(gc); 

     } 

    }.start(); 

    primaryStage.show(); 
} 

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

/** 
* Handles what happens when a key is pressed. Depending on what key is pressed, 
* the paddle will move up or down. 
* 
* @author Phillip 
* 
*/ 
private class KeyPressedHandler implements EventHandler<KeyEvent> { 

    @Override 
    public void handle(KeyEvent event) { 
     switch (event.getCode()) { 
     case W: 
      leftPaddle.moveUp(); 
      break; 
     case S: 
      leftPaddle.moveDown(); 
      break; 
     default: 
      break; 
     } 

    } 

} 

/** 
* Handles what happens when a key is released. Depending on what key is 
* released, the paddle will stop moving. 
* 
* @author Phillip 
* 
*/ 
private class KeyReleasedHandler implements EventHandler<KeyEvent> { 

    @Override 
    public void handle(KeyEvent event) { 
     switch (event.getCode()) { 
     case W: 
     case S: 
      leftPaddle.setvY(0); 
      break; 
     default: 
      break; 
     } 
    } 

} 

}

はパドルクラスです:

public class Paddle extends Sprite { 
private int points; 
private String name; 

private static final double PADDLE_SPEED = 2.5; 

public Paddle(double x, double y, double width, double height, String name, GraphicsContext gc) { 
    super(x, y, width, height, gc); 
    this.points = 0; 
    this.name = name; 
} 

@Override 
public boolean didCollideWith(Sprite other) { 
    Ball ball = (Ball) other; 
    double ballCenterX = ball.getCenterX(); 
    double ballRadius = ball.getRadius(); 
    double ballCenterY = ball.getCenterY(); 

    double halfWidth = this.getHalfWidth(); 
    double halfHeight = this.getHalfHeight(); 
    double centerX = this.getCenterX(); 
    double centerY = this.getCenterY(); 

    if (getName().equals("Left")) { 
     boolean hitXBounds = ballCenterX - ballRadius <= centerX + halfWidth; 
     boolean hitTopPartOfBall = ballCenterY - ballRadius <= centerY + halfHeight 
       && ballCenterY - ballRadius >= centerY - halfHeight; 
     boolean hitBotPartOfBall = ballCenterY + ballRadius <= centerY + halfHeight 
       && ballCenterY + ballRadius >= centerY - halfHeight; 

     return hitXBounds && (hitTopPartOfBall || hitBotPartOfBall); 
    } 
    return false; 
} 

@Override 
public void render(GraphicsContext gc) { 
    gc.fillRect(getX(), getY(), getWidth(), getHeight()); 
} 

@Override 
public boolean didCollideWithWalls(Canvas canvas) { 
    Bounds bounds = canvas.getBoundsInLocal(); 

    boolean atTopWall = this.getY() <= bounds.getMinY(); 
    boolean atBotWall = this.getY() >= bounds.getMaxY(); 

    if (atTopWall || atBotWall) { 
     return true; 
    } 

    return false; 
} 

public int getPoints() { 
    return points; 
} 

public void setPoints(int points) { 
    this.points = points; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public void moveUp() { 
    this.setvY(-PADDLE_SPEED); 
} 

public void moveDown() { 
    this.setvY(PADDLE_SPEED); 
} 

}

ありがとうございました!

答えて

2

を押すと、例えばW、そして、あなたは順番に、呼び出し、Wを離した後、S

  • setvY(-PADDLE_SPEED)
  • setvY(PADDLE_SPEED)
  • setvY(0)を押すあなたがするつもり何だろうではありません

Sがまだ押されていても、vY=0になります。

ちょっと後にネイティブキーボードのリピートがSにもう一度呼び出されますので、setvY(PADDLE_SPEED)に再度電話をかけてパドルの移動を開始します。 2つの真偽値(moveUpmoveDown)を使用し、truefalseにそれらを設定して、両方のそれらの値に基づいて速度を更新することを検討してください。例えば。あなたのハンドラで次に

public class Paddle extends Sprite { 

    private boolean moveUp ; 
    private boolean moveDown ; 

    // ... 

    public void setMoveUp(boolean moveUp) { 
     this.moveUp = moveUp ; 
     updateVy(); 
    } 

    public void setMoveDown(booleam moveDown) { 
     this.moveDown = moveDown ; 
     updateVy(); 
    } 

    private void updateVy() { 
     setvY(
      (moveUp ? -PADDLE_SPEED : 0) + 
      (moveDown ? PADDLE_SPEED : 0) 
     ); 
    } 

    // ... 
} 

private class KeyPressedHandler implements EventHandler<KeyEvent> { 

    @Override 
    public void handle(KeyEvent event) { 
     switch (event.getCode()) { 
     case W: 
      leftPaddle.setMoveUp(true); 
      break; 
     case S: 
      leftPaddle.setMoveDown(true); 
      break; 
     default: 
      break; 
     } 

    } 

} 

private class KeyReleasedHandler implements EventHandler<KeyEvent> { 

    @Override 
    public void handle(KeyEvent event) { 
     switch (event.getCode()) { 
     case W: 
      leftPaddle.setMoveUp(false); 
      break ; 
     case S: 
      leftPaddle.setMoveDown(false); 
      break; 
     default: 
      break; 
     } 

    } 

} 
私はアニメーションタイマーでそれらをチェックしに行くかどう
+0

しますか? –

+1

@PhillipLagocああ、本当の必要はありません。両方のブール値を変更したときだけチェックし、両方の値に応じて 'setvY(...)'を呼び出します。私は答えを更新しました。 –

関連する問題