简体   繁体   English

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

[英]How do I make bouncing ball move quicker? dynamic velocity?

So I had a program to move a bouncing ball across the screen using JavaFX now, Now I've tried reformatting certain values under Duration.millis() in my Timeline Animation and the lower I put it the faster the ball goes but, someone has told me that is not the best way to go instead I should ask about dynamic velocity to add to my program here's my code for movement of my ball:所以我现在有一个程序可以使用 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);
} }

In turn, it's going to be a pong game so I'm going to have 5 levels and in each level, I want the ball to move faster I can do this by lowering the Duration.millis() but I am told that is not the greatest way instead to add velocity how may I go about doing this without lowering my Duration.millis in my Time line animation parameters?反过来,这将是一场乒乓球比赛,所以我将有 5 个级别,在每个级别中,我希望球移动得更快我可以通过降低 Duration.millis() 来做到这一点,但我被告知这不是最好的方法是增加速度,我如何在不降低时间线动画参数中的 Duration.millis 的情况下进行此操作? Is there another parameter I should add or another method of velocity?我应该添加另一个参数或另一种速度方法吗?

I'd like to suggest another approach: Use an AnimationTimer , Vector calculation and Forces .我想建议另一种方法:使用AnimationTimerVector 计算Forces

The balls / sprites have attributes:球/精灵具有以下属性:

PVector location;
PVector velocity;
PVector acceleration;

The movement is done by applying forces to acceleration, acceleration to velocity and velocity to location:运动是通过将力施加到加速度、加速度施加到速度和速度施加到位置来完成的:

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

And this is done in a game loop for every sprite:这是在每个精灵的游戏循环中完成的:

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

    }
};

You can find a complete example on this gist .你可以在这个gist上找到一个完整的例子。 The balls bounce on the floor, depending on the gravity.球会根据重力在地板上弹跳。 Wind blows from left to right, so the balls move there.风从左吹到右,所以球在那里移动。 But you can easily change that in the settings attributes.但是您可以在设置属性中轻松更改它。

Don't worry, it's not much code, just the general purpose Vector calculation class is lengthy.不用担心,代码不多,只是通用的Vector计算类比较长。 But you only have to know a few methods of it.但是你只需要知道它的一些方法。

The example uses the forces wind and gravity.该示例使用了风力和重力。 Whatever you want to achieve, just apply the force of it.无论你想达到什么目的,只要运用它的力量。 Of course for your question you could simply increase the velocity without applying a force.当然,对于您的问题,您可以在不施加力的情况下简单地增加速度。 It all depends on what you want to toy around with.这一切都取决于你想玩什么。

Screenshot:截屏:

在此处输入图片说明

Example about how you could change the bouncing of the balls because of friction is in chapter 2.7 .关于如何改变球由于摩擦而弹跳的例子在第 2.7 章 Here's the processing code that Daniel Shiffman uses in his book, but you see it's very easy to translate to JavaFX:以下是 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();
  }

I leave the JavaFX implementation to you.我将 JavaFX 实现留给您。

You may also be interested in a video about how chapter 2.10 (everything attracts everything) looks like.您可能还对有关第 2.10 章(一切都吸引一切)的视频感兴趣。 It's really not much to code if you want to achieve something like this.如果你想实现这样的东西,编码真的不多。 That code is also available .代码也可用 It uses the Point2D class, if you are more comfortable with that.它使用 Point2D 类,如果您对此更满意的话。 However, you shouldn't use Point2D since there are limitations with it and you have to create new Point2D objects all the time which can be avoided by a custom Vector class implementation.但是,您不应该使用 Point2D,因为它存在局限性,并且您必须始终创建新的 Point2D 对象,而这可以通过自定义 Vector 类实现来避免。

I would do it physics centered : When you do dynamics like this you should get your velocity and coordinates out of your accelerations.我会以物理学为中心:当你做这样的动力学时,你应该从你的加速度中获得你的速度和坐标。

Each program tick calculates new acceleration (using the mass of the ball, the gravity constant, various coefficients such as the elasticity coefficient or friction with air one), all of these being vectors.每个程序滴答计算新的加速度(使用球的质量、重力常数、各种系数,例如弹性系数或与空气的摩擦系数),所有这些都是向量。

Then you would basically integrate these vectors : acceleration -> velocity -> coordinates.然后你基本上可以整合这些向量:加速度 -> 速度 -> 坐标。

After this being done, all you need is to tweak your acceleration, on only that vector, to make your ball move faster/slower, bounce higher or not, and such.完成此操作后,您只需调整加速度,仅在该向量上,使您的球移动得更快/更慢,弹得更高或不弹得更高,等等。

You might want to check Euler integration to do the job您可能需要检查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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM