// Here's my code:
Main Class:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Display extends Canvas implements Runnable{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension dim = toolkit.getScreenSize();
public static int WIDTH;
public static int HEIGHT;
public static final String title = "First Person Game";
public static Thread thread;
public static Screen screen;
public static BufferedImage img;
public static boolean running = false;
public static int[] pixels;
public static Render render;
public Display(){
WIDTH = dim.width;
HEIGHT = dim.height;
screen = new Screen(WIDTH, HEIGHT);
img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
}
private void start(){
if(running){
return;
}else{
running = true;
thread = new Thread(this);
thread.start();
}
}
private void stop(){
if(!running){
return;
}else{
running = false;
try{
thread.join();
}catch(Exception x){
System.exit(0);
}
}
}
public void run(){
while(running){
render();
}
}
public void render(){
BufferStrategy bs = this.getBufferStrategy();
if(bs == null){
createBufferStrategy(3);
return;
}
screen.render();
for(int i = 0; i < WIDTH * HEIGHT; i++){
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
g.dispose();
bs.show();
}
public static void main(String args[]){
JFrame frame = new JFrame();
BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
frame.getContentPane().setCursor(blankCursor);
Display game = new Display();
frame.setUndecorated(true);
frame.add(game);
frame.setTitle(title);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
fps f = new fps();
game.start();
}
}
The class I need to call:
public class fps{
public void fps(){
System.out.println("Test 1 successful.");
int frames = 0;
double unprocessedSeconds = 0;
long previousTime = System.nanoTime();
double secondsPerTick = 1 / 60.0;
int tickCount = 0;
boolean ticked = false;
Display c = new Display();
System.out.println("Test 2 successful.");
c.render();
long currentTime = System.nanoTime();
long passedTime = currentTime - previousTime;
previousTime = currentTime;
unprocessedSeconds += passedTime / 1000000000.0;
while(unprocessedSeconds > secondsPerTick){
System.out.println("Test 3 successful.");
tick();
unprocessedSeconds -= secondsPerTick;
ticked = true;
tickCount++;
if(tickCount % 60 == 0){
System.out.println(frames + " fps");
previousTime += 1000;
frames = 0;
}
}
if(ticked){
c.render();
frames++;
}
c.render();
frames++;
}
public void tick(){}
}
/* I don't know how to do this, I've been trying all sorts of things. I basically need *to make sure fps is printing into the console while display is running. I can't seem to so */ this. I tried in method run() but it just wouldn't call it.
I beleive you need to create an instance of the fps class in your main class, and then call the method through it.
fps nameOfClassInstance = new fps(//don't forget anything you need to send for constructor);
fps.run();
At least this is how it is in C# which I know is very similar to java.
if this doesn't help,then I beleive it is a threading issue, and you need to make sure you are handling the threads properly. ( I can't help with this issue, I am still green to java threading.)
It is a little strange to have a method with the same name as your class. Is it meant to be a constructor, like this?
public class fps{
//Note that the void is removed here
public fps(){
System.out.println("Test 1 successful.");
int frames = 0;
double unprocessedSeconds = 0;
long previousTime = System.nanoTime();
double secondsPerTick = 1 / 60.0;
int tickCount = 0;
boolean ticked = false;
Display c = new Display();
System.out.println("Test 2 successful.");
c.render();
long currentTime = System.nanoTime();
long passedTime = currentTime - previousTime;
previousTime = currentTime;
unprocessedSeconds += passedTime / 1000000000.0;
while(unprocessedSeconds > secondsPerTick){
System.out.println("Test 3 successful.");
tick();
unprocessedSeconds -= secondsPerTick;
ticked = true;
tickCount++;
if(tickCount % 60 == 0){
System.out.println(frames + " fps");
previousTime += 1000;
frames = 0;
}
}
if(ticked){
c.render();
frames++;
}
c.render();
frames++;
}
public void tick(){}
}
I would also suggest that all that code is not really appropriate for a constructor and should be moved to its own method. Then, as mentioned by others, you can call your method after first creating an fps object.
There's an error in your code:
private void start(){
if(running){
return;
}else{
running = true;
thread = new Thread(this);
thread.start();
}
}
Threads are started by calling the start method. What you've done is to change the start() method. You should use the run method instead of the start method, as Thread.start() is meant for starting a thread while run() is where you are supposed to put the execution code.
As from the JavaDoc of the Java API, http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#start%28%29
public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
Well, you can do one of two things. You can either declare an fps object:
fps myfps = new fps();
myfps.fps();
or you can make it all static:
public static void fps(){
...
}
public static void tick(){}
//elsewhere
fps.fps()
static
and void
keywords both at the same time. You're code will not compile - mtk 2012-04-05 17:22
class fps{
public static void fps(){
}
}
. This is what i interpreted from your 2nd approach i.e. fps.fps()
.
I was commenting on the error in your 2nd code and not in your approach. : - mtk 2012-04-07 22:04