【问题标题】:How do I make bouncing ball move quicker? dynamic velocity?如何让弹跳球移动得更快?动态速度?
【发布时间】:2016-03-29 23:34:55
【问题描述】:

所以我现在有一个程序可以使用 JavaFX 在屏幕上移动一个弹跳球,现在我尝试在我的时间轴动画中重新格式化 Duration.millis() 下的某些值,我把它放得越低,球跑得越快但是,有人告诉我这不是最好的方法,我应该询问动态速度以添加到我的程序中这是我的球运动代码:

    public class BallPane extends Pane {

public final double radius = 5;
public double x = radius, y = radius;
public double dx = 1, dy = 1;
public Circle circle = new Circle(x, y, radius);
public Timeline animation;

public BallPane(){    
circle.setFill(Color.BLACK); // Set ball color
getChildren().add(circle); // Place ball into Pane

// Create animation for moving the Ball
animation = new Timeline(
    new KeyFrame(Duration.millis(10), e -> moveBall() ));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
} 

public void moveBall() {
// Check Boundaries
if (x < radius || x > getWidth() - radius) {
    dx *= -1; //change Ball direction
}
if (y < radius || y > getHeight() - radius) {
    dy *= -1; //change Ball direction
}
x += dx;
y += dy;
circle.setCenterX(x);
circle.setCenterY(y);
} }

反过来,这将是一场乒乓球比赛,所以我将有 5 个级别,在每个级别中,我希望球移动得更快我可以通过降低 Duration.millis() 来做到这一点,但有人告诉我这不是增加速度的最佳方法,我该如何在不降低时间线动画参数中的 Duration.millis 的情况下执行此操作?我应该添加其他参数或其他速度方法吗?

【问题讨论】:

  • 您可以将dxdy 乘以速度系数。

标签: java animation javafx game-physics velocity


【解决方案1】:

我想建议另一种方法:使用AnimationTimerVector calculationForces

球/精灵有属性:

PVector location;
PVector velocity;
PVector acceleration;

运动是通过向加速度施加力、向速度施加加速度和向位置施加速度来完成的:

public void applyForce(PVector force) {

    // Making a copy of the PVector before using it!
    PVector f = PVector.div(force, mass);
    acceleration.add(f);
}

public void move() {

    // set velocity depending on acceleration
    velocity.add(acceleration);

    // limit velocity to max speed
    velocity.limit(maxSpeed);

    // change location depending on velocity
    location.add(velocity);

    // clear acceleration
    acceleration.mult(0);
}

这是在每个精灵的游戏循环中完成的:

gameLoop = new AnimationTimer() {

    @Override
    public void handle(long now) {

        // physics: apply forces
        allSprites.forEach(s -> s.applyForce(Settings.FORCE_GRAVITY));
        allSprites.forEach(s -> s.applyForce(Settings.FORCE_WIND));

        // move
        allSprites.forEach(Sprite::move);

        // check boundaries
        allSprites.forEach(Sprite::checkBounds);

        // update in fx scene
        allSprites.forEach(Sprite::display);

    }
};

您可以在 gist 上找到完整的示例。球在地板上弹跳,取决于重力。风从左到右吹,所以球在那里移动。但是您可以在设置属性中轻松更改它。

别着急,代码不多,只是通用的Vector计算类比较长。但你只需要知道它的几个方法。

该示例使用风和重力。无论你想达到什么,只要施加它的力量。当然,对于您的问题,您可以简单地增加速度而不施加力。这完全取决于你想玩什么。

截图:

chapter 2.7 中提供了有关如何改变球因摩擦而弹跳的示例。这是 Daniel Shiffman 在他的书中使用的处理代码,但您会发现它很容易转换为 JavaFX:

for (int i = 0; i < movers.length; i++) {

    float c = 0.01;
    PVector friction = movers[i].velocity.get();
    friction.mult(-1);
    friction.normalize();
    friction.mult(c);

    movers[i].applyForce(friction);
    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);

    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }

JavaFX 实现留给你。

您可能还对a video about how chapter 2.10(一切吸引一切)的样子感兴趣。如果你想实现这样的目标,编写代码真的不多。那code is also available。如果您对此更满意,它使用 Point2D 类。但是,您不应该使用 Point2D,因为它有一些限制,并且您必须始终创建新的 Point2D 对象,这可以通过自定义 Vector 类实现来避免。

【讨论】:

    【解决方案2】:

    我会以物理为中心:当你做这样的动力学时,你应该从你的加速度中得到你的速度和坐标。

    每个程序滴答计算新的加速度(使用球的质量、重力常数、各种系数,如弹性系数或与空气的摩擦系数),所有这些都是向量。

    然后你基本上会整合这些向量:加速度 -> 速度 -> 坐标。

    完成此操作后,您只需要在该向量上调整加速度,以使您的球移动得更快/更慢,反弹或不反弹等等。

    您可能需要检查Euler integration 来完成这项工作

    Vector position, velocity, acceleration;
    
    public void eulerIntegration(double dt){
        //TODO create the calculate acceleration method using your ball model
        acceleration = calculateAcceleration();
        velocity = acceleration * dt;
        position = velocity * dt;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-24
      • 1970-01-01
      • 2013-05-05
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多