marcuiulian13
|
 |
«
Posted
2012-04-10 09:49:43 » |
|
Hello there! I'm new here, and also in java world. I'm currently working on a tile-based game. The problem is: When i make a runnable jar file and open it in my computer, i have 55-60 FPS, but if one of my friends open it, the FPS don't pass 18. I have to mention that my PC is slower (in hardware) than theirs. Here is my Core class: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| package com.game;
import java.awt.*; import com.game.gui.*;
public abstract class Core implements Runnable { private boolean running; public static GameScreen screen; public boolean paused; public int fps; boolean game_is_running = true; long startTime, currTime; public void run() { init(); gameLoop(); startTime = System.currentTimeMillis(); currTime = System.currentTimeMillis(); } public void init() { screen = new GameScreen(); running = true; } public void gameLoop() { int TICKS_PER_SECOND = 60; int SKIP_TICKS = 1000 / TICKS_PER_SECOND; int MAX_FRAMESKIP = 10; long next_game_tick = currTime-startTime; int loops; fps = 0; int frames = 0; long totalTime = 0; long curTime = System.currentTimeMillis(); long lastTime = curTime; while(running) { lastTime = curTime; curTime = System.currentTimeMillis(); totalTime += curTime - lastTime; if( totalTime > 1000 ) { totalTime -= 1000; fps = frames; frames = 0; } frames++; currTime = System.currentTimeMillis(); loops = 0; while( currTime - startTime > next_game_tick && loops < MAX_FRAMESKIP) { update(); next_game_tick += SKIP_TICKS; loops++; } Graphics2D g = screen.getGraphics(); render(g); g.dispose(); screen.update(); } }
public abstract void render(Graphics2D g); public void update() {} } |
|
Getting a project done is by far the most hard thing in game development.
|
|
|
ra4king
|
 |
«
Reply #1 - Posted
2012-04-10 10:17:33 » |
|
Your game loop runs without sleeping, so I blame the accuracy of System.currentTimeMillis. Use System.nanoTime() instead.
However, it's generally not a good idea to let the game loop run as fast as possible, since this will take up 100% of the CPU.
Also, what OS are you and your friend using?
|
|
|
|
marcuiulian13
|
 |
«
Reply #2 - Posted
2012-04-10 10:21:45 » |
|
I've never used System.nanoTime() before, so is this the only change that i should make (change everywhere System.currentTimeMillis() with System.nanoTime()) ? How to calculate the fps with nano?
I use Windows 7 and they use Win7, WinXP and WinVista.
|
Getting a project done is by far the most hard thing in game development.
|
|
|
Games published by our own members! Check 'em out!
|
|
Waterwolf
|
 |
«
Reply #3 - Posted
2012-04-10 10:24:35 » |
|
Maybe the hardware graphics acceleration is enabled on your computer but not on your friend's
|
|
|
|
marcuiulian13
|
 |
«
Reply #4 - Posted
2012-04-10 10:26:24 » |
|
I don't think so... Also, i have notebook, if this is relevant. This is my Screen class: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| package com.game.gui; import java.awt.Canvas; import java.awt.Graphics2D; import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class GameScreen extends JFrame { private static final long serialVersionUID = 1L; final int SCREEN_WIDTH = 512, SCREEN_HEIGHT = 512; public Canvas canvas; public BufferStrategy buffer; public GameScreen() { this.setResizable(false); this.setIgnoreRepaint(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); canvas = new Canvas(); canvas.setIgnoreRepaint( true ); canvas.setSize(SCREEN_WIDTH, SCREEN_HEIGHT); this.add(canvas); this.pack(); this.setVisible(true); this.setLocationRelativeTo(null); canvas.createBufferStrategy(3); } public Graphics2D getGraphics() { buffer = canvas.getBufferStrategy(); return (Graphics2D) buffer.getDrawGraphics(); } public void update() { if(canvas != null) { buffer = canvas.getBufferStrategy(); if(!buffer.contentsLost()) buffer.show(); } } } |
|
Getting a project done is by far the most hard thing in game development.
|
|
|
marcuiulian13
|
 |
«
Reply #5 - Posted
2012-04-10 10:39:01 » |
|
Cold anyone recommend me a good game loop? Because i think this is the problem. Thanks!
|
Getting a project done is by far the most hard thing in game development.
|
|
|
|
ReBirth
|
 |
«
Reply #7 - Posted
2012-04-10 11:31:48 » |
|
On far sight, somebody can't keep their OS clean. So many background services running and eat CPU. Maybe your friends too.
|
|
|
|
marcuiulian13
|
 |
