ns is 1000000000 / amountOfTicks;
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta >= 1) {
tick(glad);
updates++;
delta--;
fps_counter = 0;
}
if (delta >= fps_counter / FramesPerTick) { // render
fps_counter++;
frames++;
render(glad);
}
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
frame.setTitle("Ticks: " + updates + " Fps: " + frames);
updates = 0;
frames = 0;
}
So if i have 20 ticks and 3 FramesPerTick i get 60fps
it checks whenever delta is bigger than 1/3, 2/3 and 3/3, so every tick has 3 frames
Everything is jittery, movement, mouse look.
Animation gets more and more jittery the lower the FPS, i dont understand why.
Also when i take the render(glad) method out of the if, it goes up to 400 fps and runs very smoothly.
Related
I built a small game in java in which i use a game loop. I add gameobjects which i render using render() and tick() methods. However, now the program gets bigger i encounterted a problem.
How do you solve that when i use velocity to move a picture, the object keeps rendering on old positions? For small programs this aint a problem, but when you get like 100 objects in the screen the FPS keeps dropping to the point the program doesnt work properly anymore. This is just because there are so many objects to render. Is there a way to remove the rendering of the old positions of the object? Here below is some code i have written.
The game loop i used:
public void run() {
this.requestFocus();
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
tick();
delta--;
}
if (running) {
try {
render();
} catch (IOException e) {
e.printStackTrace();
} catch (FontFormatException e) {
e.printStackTrace();
}
}
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}
I used the Graphics class in Java to draw the images/strings/rectangles/etc. on the JFrame.
Here below is a picture of the problem. You can see that the object began all the way to the right. I changed the x-axis every tick of the game loop which made the object go to the left. Unfortunately, the object leaves a trace behind it and keeps rendering that, while i want it to only render the newest position.
Object rendering problem picture:
How can i solve this? Thanks in advance.
I'm trying to make a simple game engine and I'm trying to make delta time available to the user. This is how it is calculated and given to the user (they get it as a float):
float deltaTime;
long lastLoop = System.nanoTime();
UpdateInfo updateInfo = new UpdateInfo(0, 0, gameInstance.window.getWindowHandle());
while (!glfwWindowShouldClose(gameInstance.window.getWindowHandle()))
{
deltaTime = (float)((System.nanoTime() - lastLoop) / 1000000f);
updateInfo.setDeltaTime(deltaTime);
if (gameInstance.window.isFPSCounterEnabled())
{
if (System.currentTimeMillis() - lastFrameCount >= 1000)
{
fps = frames;
frames = 0;
lastFrameCount = System.currentTimeMillis();
}
}
else
{
fps = -1;
}
updateInfo.setFPS(fps);
gameInstance.updateGame(updateInfo);
gameInstance.drawGame(gameInstance.window.getDrawboard());
lastLoop = System.nanoTime();
glfwPollEvents();
}
But when I test the delta time value in moving a sprite across the screen, it's really choppy. This is both when VSync is enabled and disabled. Am I calculating it wrong or is my game being unstable?
I must be making some silly mistake in my code, In my head this should work but the timer works a bit too fast ( I want to get time left in seconds).
My code:
timeElapsed = 0;
timeLeft = 60;
//delta = time it took to get through one frame (60 fps).
timeElapsed += delta/getFramesPerSecond(); //FPS = 60f
timeLeft -= timeElapsed; //timeLeft starts at 60 (seconds)
timeDisplay = "Time left: " + timeLeft;
I have checked that FPS is always 60, what am I missing here?
Delta sample prints:
0.016969847
0.017038532
0.017123796
0.017026689
0.016969848
0.017059453
0.01697774
0.016987609
0.017073665
0.017035767
0.01708432
timeElapsed+timeLeft should be a constant (thus both should change by the same amount in opposite directions), however, you are repeatedly reducing timeLeft by timeElapsed
In a demonstrative example with steps 1 in timeElapsed, your code gives
timeElapsed timeLeft
0 60
1 59
2 57
3 54
4 50
5 45
6 39
7 32
Change the code to
timeDelta = delta/getFramesPerSecond();
timeElapsed += timeDelta;
timeLeft -= timeDelta;
timeDisplay = "Time left: " + timeLeft;
I have a draw method drawing a String to the screen using a Graphics2D object. I set up an if statement in the draw method to make the text draw every second (blinking effect), but the text will draw for a second, then not draw only one frame and continue drawing again. I would like for it to draw for a second, then not draw for a second and so on.
Here is the method -
long elapsed = (System.nanoTime() - blinkTimer) / 1000000;
if(elapsed < 1000){
// g.drawString("",x,y); Draw String Here
}else{
blinkTimer = System.nanoTime();
}
blinkTimer is initialized in the constructor as System.nanoTime();
I would like to accomplish this without using the Java Timer object. Thanks in advance!
Added an additional timer -
long elapsed = (System.nanoTime() - blinkTimer) / 1000000;
if(elapsed < 1000){
//g.drawString("",x,y); Draw String Here
breakTimer = System.nanoTime();
}
long breakElapsed = (System.nanoTime() - breakTimer) / 1000000;
if(breakElapsed > 500){
blinkTimer = System.nanoTime();
}
So I'm currently just learning how to do this, and someone said that the code is inefficient because the thread is still running when nothing is updating. When I look at the CPU usage in the task manager, it shoots up to 35 - 45% and 20 in the CPU column when only a black screen is being rendered. Is there a way to make the thread sleep when the CPU isn't updating anything?
Thanks!
public void run() {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1) {
update();
updates++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000) {
timer += 1000;
updates = 0;
frames = 0;
}
}
stop();
}
You shouldn't render on your own threads. SWING is thread unsafe so all GUI operations should happen on the SWING thread. It just happens SWING has a thread specially made for this.
timer = new javax.swing.Timer(1000 / 60, this);
timer.start();
#Override
public void actionPerformed(ActionEvent e) {
// Do your stuff (ignore 'e')
}
The only good way of doing it, is to execute the yourThread.wait() when the game stops doing stuff, and then yourThread.notify() when the game makes an action again.