Trying to figure out where to go from here. My update code is contained in my GameThread class, while my paint code is contained in my GamePanel class (which extends JPanel).
I want to be able to calculate the average frame rate/FPS in this but I'm not sure where to go from here. I currently calculate the elapsed time in my Update() loop but I also need to take into consideration my paintComponent() method in my GamePanel class.
Where would I go from here? What's the best way to calculate FPS based on this setup?
package networkresearch;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
*
*/
public class GamePanel extends CorePanel {
NetworkResearch ui;
GameThread gameThread;
ServerThread serverThread;
BufferedImage[] images_players;
ArrayList<Player> players;
BufferedImage gameBackground;
long startTime = 0;
long endTime = 0;
GamePanel(NetworkResearch ui) throws IOException{
images_players = new BufferedImage[5];
images_players[0] = ui.loadAsset("player_knight.png");
images_players[1] = ui.loadAsset("player_goblin.png");
images_players[2] = ui.loadAsset("player_ogre.png");
images_players[3] = ui.loadAsset("player_skeleton.png");
images_players[4] = ui.loadAsset("player_wolf.png");
this.ui = ui;
JTextField nameField = new JTextField("Test Player");
nameField.setColumns(6);
add(nameField);
gameBackground = ui.loadAsset("gameBackground.png");
players = new ArrayList();
Player player = new Player(images_players[4]);
players.add(player);
gameThread = new GameThread(this);
serverThread = new ServerThread();
}
@Override
public void keyTyped(KeyEvent e){
}
@Override
public void keyPressed(KeyEvent e){
for(Player player : players){
switch(e.getKeyChar()){
case 'a':
player.keyLeft = true;
break;
case 's':
player.keyDown = true;
break;
case 'd':
player.keyRight = true;
break;
case 'w':
player.keyUp = true;
break;
}
}
}
@Override
public void keyReleased(KeyEvent e){
for(Player player : players){
switch(e.getKeyChar()){
case 'a':
player.keyLeft = false;
break;
case 's':
player.keyDown = false;
break;
case 'd':
player.keyRight = false;
break;
case 'w':
player.keyUp = false;
break;
}
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(gameBackground, 0, 0, this);
for(Player player : players){
player.paint(g);
}
repaint();
}
@Override
public void start() {
this.setFocusable(true);
gameThread.start();
serverThread.start();
startTime = new Date().getTime();
}
@Override
public void stop(){
gameThread.stop();
serverThread.stop();
}
}
class GameThread extends Thread{
GamePanel game;
GameThread(GamePanel game){
this.game = game;
}
@Override
public void run() {
while(this.isAlive()){
for(Player player : game.players){
player.update();
}
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
Logger.getLogger(GameThread.class.getName()).log(Level.SEVERE, null, ex);
}
game.endTime = new Date().getTime();
long difference = game.endTime - game.startTime;
System.out.println("Elapsed milliseconds: " + difference);
}
}
}
class ServerThread extends Thread{
@Override
public void run() {
while(this.isAlive()){
}
}
}
Declare these variables with your other declarations:
long framerate = 1000 / 60;
// time the frame began. Edit the second value (60) to change the prefered FPS (i.e. change to 50 for 50 fps)
long frameStart;
// number of frames counted this second
long frameCount = 0;
// time elapsed during one frame
long elapsedTime;
// accumulates elapsed time over multiple frames
long totalElapsedTime = 0;
// the actual calculated framerate reported
Now, when the program is preparing for a 'loop-around' of the code, insert this:
// calculate the time it took to render the frame
elapsedTime = System.currentTimeMillis() - frameStart;
// sync the framerate
try {
// make sure framerate milliseconds have passed this frame
if (elapsedTime < framerate) {
Thread.sleep(framerate - elapsedTime);
}
else {
// don't starve the garbage collector
Thread.sleep(5);
}
}
catch (InterruptedException e) {
break;
}
++frameCount;
totalElapsedTime += (System.currentTimeMillis() - frameStart);
if (totalElapsedTime > 1000) {
reportedFramerate = (long) ((double) frameCount
/ (double) totalElapsedTime * 1000.0);
// show the framerate in the applet status window
System.out.println("fps: " + reportedFramerate);
// repaint();
frameCount = 0;
totalElapsedTime = 0;
}
Hopefully, the comment code is enough for you to get the gist of what is going on in this. Let me know if you have issues understanding this. Cheers.