Точный выбор времени важен для любого приложения высокой производительности или игры. Обычно таймер нужен с точностью как минимум 1 миллисекунды.
в Java System.currentTimeMillis() имеет точность где-нибудь между 1 к 55 миллисекундам в зависимости от операционной системы. Это не будет хорошо работать для игр.
Code
/**
* получение времени в миллисекундах
*
* @возвращение системного времени в миллисекундах
*/
public long getTime() {
return System.nanoTime() / 1000000;
}
Sys.getTime() является LWJGL' высоким таймером резолюции и будет возвращать время'. Это значение может быть в любом формате (наносекунды, микросекунда, миллисекунды, и т.д)
Вычисление FPS
Для простоты мы будем использовать метод Display.setTitle(Заглавие строки), чтобы показать частоту кадров в заглавии окна.
Code
public void start() {
lastFPS = getTime(); //initialise lastFPS by setting to current Time
}
/**
* вычисление FPS в окне.
*/
public void updateFPS() {
if (getTime() - lastFPS > 1000) {
Display.setTitle("FPS: " + fps);
fps = 0;
lastFPS += 1000;
}
fps++;
}
в представленном ниже коде, вы будете управлять вращающимся квадратом и измерять FPS
Code
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
public class TimerExample {
/** позиция квадрата */
float x = 400, y = 300;
/** вращение квадрата */
float rotation = 0;
/** время в последней рамке */
long lastFrame;
/** рамки за секунду */
int fps;
/** последнее FPS время */
long lastFPS;
public void start() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
initGL();
getDelta(); //инициализация
lastFPS = getTime();
while (!Display.isCloseRequested()) {
int delta = getDelta();
update(delta);
renderGL();
Display.update();
Display.sync(60); // 60FPS-максимальный
}
Display.destroy();
}
public void update(int delta) {
// rotate quad
rotation += 0.15f * delta;
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) x -= 0.35f * delta;
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) x += 0.35f * delta;
if (Keyboard.isKeyDown(Keyboard.KEY_UP)) y -= 0.35f * delta;
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) y += 0.35f * delta;
// не дает квадрату выйти за пределы окна
if (x < 0) x = 0;
if (x > 800) x = 800;
if (y < 0) y = 0;
if (y > 600) y = 600;
updateFPS(); // обновление FPS таймера.
}
//вычисление сколько миллисекунд прошло
//вычисление рамки
public int getDelta() {
long time = getTime();
int delta = (int) (time - lastFrame);
lastFrame = time;
return delta;
}
//получение точного системного времени
public long getTime() {
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}
//вычисление FPS и установка сверху.
public void updateFPS() {
if (getTime() - lastFPS > 1000) {
Display.setTitle("FPS: " + fps);
fps = 0;
lastFPS += 1000;
}
fps++;
}
public void initGL() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 800, 0, 600, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
public void renderGL() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GL11.glColor3f(0.5f, 0.5f, 1.0f);
GL11.glPushMatrix();
GL11.glTranslatef(x, y, 0);
GL11.glRotatef(rotation, 0f, 0f, 1f);
GL11.glTranslatef(-x, -y, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2f(x - 50, y - 50);
GL11.glVertex2f(x + 50, y - 50);
GL11.glVertex2f(x + 50, y + 50);
GL11.glVertex2f(x - 50, y + 50);
GL11.glEnd();
GL11.glPopMatrix();
}
public static void main(String[] argv) {
TimerExample timerExample = new TimerExample();
timerExample.start();
}
}