I ran into a problem, where doing everything on a single thread may lead to some lags. The problem is, when I start to create loads of new objects (like 300 per second), my physics rate drops.
I sort all rendering objects each frame, so I would know which one to draw in which order, this might be the reason why it can handle only so little, but even if that was removed, there still would be like max operations per update, otherwise physics will lag.
Any ideas on how to achieve the correct zOrder, or remove possible physics lags?
Or detach physics from rendering ... ?
My game loop:
while (isRunning) {
currentFrameTime = System.nanoTime();
passedTime = currentFrameTime - lastFrameTime;
lastFrameTime = currentFrameTime;
physicsPassedTime += passedTime;
updatePassedTime += passedTime;
if (physicsPassedTime >= (double) 1_000_000_000 / physicsRate) {
physicsPassedTime = 0;
PhysicsUpdate();
}
if (updatePassedTime >= (double) 1_000_000_000 / refreshRate) {
updatePassedTime = 0;
Update();
Render();
LateUpdate();
}
}
Looks like the best solution (as suggested in comments) will be to run a second loop on a second thread with just physics update, and everything else on the other thread.
That way frame drops should not intervene with the physic updates.
Edit: Implemented this, and works like charm. I'll mark the answer when I'll be able to.
Related
I'm new to java and I'm trying to constantly add "zombie" entity to my game after a delay, and then shortening the delay as time goes on.
In my PlayState class I've got the code to spawn the entities in a position when my update(); method is run (which houses getInput(); and such. Not shown for clarity.)
public void update(long elapsed) {
this.entities.add(new Zombie(-535));
}
How would i make a delay that shortens? I'm guessing I would make the delay and then use a multiplier which i have getting smaller every 10 seconds or so, but how would I do this?
Now, I don't know much about the finer workings of your class, but this might give you a general idea of what I mean:
int counter = 50;
for(int i = 100; i >= 0; i--)
{
if(i == counter)
{
counter = counter / 2;
this.entities.add(new Zombie(-535));
}
}
Suppose i is the the total run-time of the game, and counter represents a percent of the game when you want to add a zombie.
If you want to add a zombie after 50% of the run-time (here, 100 seconds), then as the time reduces, you check if the time has come to add a zombie (Here, 50 seconds).
What I've done here is reduce the delay to half, and continue checking if the time has come to add a zombie.
Maybe you could call sleep on your thread of execution:
int sleepInMs = 5000
Thread.sleep(sleepInMs);
sleepInMs+=1000; //Then of course handle the case when sleepInMs == 0
Really need more information about your implementation.
For a simple delay, use "delay ms;"
Edit ms for the number of milliseconds you want. 1000 milliseconds is one second
The Problem I have ArrayList of "pellets". I'm pushing around 25 of them and they all bounce. However, for some reason they seem to go faster while render() is slower / takes more time (wut?) Please help me make it so that the 25 sprites smoothly glide about at a constant speed. It also jerks when only 5 sprites are onScreen.
Tried this stuff:
Reading around SO. They recommended getDeltaTime
Gdx.graphics.getDeltaTime() multiplying by pelletSpeed (no Change)
In the current code the pellets hop, jerk, and inconsistently sputter about almost unpredictably. I am assuming that it's going constant speed underneath the hood but honestly it's hard to tell
For Loop in Render:
String currentDir = pelletList.get(i).getDir();
String currentColor = pelletList.get(i).getColor6();
pelletSpeedElapsedTime = TimeUtils.nanoTime();
if(currentDir.equals("Up")) {
pelletList.get(i).y -= pelletSpeed * TimeUtils.timeSinceNanos(pelletSpeedElapsedTime);
if(pelletList.get(i).y < 0 ) {
pelletList.get(i).setDir("Down");
}
} else if (currentDir.equals("Down")) {
pelletList.get(i).y += pelletSpeed * TimeUtils.timeSinceNanos(pelletSpeedElapsedTime);
if(pelletList.get(i).y > screenHeight) {
pelletList.get(i).setDir("Up");
}
} else if (currentDir.equals("Left")) {
pelletList.get(i).x -= pelletSpeed * TimeUtils.timeSinceNanos(pelletSpeedElapsedTime);
if(pelletList.get(i).x < 0) {
pelletList.get(i).setDir("Right");
}
} else if (currentDir.equals("Right")) {
pelletList.get(i).x += pelletSpeed * TimeUtils.timeSinceNanos(pelletSpeedElapsedTime);
if(pelletList.get(i).x > screenWidth) {
pelletList.get(i).setDir("Left");
}
}
Thanks
The pelletSpeedElapsedTime = TimeUtils.nanoTime(); looks suspicious to me - you're getting this time, and then calculating elapsed time for bullets immediately afterward. Almost no time will have elapsed by then, and you won't be accounting at all for whatever time passes before the next call to whatever method this is.
I think (guessing at what the rest of your code is like) that you want to move that pelletSpeedElapsedTime assignment to the end of this method. The idea here is that you want to capture the time where you finished this update, so that the next time you update you know how much time has passed between updates (e.g. time spent rendering, sleeping, whatever.)
Doing this would mean that you'd have to handle the case where pelletSpeedElapsedTime hasn't been initialized, as well (maybe initialize it in the constructor? again, not sure of the broader context.) Also, I don't think all those TimeUtils.timeSinceNanos calls or necessary - I would call that once at the start of this section of code and use the value (to make sure the moving entities all get a consistent time delta, and to avoid the redundant call/calculation.)
Recently, I've been getting into Java Game programming. I have learned Java before, but this is my first time with Graphics, Game Loops etc.
I followed this tutorial for a Game Loop, and it's working pretty well.
There is nothing wrong with it, but I just can't figure out why I am thread.sleeping the code, and whats the point of it.
If anyone could explain what start, elapsed and running do, and why I am doing thread.sleep(wait) then I would be super appreciative!
GAME LOOP (Remember, it works, I just don't know why):
while (running) {
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if (wait < 0) {
wait = 5;
}
try {
Thread.sleep(wait);
} catch (Exception e) {
Game.logger.log("ERROR! Printing Stacktrace...");
e.printStackTrace();
}
}
}
Well, running is a flag that can be set to false to terminate the game.
start and elapsed are used to measure the time one round in the loop took. You are waiting to not make the game run too fast. If you are moving elements with a set speed, then having the game loop run too fast makes them also move too fast. That can lead to a bad user experience, since the user might not be fast enough to play the game.
Additionally, any animation doesn't run smooth anymore without the waiting. It will speed up and slow down depending on how fast your code executes.
Just continue with the tutorial, and when are at the point where you make something move, remove the waiting and see what happens.
EDIT
The code makes a round in the loop take about targetTime. It's unit is milliseconds. So to calculate the frame rate, just divide 1000 / targetTime.
start is the time before the game logic runs. elapsed is the amount of time that it takes for the game logic to run. running is a boolean (true/false) variable that determines whether the game should continue. Thread.sleep(wait) is a method that delays for a certain amount of time.
The goal is to keep the amount of time between frames roughly constant by delaying, so that the animations don't run faster or slower depending on how fast your computer processor is running.
It appears the code aims to be executed targetTime seconds. So you count how much time has already passed (elapsed), and then calculate how much to wait (divide it to get your remaining time in miliseconds, required for methon sleep(wait)).
One purpose of such waiting is often forcing some time between repainting to the screen.
To get your FPS, one way would be to slightly change your code:
long prevStart = 0; //just initialize. First FPS is of course wrong, next get fine.
double FPS = 0;
while (running) {
start = System.nanoTime();
FPS = 1 / double(start - prevStart);
prevStart = start;
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if (wait < 0) {
wait = 5;
}
try {
Thread.sleep(wait);
} catch (Exception e) {
Game.logger.log("ERROR! Printing Stacktrace...");
e.printStackTrace();
}
}
So, I am working on making a 2D game in Java, and I really don't have too much experience with Java. I currently use a very simple loop using a swing timer running every 10ms or so that looks something like:
public void actionPerformed(ActionEvent e) {
update();
repaint();
}
However, I need something more practical for obvious reasons. These reasons include the fact that more lag means less FPS AND slower movement/other updating.
I found the following code in a tutorial for a 3D Java game here. It would begin running when the program starts, and I understand enough to know it would work. However, I do not fully understand it: (tick() is the updater, render() renders the screen)
long currenttime;
long previoustime = System.nanoTime();
long passedtime;
int frames = 0;
double unprocessedseconds = 0;
double secondspertick = 1 / 60.0;
int tickcount = 0;
boolean ticked = false;
while (gameIsRunning) {
currenttime = System.nanoTime();
passedtime = currenttime - previoustime;
previoustime = currenttime;
unprocessedseconds += passedtime / 1000000000.0;
while (unprocessedseconds > secondspertick) {
tick();
unprocessedseconds -= secondspertick;
ticked = true;
tickcount++;
System.out.println(tickcount);
if (tickcount % 60 == 0) {
System.out.println(frames + " FPS");
previoustime += 1000;
frames = 0;
}
}
if (ticked) {
render();
frames++;
}
render();
frames++;
}
This code was not explained in the tutorial I found it in. Could someone please break this down and explain it?
I have also looked here for ideas, and the final piece of code on that page with a render thread and an update thread makes a lot of sense to me.
Which method should I use? One of the above, or something totally different? Also, you can probably tell that this is my first question here on stackoverflow.
Thanks in advance,
Josh
tick() is probably updating the game object's physical properties (position, velocity, etc.) tick() is called multiple times each update because some simulations can't handle too large a timestep without becoming unstable.
There's a popular article online which explains why this is the case, and why using a fixed timestep is the proper procedure. Check it out.
Each update the game is advanced in 1/60th second (so 60 frames a second) increments. This is repeated until there's less than 1/60th a second remaining in the aggregate. Aggregate is just a fancy word for sum.
Then a snapshot of the game's current state is rendered to the screen.
I won't get too deep into it, but really this code should be inerpolating each object's position by the remaining time in the aggregate during render().
long currenttime;
long previoustime = System.nanoTime();
long passedtime;
int frames = 0;
//this is an aggregate, games usually step in fixed units of time.
//this is usually because physics simulations can't handle too large of time steps.
double unprocessedseconds = 0;
double secondspertick = 1 / 60.0;
int tickcount = 0;
boolean ticked = false;
while (gameIsRunning) {
//get elapsed nano seconds from the epoch (january 1st, 1970)
currenttime = System.nanoTime();
//take difference of current time in nanos and previous time in nanos
passedtime = currenttime - previoustime;
previoustime = currenttime;
//divide to get the elapsed time in seconds.
unprocessedseconds += passedtime / 1000000000.0;
while (unprocessedseconds > secondspertick) {
tick();
unprocessedseconds -= secondspertick;
ticked = true;
tickcount++;
System.out.println(tickcount);
if (tickcount % 60 == 0) {
System.out.println(frames + " FPS");
previoustime += 1000;
frames = 0;
}
}
if (ticked) {
render();
frames++;
}
render();
frames++;
}
Good luck Josh.
Edit:
I have no experience with games using one thread for updates, and one for rendering. I can't give advice on those for that reason. If you have little or no experience with multithreading I'd avoid it as only complex games are likely to require this approach, and multithreading will add a multitude of issues you probably don't want to deal with.
Multithreaded game engines will consume more memory between rendering and updating than a single threaded game, or will wind up being depend on one another anyway. This is because the two threads can't manipulate the same data simultaneously. Therefor the only way for the two threads to operate is with synchronization on those data structures, or by the update thread suppling the render thread with immutable data to render.
Writing a multithreaded game engine would be a good introduction to threading. It could teach you quite a lot. Depends on what you want to get out of this.
If you are making a 2D game I feel even more confident that you will not need one thread for updating and one for rendering.
If you really want to pursue this, here's the approach I'd take.
You don't need more than a while loop to control rendering.
The way I do my engines is just as explained before, I multi-thread. Basically, if you split the job of processing and drawing the game into two segments it becomes quicker at the expense of more resources in use. I do a little something like this:
public class Engine implements Runnable {
//Sets classes
Engine tick = new Engine(true);
Engine render = new Engine(false);
Thread tickThread = new Thread(tick);
Thread renderThread = new Thread(render);
boolean job;
boolean isRunning = false;
long sleepTime = 5L;
public Engine(boolean job) {
//Sets what the thread does
this.job = job;
}
public static void startEngine() {
//Starts Engine
isRunning = true;
tickThread.start();
renderThread.start();
}
public void tick() {
//Process things
}
public void render() {
//Draw things
}
public void run() {
//Do engine base things
while(isRunning) {
if(job) {
tick();
} else {
render();
}
Thread.sleep(sleepTime);
}
}
}
This is by no means advanced. This is just an example of what a simple multi-thread game engine would be like. Honestly, I used this exact code when I was starting off making games. This could be used but some adjustments should be made depending on what you use it for. What I mean is that lets say you have an object that's moving and its being rendered at the same time. If the objects position is 50 and increasing and the render method is drawing it then the object could go to 51 then 52 before being rendered again. Normally, the processing is faster than the drawing. Another example: Lets say you have an ArrayList and are constantly removing and adding objects to it. Sometimes you can remove an object just as the render method is about to draw it and cause a null pointer exception because it's trying to draw something that doesn't exist. (I used "if(object.get(i) != null)" and worked around it that way)
I hope this helped at least a little (two years later, lol) and helped you get a basis of what multi-threading is like (if you didn't already).
I'm making a basic 2D game, yet I'm having problems with lag. The character on the game moves fine, yet sometimes slows right down, mainly when near an enemy. The enemy is not causing the lag though, as I've had 50 of them on the screen at once and it runs fine.
I've done the timing almost identically to how it's done in the Killer Game Programming in Java book, yet it doesn't seem to work too well. The FPS also seems to change a lot, which it shouldn't, because it should always take 15ms to complete an update-render-paint-sleep cycle, can anyone explain this?
Also, I think it lags more when my computer is doing things in the background (antivirus scanning, etc.), although I can run the game at about 550FPS while it's running other programs, so I don't think it's my computer.
Here's how I do the timing:
int waitTime = 1000 / 65; //65 being the desired FPS
while(running){
if(!loading){
gameUpdate();
gameRender();
gamePaint();
afterTime = System.nanoTime();
timeDiff = afterTime - beforeTime;
sleepTime = waitTime - (timeDiff / 1000000L);
if(sleepTime > 0){
try{
mainThread.sleep(sleepTime);
} catch(InterruptedException ie){}
}
else{
sleepSkipped++;
if(sleepSkipped == maxSleepSkipped){
Thread.yield();
sleepSkipped = 0;
}
}
fpsTime += (System.nanoTime() - beforeTime) / 1000000;
fps++;
if(fpsTime > 1000){
System.out.println("FPS: " + fps);
fps = 0;
fpsTime = 0;
}
beforeTime = System.nanoTime();
}
}
I think your problem is similar to one very recently Weird behavior in Thread.sleep()
I see that in your loop you add the sleeptime to your timer, meaning it keeps increasing (lowering fps) until it becomes so large that substracting the waittime from it gives a negative number, making your loop go into the one that yields the thread where it adds to the skipcount and yields when the count is high enough.
As arynaq suggested, it was a problem with the enemy collision detection. Every cycle through the loop made each enemy call quite a few methods, however I have now removed and relocated many of the method calls, which has completely fixed the lag problem. Thank you, arynaq.