2016-03-29 103 views
2

所以我有一個程序使用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?我應該添加另一個參數還是另一個速度方法?

+2

您可以通過速度的因素相乘'dx'和'dy'。 – Oisin

回答

2

我想推薦另一種方法:使用AnimationTimer,Vector 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); 

    } 
}; 

你可以找到一個完整的例子o在這gist。球根據重力在地板上彈跳。風從左向右吹,所以球在那裏移動。但是你可以在設置屬性中輕鬆改變它。

別擔心,代碼不多,只是一般用途的矢量計算類很長。但是你只需要知道一些方法。

該示例使用了力風和重力。無論你想達到什麼目的,只要運用它的力量。當然對於你的問題,你可以簡單地增加速度而不用施加力量。這一切都取決於你想玩什麼。

截圖:

enter image description here

示例你如何會改變,因爲摩擦球的彈跳是chapter 2.7。下面是丹尼爾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類實現來避免。

0

我會做它物理中心:當你這樣做的動態時,你應該得到你的速度和座標加速度。

每個程序滴答計算新的加速度(使用質量的球,重力常數,各種係數,如彈性係數或與空氣的摩擦係數),所有這些都是向量。

然後,您將基本上整合這些向量:加速度 - >速度 - >座標。

完成這一步之後,您只需要調整加速度,僅調整該矢量,使球移動得更快/更慢,反彈更高或更低等等。

你可能要檢查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; 
}