Как отделить физику от частоты кадров? (Движок физики 2D сверху вниз на Java)
Я делаю очень простой 2D физический движок сверху вниз для развлечения, но я не знаю, как отвязать физику от частоты кадров. У меня есть рабочий временной интервал, но я не знаю, как его реализовать в физических расчетах.
Я создал это на основе моих школьных знаний о динамике, поэтому я могу добавить силу к объекту, и объект будет реагировать соответствующим образом. На объект также действует трение, поэтому он замедляется. Но когда дело доходит до реализации моего временного шага, я не знаю, что делать.
Вот мой класс PhysicsObject:
import java.util.*;
public class PhysicsObject {
// Position, Velocity, Acceleration
Vector2 p = new Vector2();
Vector2 v = new Vector2();
Vector2 a = new Vector2();
// Force stuff
Vector2 fNet = new Vector2();
Vector2 fFriction = new Vector2();
ArrayList<Force> forceList = new ArrayList<Force>();
// Wall Collisions
boolean collisionX = false;
boolean collisionY = false;
// Friction stuff
double mu = 0.15;
static final double G = 9.8;
// Personal stats
int size;
double m;
public PhysicsObject(Vector2 startingPos, int size, double mass) {
this.size = size;
p = startingPos;
m = mass;
}
// Calculates the position of the object this frame
public void calcPos() {
// Calculates net force
addForces();
addFriction();
// Calculates acceleration
a.x = fNet.x / m;
a.y = fNet.y / m;
// Calculates the velocity and position
v = VMath.addVectors(a, v);
p = VMath.addVectors(v, p);
// Resets the net force
fNet.x = 0;
fNet.y = 0;
}
// Adds a force to the force list
public void addForce(Vector2 force, double t) {
// Adds the force to the list of active forces
Force forceToAdd = new Force(force, t);
forceList.add(forceToAdd);
}
// Adds the list of active forces to a net force
private void addForces() {
for(int i = 0; i < forceList.size(); i++) {
// Adds the force vector to the net force
fNet = VMath.addVectors(fNet, VMath.polarToCart(forceList.get(i).vector));
// Subtracts the frame's time from the force's timer
forceList.get(i).time = forceList.get(i).time - Time.deltaTime();
if(forceList.get(i).time <= 0) { // If the timer runs out, remove force
forceList.remove(i);
}
}
}
// Adds friction to the net force
private void addFriction() {
// Calculates friction magnitude and direction
fFriction.x = m * G * mu;
fFriction.y = VMath.cartToPolar(v).y - Math.PI;
// Accounts for the friction changing direction of motion
if(fFriction.x/m > VMath.cartToPolar(v).x) {
v.x = 0;
v.y = 0;
}
// Adds friction to the net force
else if(VMath.cartToPolar(v).x > 0) {
fNet = VMath.addVectors(fNet, VMath.polarToCart(fFriction));
}
}
}
Класс Vector2 - это просто класс с двумя двойниками, один для x и один для y, а класс Force просто содержит один Vector2 и один двойной для времени, в течение которого он активен.
Я попытался просто умножить ускорение и скорость на временной шаг, как я это делал в других проектах, но это не сработало, и я не понимаю, почему, разве временной шаг не должен быть нужен только тогда, когда расчет требует времени? (например, скорость, ускорение) И если да, то почему это не работает, когда я просто умножаю скорость и ускорение на временной шаг?
Я также понимаю, что мой код может быть очень беспорядочным или неэффективным, поэтому я с радостью приму критику за все, что я сделал неправильно.