I am making a game which runs according to physical laws: namely F = ma. Objects in the game, change their velocities and positions according to the force experienced by them.
I am using the AnimationTimer class.
The game is 2-dimensional.
I have a class Ball:
public class Ball extends javafx.scene.shape.Circle {
int m; //mass
int vX, vY; // velocity componenets
void feelForce (int forceX, int forceY) {
vX += forceX * t/m;
vY += forceY * t/m;
setCenterX (getCenterX() + vX * t);
setCenterY (getCenterY() + vY * t);
}
}
The problem I face is that I don't know how to define t. The number of frames per second might vary throughout runtime, and I want to know how to find that value, each time feelforce()
is called.
public void start(Stage stage) throws Exception {
//have overridden the constructor in class Ball. Had not shown it to keep it short
Ball player = new Ball(400.0, 300.0, 30.0, Color.TOMATO);
Pane main = new Pane(player);
Scene scene = new Scene(main);
stage.setScene(scene);
stage.show();
AnimationTimer gamePlay = new AnimationTimer() {
public void handle(long now){
player.feelForce(Math.random() * 10, Math.random() * 10);
// I use MouseEvents to get force values, but have used random numbers here, for brevity
}
};
gamePlay.start();
}
If this is no possible/efficient using AnimationTimer, a solution using another class would also be appreciated.
P.S: The reason I am using AnimationTimer instead of Timeline, is that a fixed rate is not necessary.
The value passed to the handle(...)
method is a timestamp, in nanoseconds. So you can calculate the amount of time that has elapsed since the last time handle(...)
was invoked:
AnimationTimer gamePlay = new AnimationTimer() {
private long lastUpdate = -1 ;
public void handle(long now){
if (lastUpdate == -1) {
lastUpdate = now ;
return ;
}
double elapsedSeconds = (now - lastUpdate) / 1_000_000_000.0 ;
lastUpdate = now ;
player.feelForce(Math.random() * 10, Math.random() * 10, elapsedSeconds);
// I use MouseEvents to get force values, but have used random numbers here, for brevity
}
};
and then just update the feelForce(...)
method accordingly:
public class Ball extends javafx.scene.shape.Circle {
int m; //mass
int vX, vY; // velocity componenets
void feelForce (int forceX, int forceY, double t) {
vX += forceX * t/m;
vY += forceY * t/m;
setCenterX (getCenterX() + vX * t);
setCenterY (getCenterY() + vY * t);
}
}