如何使弹跳球更快移动? 动态速度?

所以我现在有一个程序可以使用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  getWidth() - radius) { dx *= -1; //change Ball direction } if (y  getHeight() - radius) { dy *= -1; //change Ball direction } x += dx; y += dy; circle.setCenterX(x); circle.setCenterY(y); } } 

反过来,它将是一个乒乓球游戏,所以我将有5个级别,在每个级别,我希望球移动得更快我可以通过降低Duration.millis()来做到这一点,但我被告知不是相反,添加速度的最好方法是如何在不降低我的时间线动画参数中的Duration.millis的情况下进行此操作? 我应该添加另一个参数还是另一种速度方法?

我想建议另一种方法:使用AnimationTimer , Vector计算和Forces 。

球/精灵有属性:

 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); } }; 

你可以在这个要点上找到一个完整的例子。 根据重力,球在地板上反弹。 风从左向右吹,所以球在那里移动。 但您可以在设置属性中轻松更改它。

别担心,它的代码不多,只是通用的Vector计算类很冗长。 但你只需要了解它的一些方法。

该示例使用力风和重力。 无论你想要实现什么,只要施加它的力量。 当然,对于您的问题,您可以在不施加力的情况下简单地增加速度。 这一切都取决于你想玩的东西。

截图:

在此处输入图像描述

关于如何通过摩擦来改变球的弹跳的示例在第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实现留给您。

您可能还对有关第2.10章 (一切都吸引所有内容) 的video感兴趣。 如果你想要实现这样的东西,那么编码真的不多。 该代码也可用 。 它使用Point2D类,如果你更熟悉它。 但是,您不应该使用Point2D,因为它有一些限制,您必须始终创建新的Point2D对象,这可以通过自定义Vector类实现来避免。

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

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

然后你基本上将这些向量集成:acceleration – > velocity – > coordinates。

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

您可能想要检查Euler集成以完成工作

 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; }