Как мне отделить физику от частоты кадров? (Сверху вниз физический движок 2D в Java) - PullRequest
0 голосов
/ 08 апреля 2020

Я делаю очень простой двухмерный физический движок для развлечения, но я не знаю, как извлечь ie физику из частоты кадров. У меня есть временный шаг, который работает, но я не знаю, как реализовать его в расчетах по физике.

Я создал его на основе своих знаний в школе о динамике в старших классах, так что я могу добавить силу к объекту и объект будет реагировать соответственно. На объект также действует трение, поэтому оно будет замедляться. Но когда дело доходит до реализации моего временного шага, я не знаю, что делать.

Вот мой класс 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 и двойной для количества времени, в течение которого он активен.

Я попытался просто умножить ускорение и скорость на временной шаг, как я сделал в других проектах, но это не сработало, и я не понимаю, почему разве не нужен временной шаг только тогда, когда расчет требует времени? (например, скорость, ускорение) И если так, почему это не работает, когда я просто умножаю скорость и ускорение на временной шаг?

Я также понимаю, что мой код может быть очень грязным или неэффективным, поэтому я с удовольствием принять критику за все, что я сделал неправильно.

...