«
Reply #8 - Posted
2012-04-10 16:55:46 » |
|
Ok, thanks for the advices. But is really needed to use interpolation? I think are too many things to change just for some miliseconds...
EDIT: Any tip for me about how to reduce the cpu usage in MY game loop?
|
Getting a project done is by far the most hard thing in game development.
|
|
|
Riven
|
 |
«
Reply #9 - Posted
2012-04-11 07:58:25 » |
|
Unfortunately, all proposed solutions in the 'game loop thread' are flawed.  I advise you to take a look at my game-loop code that is included in LWJGL. It works properly and takes into account a lot of factors that influence both the CPU usage and the smoothness of the FPS. Usage: 1 2 3 4
| while(true) { this.render(); Sync.sync(60); } |
If you want to include fixed interval update ticks: 1 2 3 4 5 6 7 8 9 10 11 12 13
| long nanosInSecond = 1000L*1000L*1000L; long updateFrequency = 100; long updateInterval = nanosInSecond / updateFrequency; long nextUpdateTick = System.nanoTime();
while(true) { for(long now = System.nanoTime(); now > nextUpdateTick; nextUpdateTick += updateInterval) { this.update(); }
this.render(); Sync.sync(60); } |
|
Hi, appreciate more people! Σ ℠= ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
Games published by our own members! Check 'em out!
|
|
theagentd
|
 |
«
Reply #10 - Posted
2012-04-11 16:00:45 » |
|
Riven, the enemy of all current and future 120Hz monitor owners. No, thanks, I think I'll go with interpolation for my game. At least your new sync() a big improvement to the old Display.sync().
|
Myomyomyo.
|
|
|
Z-Man
|
 |
«
Reply #11 - Posted
2012-04-11 23:45:36 » |
|
Unfortunately, all proposed solutions in the 'game loop thread' are flawed.  I advise you to take a look at my game-loop code that is included in LWJGL. It works properly and takes into account a lot of factors that influence both the CPU usage and the smoothness of the FPS. Usage: 1 2 3 4
| while(true) { this.render(); Sync.sync(60); } |
If you want to include fixed interval update ticks: 1 2 3 4 5 6 7 8 9 10 11 12 13
| long nanosInSecond = 1000L*1000L*1000L; long updateFrequency = 100; long updateInterval = nanosInSecond / updateFrequency; long nextUpdateTick = System.nanoTime();
while(true) { for(long now = System.nanoTime(); now > nextUpdateTick; nextUpdateTick += updateInterval) { this.update(); }
this.render(); Sync.sync(60); } |
Since you wrote this, can we use it separate from LWJGL without having to meet the licensing conditions of LWJGL? Or at least adapt parts of it? I just don't want to do this part of the license x) Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
|
|
BoBear2681
|
 |
«
Reply #12 - Posted
2012-04-12 03:00:02 » |
|
It's quite rare that you find somebody who has beef with modified BSD.
|
|
|
|
Z-Man
|
 |
«
Reply #13 - Posted
2012-04-12 03:04:47 » |
|
I don't have a beef, I'm just lazy 
|
|
|
|
Riven
|
 |
«
Reply #14 - Posted
2012-04-12 11:31:47 » |
|
kappa/kappaOne modified the structure of the code a bit, so it's not 100% mine.
|
Hi, appreciate more people! Σ ℠= ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
joeyismusic
|
 |
«
Reply #15 - Posted
2012-04-13 02:30:22 » |
|
If anyone wants to use this without LWJGL, just replace 1 2 3 4
| private static long getTime() { return System.nanoTime(); } |
and remove the imports. I don't know what this means in terms of licensing or legalities, I'm just showing you how to use it without the LWJGL dependencies.
|
|
|
|
marcuiulian13
|
 |
«
Reply #16 - Posted
2012-04-13 21:35:40 » |
|
Thanks to everyone for answer. I resolved the problem. My game is getting shape... I hope in a week or two, it will be done.
|
Getting a project done is by far the most hard thing in game development.
|
|
|
DzzD
|
 |
«
Reply #17 - Posted
2012-04-13 21:53:53 » |
|
maybe this kind of loop will help (inded feel free to replace currentTimeMillis by nonoTime...) EDIT: after reading it dos not seems to be as good :/ this one seems better, it will do a fixed step logic/physic and will render only if at least one logic update has been performed (and then max FPS will be also limited to update logic rate but will run logic the same even on computer with very low FPS and will only consume requiered CPU on fastest computer): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| mainLoop() { time=getTime(); int elapsedTime=(time-lastTime); int nbLogic=elapsedTime/20; int interpolateMs=elapsedTime%20;
if(nbLogic!=0) { for(int n=0;n<nbLogic;n++) doLogicFor20ms(); drawAllObjectsOnScreen(interpolateMs); } else Thread.sleep(1);
lastTime+=20*nbLogic; } |
|
|
|
|
|