Reputation: 47
I did what someone told me to do with my game loop, adding swing timer etc (except overriding paintComponent as it doesn't apply in this situation), but my game loop refuses to call the Event Dispatching Thread. Because of this, the JFrame does not close and keyboard input is obsele. Can I call EDT manually or is there something I am missing?
public class Window extends JFrame implements KeyListener{
private static final long serialVersionUID = 1L;
JPanel panel;
public static int screenX = 500;
public static int screenY = 500;
private int w = 0, h = 0;
public Window(){
super("FileTyper");
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
super.setSize(506,533);
super.setResizable(false);
panel = new JPanel();
super.getContentPane().add(panel);
super.setFocusable(true);
addKeyListener(this);
super.setVisible(true);
}
public void update(){
w++;h++;
if(w>500){
w = 0;
h = 0;
}
}
public void render(Graphics2D g){
g.setColor(Color.CYAN);
g.fillRect(0,0,500,500);
g.setColor(Color.black);
g.fillOval(0, 0, w, h);
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_F9:
panel.getGraphics().setColor(Color.green);
panel.getGraphics().drawRect(0, 0, 100, 100);
break;
case KeyEvent.VK_F10:
break;
}
}
@Override
public void keyTyped(KeyEvent arg0) {
}
}
public class Boxy {
public Window window;
boolean running = true;
private BufferedImage offscreen;
public static void main (String args[]){
// Boxy box = new Boxy();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
begin();
}
});
}
public Boxy(){
//initialize variables
}
public void gameLoop(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
init();
while(running){
update();
render();
delay();
}
}
});
}
public void runGameLoop()
{
Timer timer = new Timer(20, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
gameLoop();
}
});
timer.start();
}
private void init(){
window = new Window();
offscreen = new BufferedImage(Window.screenX,Window.screenY,BufferedImage.TYPE_INT_RGB);
}
private void update(){
window.update();
}
private void render(){
Graphics2D g = (Graphics2D) offscreen.getGraphics();
window.render(g);
Graphics2D g2 = (Graphics2D) window.panel.getGraphics();
g2.drawImage(offscreen,0,0,null);
}
private void delay(){
try {Thread.sleep(10);} catch (InterruptedException ex) {System.out.println("ERROR: Delay compromised");}
}
public static void begin(){
Boxy box = new Boxy();
box.runGameLoop();
}
}
Upvotes: 0
Views: 352
Reputation: 347184
javax.swing.Timer
guarantees that the actionPerformed
method of the assigned ActionListener
is called within the context of the EDTYour runGameLoop
should look more like...
public void runGameLoop()
{
Timer timer = new Timer(20, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
update();
render();
}
});
timer.start();
}
Before implementing any suggestions, its recommended to try and understand what those recommendations are trying to acheive...
Have a read through
For more details.
Upvotes: 4