I've been following another java game development tutorial in order to get a basic understanding of threading, I have taken these tutorials and combined them with openGL programming that I have learnt previously. Except I think I may have missed something, because upon calling engine.stop()
(this includes thread.join()
), the window closes and the program hangs in the background, and you have to end its process.
Here is My Code:
package com.daboom.threadgl;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import com.daboom.threadgl.graphics.Camera;
public class EngineMain implements Runnable {
private boolean running;
private Thread thread;
private Camera cam;
/**
* Starts the Dual Threaded System, does not need to be called,
* already called upon application beginning
*/
@Override
public void run() {
initDisplay();
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
update();
updates++;
delta--;
}
render();
if (Display.isCloseRequested())
break;
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " u/sec " + frames + " f/sec");
Display.setTitle(Game.gameName + " || " + updates + " u/sec " + frames
+ " f/sec ||");
updates = 0;
frames = 0;
}
}
stop();
}
private void update() {
game.update();
}
Game game;
private void render() {
GL11.glLoadIdentity();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
cam.useView();
game.render3D();
cam.setProjection2D(Display.getWidth(), Display.getHeight());
game.render2D();
Display.update();
cam.resetTo3D();
}
public EngineMain() {
cam = new Camera();
game = new Game(this, cam);
}
private void initDisplay() {
try {
Display.setDisplayMode(new DisplayMode(800, 600));
Display.setTitle(Game.gameName);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glClearColor(0, 0, 0, 1);
cam.setProjection3D(63,(float) Display.getWidth() / (float)Display.getHeight(), 0.3f,
1000);
try {
Keyboard.create();
Mouse.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
}
/**
* Starts the Multi-Threading and the Game
*
*/
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
/**
* Safely Stops the program
* Call this to exit the game
*/
public synchronized void stop() {
running = false;
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
EngineMain main = new EngineMain();
main.start();
}
}
When i use his tutorials, with out the modifications to use his code, the process ends properly.
I cannot for the life of me, identify the problem.
P.S if you need more comments, just ask.
EDIT: Here is the original code before modification
package com.thecherno.rain;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import com.thecherno.rain.graphics.Screen;
import com.thecherno.rain.input.Keyboard;
public class Game extends Canvas implements Runnable {
/**
*
*/
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
public static String title = "Rain";
private Thread thread;
private JFrame frame;
private Keyboard key;
private boolean running = false;
private Screen screen;
private BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer())
.getData();
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
screen = new Screen(width, height);
frame = new JFrame();
key = new Keyboard();
addKeyListener(key);
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
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 updates = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
update();
updates++;
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " u/sec " + frames + " f/sec");
frame.setTitle(title + " | " + updates + " u/sec " + frames
+ " f/sec");
updates = 0;
frames = 0;
}
}
stop();
}
int x, y;
public void update() {
key.update();
if (key.up)
y--;
if (key.down)
y++;
if (key.left)
x--;
if (key.right)
x++;
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
screen.clear();
screen.render(x, y);
for (int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle(Game.title);
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}