2016-11-16 9 views
0

Я начинаю и пытаюсь создать простую игру-мини-игру с Java FX. Я построил небольшой гольф-клуб, используя линии. Я получаю пользовательский ввод о силе ударов со слайдера и могу сделать удар с помощью клавиатуры в 8 разных направлениях.Игра с мини-игру Java FX - как замедлить движение шарика

Если я нажал, например, кнопку H, мяч начинает двигаться вправо. Если значение слайдера было минимальным, оно движется медленно, и если его максимум, он движется очень быстро. Но я не могу заставить движение замедляться, пока оно не остановится.

Любые идеи, как это сделать? Мой код до сих пор ниже.

Спасибо заранее!

package sample; 

import javafx.animation.AnimationTimer; 
import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.Slider; 
import javafx.scene.input.KeyCode; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.shape.Line; 
import javafx.stage.Stage; 

public class Main extends Application { 

    double directionx = 0; 
    double directiony = 0; 
    Line line1,line2,line3,line4,line5,line6,line7,line8,line9; 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 

     primaryStage.setTitle("Minigolf"); 
     Pane pane = new Pane(); 
     Scene scene = new Scene(pane, 900, 600); 
     pane.setStyle("-fx-background-color: green"); 
     primaryStage.setScene(scene); 

     Slider slider = new Slider(); 
     slider.setMin(1); 
     slider.setMax(10); 
     slider.setValue(1); 
     slider.setShowTickLabels(true); 
     slider.setShowTickMarks(true); 
     slider.setLayoutX(10); 
     slider.setLayoutY(10); 

     Circle ball = new Circle(10); 
     Circle hole = new Circle(15); 

     hole.setCenterX(75); 
     hole.setCenterY(430); 
     hole.setFill(Color.YELLOW); 

     ball.setCenterX(100); 
     ball.setCenterY(300); 
     // creating golfcourse with lines 
     line1 = new Line(50,200,500,200); 
     line2 = new Line(50,350,650,350); 
     line3 = new Line(50,200,50,350); 
     line4 = new Line(500,200,500,50); 
     line5 = new Line(650,350,650,200); 
     line6 = new Line(500,50,800,50); 
     line7 = new Line(800,50,800,500); 
     line8 = new Line(800,500,50,500); 
     line9 = new Line(50,500,50,350); 

     pane.getChildren().addAll(slider,ball,hole,line1,line2,line3,line4,line5,line6,line7,line8,line9); 


     new AnimationTimer() { 
      @Override 
      public void handle(long now) { 

        double ballY = ball.getCenterY(); 
        double newballY = ballY + directiony; 
        // if ball touches vertical walls 
        if (ball.getBoundsInParent().intersects(line5.getBoundsInParent()) 
          || ball.getBoundsInParent().intersects(line3.getBoundsInParent()) 
          || ball.getBoundsInParent().intersects(line4.getBoundsInParent()) 
          || ball.getBoundsInParent().intersects(line7.getBoundsInParent()) 
          || ball.getBoundsInParent().intersects(line9.getBoundsInParent())) { 
         // changes direction 
         directionx = directionx * -1; 
        } 
        ball.setCenterX(ball.getCenterX() + directionx); 
        ball.setCenterY(newballY); 
        // if ball touches horizontal walls 
        if (ball.getBoundsInParent().intersects(line1.getBoundsInParent()) 
          || ball.getBoundsInParent().intersects(line2.getBoundsInParent()) 
          || ball.getBoundsInParent().intersects(line6.getBoundsInParent()) 
          || ball.getBoundsInParent().intersects(line8.getBoundsInParent())) { 
         directiony = directiony * -1; 
        } 
        // if ball touches hole, then game is over 
        if (ball.getBoundsInParent().intersects(hole.getBoundsInParent())) { 
         System.out.println("Game over"); 
         pane.getChildren().removeAll(ball); 
        } 




      } 

     }.start(); 

