0

我正在使用 Java 和 LWJGL 开发物理/游戏引擎。到目前为止,我一直使用Display.Sync(int)恒定的帧速率和 1/int 的时间增量来进行物理更新。我正在尝试实现真正的时间增量,以便我可以充分利用处理能力。下面是我用来跟踪这个增量的类:

package techwiz24.jVox2D.Physics;

public class PhysicsUtils {
    private static long lastTime = System.nanoTime();

    public static double getTimeDelta(){
        return (System.nanoTime()-lastTime)/1000000000d;
    }

    public static void updateDelta(){
        lastTime = System.nanoTime();
    }
}

在每个滴答声中,引擎循环通过物理实体并应用标准重力等,更新速度和加速度分量。然后应该使用时间增量应用运动。在循环结束时,updateDelta()被调用。问题在于,这以某种方式使一切进展得更快。例如,这是我的运动模块:

package techwiz24.jVox2D.Physics;

/**
 * Moves an object in relation to it's velocity, acceleration, and time components
 * using the Kinematic equations.
 * @author techwiz24
 *
 */
public class PStandardMotion extends PhysicsEffect {

    @Override
    public String getName() {
        return "Standard Motion Effect";
    }

    @Override
    public String getVersion() {
        return "1";
    }

    /**
     * Using two Kinematic Equations, we can update velocity and location 
     * to simulate an earth-like gravity effect. This is called every tick,
     * and uses the TimeDelta stored in the physics object (Time since last update)
     * as the Time component. TODO: Figure out actual time deltas...
     * 
     * Note: This ignores wind resistance
     * 
     * Using: V_FINAL=V_INITIAL+at
     *        X=V_INITIAL*t + .5 * a * t^2
     * 
     * @param o The physics object to apply this to.
     */
    public void applyTo(PhysicsObject o) {

        double vf = o.getVelocityComponent()[1] + (o.getAccelerationComponent()[1]*o.timeDelta());
        double dy = o.getVelocityComponent()[1] + (0.5d * o.getAccelerationComponent()[1] * Math.pow(o.timeDelta(), 2));
        double dx = o.getVelocityComponent()[0] + (0.5d * o.getAccelerationComponent()[0] * Math.pow(o.timeDelta(), 2));

        o.updateVelocity(o.getVelocityComponent()[0], vf);
        o.updateLocation(o.getLocationComponent()[0]+dx, o.getLocationComponent()[1]+dy);

    }

}

timeDelta()只返回当前时间增量。

public double timeDelta(){
        return PhysicsUtils.getTimeDelta();
}

我是否以错误的方式处理这件事?

4

1 回答 1

-1
This is generally how I do my FPS counter.

public class Game {
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
public static final String TITLE = "Physics Tech Demo";

private long lastFrame;
private long lastFPS;
private int fps;

public void init() {
    try {
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.setTitle(TITLE);
        Display.create();
    } catch (LWJGLException e) {
        e.printStackTrace();
        Display.destroy();
    }

    initGL();
    getDelta();
    lastFPS = getTime();

    while (!Display.isCloseRequested()) {
        int delta = getDelta();
        tick(delta);
        renderGL();
        Display.update();
        Display.sync(60);
    }
    Display.destroy();
}

public int getDelta() {
    long time = getTime();
    int delta = (int) (time - lastFrame);
    lastFrame = time;

    return delta;
}

public long getTime() {
    return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}

public void updateFPS() {
    if (getTime() - lastFPS > 1000) {
        System.out.println("FPS: " + fps);
        fps = 0;
        lastFPS += 1000;
    }
    fps++;
}

public void initGL() {
}

public void tick(int delta) {
    updateFPS();
}

public void renderGL() {
}

public static void main(String[] args) {
    Game game = new Game();
    game.init();
}

}

于 2013-06-02T16:00:49.730 回答