How to make a game clock that handles fps and updates separately? - java

Currently I have an abstract GameClock class that implements runnable and calls an update method which handles both fps and updates with a defined nano second delay. This is the loop:
#Override
public void run() {
launch();
long nanoPrevious = System.nanoTime();
long nanoCurrent, nanoElapsed = 0;
while (running) {
nanoCurrent = System.nanoTime();
nanoElapsed += (nanoCurrent - nanoPrevious);
nanoPrevious = nanoCurrent;
while (nanoElapsed >= nanoSPU) {
update(); updates++;
nanoElapsed -= nanoSPU;
}
} finish();
}
I'd like to know if this method is lag efficient, and what I could improve, but most importantly how could it handle both fps and updates separately, and how the fps limit could be changed by the user within the game with minimal lag similar to minecraft where you can change your fps cap or set it to unlimited.

Related

Where to use multithreading in Java Game Dev (Swing)

I am developing a game using Java Swing and I've been wondering how can I implement multithreading into it. I thought I could move some parts of the game logic to new threads (like weather implementation/lighting effect or some complex in-game events that are running in the background independently of the main thread). I would like to hear possible suggestions and common practices on how to do it as well as possible elements of the game that are best to be implemented in individual threads.
Currently it uses a single thread. Here is the core of the game (game loop, where things are updated (game logic) and rendered) :
#Override
public void run() {
double drawInterval = 1000000000.0/FPS;
double delta = 0;
long lastTime = System.nanoTime();
long currentTime;
while(gameThread != null) {
currentTime = System.nanoTime();
delta += (currentTime - lastTime) / drawInterval;
lastTime = currentTime;
if(delta >= 1) {
// 1 UPDATE: update information such as character position
update();
// 2 DRAW: draw the screen with the updated information
repaint();
delta--;
}
}
}
public void startGameThread() {
gameThread = new Thread(this);
gameThread.start();
}
(And then it is called in the main method...)

How do i make my game not speed up/slow down depending on the fps in java?

So when I'm running a game I'm working on, the FPS will go up and down. But then so will the in game time. more fps, faster movement. less fps, slower movement. I'm using the javax.swing.Timer class with a 10ms delay and a personalized ActionListener class. Does anyone know how to get rid of these time conundrums? Something like Unity's Time.deltaTime would be perfect, as that's what I'm used to.
Record the time in your ActionListener class:
class MyActionListener implements ActionListener {
private long previousStartTime = -1;
#Override
public void actionPerformed(ActionEvent e) {
long now = System.currentTimeMillis();
long elapsedTime = previousStartTime != -1 ? now - previousStartTime : 0;
previousStartTime = now;
// use elapsedTime
// e.g.
double pixelsToMove = speedPerMs * elapsedTime;
}
}
On the first iteration the elapsedTime will be zero.

What is the proper way to implement multi threading while using a gameLoop

I'm working on a game where I move a car image based on keyboard input. Currently I'm using this game loop:
private void runGameLoop() {
window.setVisible();
isRunning = true;
final double FRAMES_PER_SECOND = 60;
double timePerUpdate = 1000000000 / FRAMES_PER_SECOND;
double timeFromLastUpdate = 0;
long now;
long last = System.nanoTime();
while (isRunning) {
now = System.nanoTime();
timeFromLastUpdate += (now - last) / timePerUpdate;
last = now;
if(timeFromLastUpdate >= 1) {
tick();
render();
timeFromLastUpdate--;
}
}
}
The tick method updates the car image location, and the render method will render the image(with the new location) on screen.
I want to have the calculations for the new image location on a separate thread, because at the moment the calculations are taking to long and causing a rendering lag. Is there a way to use multi threading while still implementing a game loop?
Thanks in advance.
Perhpas you can do something similar to what Android does. In Android there is the mainthread which would be like your game loop. It has a Handler for runnables that are posted from background/concurrent threads to the mainthread.
So at every loop cycle the mainthread executes any runnables posted feom background threads.
Note, that the calculations should not be done in the runnables (which are executed in mainthread), only passing the results/updating stuff should be done in the runnables.

How to add time events in libgdx

I wanted to know how can I add time to my events in libgdx. I have a button and when you press it a sprite will appear. I want the sprite to appear for only a short period of time. How can I do this? I used Scene2D to make the sprites as an actor.
I will show you an example in pseudo code.
wait time = 5 second;
current time = get time;
if (current time > wait time) {
// do the following
}
There's two ways to do this. You can either use something similar to your your pseudo code or you can use a timer.
Manual calculation:
private Long lifeTime;
private Long delay = 2000L; //1000 milliseconds per second, so 2 seconds.
public void create () {
lifeTime = System.currentTimeMillis();
}
public void render () {
lifeTime += Gdx.graphics.getDeltaTime();
if (lifetime > delay) {
//Do something
}
}
Using a timer:
private float delay = 2; //In seconds this time
//At some point you set the timer
Timer.schedule(new Task(){
#Override
public void run() {
// Do something
}
}, delay);
Read more here: https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/Timer.html

Slow down the call to a specific function

I have a game loop here, that calls the tick method. Inside the tick method, other tick methods are called. How would I slow down the call to input.tick() without slowing down the whole program? Putting a Thread.sleep(); anywhere in the tick methods slows down the whole program and that is not what I want.
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 ticks = 0;
while(running){
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1){
tick();
ticks++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000){
timer += 1000;
System.out.println(ticks + " tps, " + frames + " fps");
ticks = 0;
frames = 0;
}
}
stop();
}
public void tick(){
input.tick(); // How do I slow down the call to this?
if(gameState){
player.tick();
player.move();
collision();
treeline.move();
obstacleHole.move();
obstacleWolf.move();
coin.move();
coin.tick();
}
}
It seems you are doing a GUI application and the code you are showing runs on the Event Dispatch Thread. The sleeps make the EDT freeze and be unable to update the GUI. What you must do instead is use the javax.swing.Timer class to postpone the execution of the code.
If you want to tick at regular intervals, then just reschedule the same task again in the handler submitted to Timer.
Use a Thread to call tick() in a deferred way, something like this:
private static final Timer TIMER = new Timer();
// ...
public void tick(){
TIMER.schedule(new TimerTask(){
void run() {
input.tick(); // Your tick method
}
}, 1000 /* delay in milliseconds */)
// ... rest of your method
}
If the input.tick() method collects the input of the player (e.g. key presses) it does no seem appropriate to delay it.
Perhaps you might be interested in implementing a Keyboard Input Polling mechanism. (see here for an example).
This is a usual technique in games so you do not respond to the input of the player in the usual way you would with other GUI applications. Instead you collect all the user input e.g. in a queue and then you poll that queue to read input at your own speed (e.g. 30 times per second).
I hope it helps

Categories

Resources