     // I get the slider value and making array where are 10 different strengts 
     scene.setOnKeyPressed(event -> { 
      double b = Math.round(slider.getValue()); 
      b--; 
      int c = (int) b; 
      double [] strengts = new double[10]; 
      double k = 0.1; 
      for (int i = 0; i < strengts.length; i++) { 
       strengts[i] = k; 
       k = k + 0.5; 
      } 
      // 8 different directions to move the ball 
      if (event.getCode().equals(KeyCode.H)) { 
       directionx = directionx + strengts[c]; 
      } 
      else if(event.getCode().equals(KeyCode.F)) { 
       directionx = directionx - strengts[c]; 
      } 
      else if(event.getCode().equals(KeyCode.V)) { 
       directiony=directiony + strengts[c]; 
      } 
      else if(event.getCode().equals(KeyCode.T)) { 
       directiony= directiony - strengts[c]; 
      } 
      else if(event.getCode().equals(KeyCode.B)) 
      { 
       directionx = directionx + strengts[c]; 
       directiony = directiony + strengts[c]; 
      } 
      else if(event.getCode().equals(KeyCode.Y)) 
      { 
       directionx = directionx + strengts[c]; 
       directiony = directiony - strengts[c]; 
      } 
      else if(event.getCode().equals(KeyCode.R)) 
      { 
       directionx = directionx - strengts[c]; 
       directiony = directiony - strengts[c]; 
      } 
      else if(event.getCode().equals(KeyCode.C)) 
      { 
       directionx = directionx - strengts[c]; 
       directiony = directiony + strengts[c]; 
      } 
     }); 
     primaryStage.show(); 
    } 


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

попробуйте подождать (200), чтобы замедлить движение мяча –

ответ

0

Просто используйте физику для трения. Предположим, что для каждого кадра скорость (v) остается постоянной.

Энергия шара (масса m):

E = 0.5 * m * v² 

Работа для трения в зависимости от расстояния (s) путешествовала и трение постоянной μ

ΔE = s * m * μ = Δt * v * m * μ 

Новая энергия E - ΔE который вы можете использовать с первой формулой для расчета новой скорости v':

0.5 * m * v'² = 0.5 * m * v² - s * m * μ 
      v'² = v² - s * μ * 2 
      v' = sqrt(v² - s * μ * 2) 

Вышеупомянутое предполагает, что земля плоская.

Это позволяет уменьшить скорость, как это:

@Override 
public void start(Stage primaryStage) { 
    Point2D direction = new Point2D(1, 1).normalize(); 
    Circle c = new Circle(10, 10, 10); 

    Timeline tl = new Timeline(); 
    tl.getKeyFrames().setAll(new KeyFrame(Duration.seconds(1/60d), new EventHandler() { 

     double speed = 3; 
     double friction = 0.02; 

     @Override 
     public void handle(Event event) { 
      double distance = speed; 

      Point2D movement = direction.multiply(distance); 
      c.setCenterX(c.getCenterX() + movement.getX()); 
      c.setCenterY(c.getCenterY() + movement.getY()); 

      double energyBefore = speed * speed; 
      double energyLost = distance * friction; 

      if (energyLost > energyBefore) { 
       tl.stop(); 
       speed = 0; 
       System.out.println("stopped"); 
      } else { 
       speed = Math.sqrt(energyBefore - energyLost); 
      } 

     } 
    })); 

    tl.setCycleCount(Animation.INDEFINITE); 

    Pane root = new Pane(); 
    root.getChildren().add(c); 

    Scene scene = new Scene(root, 400, 400); 
    scene.setOnMouseClicked(evt -> tl.play()); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
0

Спасибо за ответ, но как новичок я теперь нашел сам простым решением.

Я просто добавить 4, если-заявления следующим образом:

if (directionx>0) { 
       directionx = directionx - 0.01; 
      } 
if(directionx<0){ 
       directionx = directionx + 0.01; 
      } 
if(directiony>0) { 
       directiony = directiony - 0.01; 
      } 
if(directiony<0) { 
       directiony = directiony + 0.01; 
      } 

Возможно, в реальной физически его как-то неправильно, но это выглядит вполне реально для меня.