import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Graphics; import java.awt.Image; import java.awt.Dimension; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelListener; import java.awt.event.MouseWheelEvent; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.ComponentListener; import java.awt.event.ComponentEvent; import java.lang.Runnable; import java.lang.Thread; import java.awt.Toolkit; public class Subconscious extends JPanel implements Runnable, MouseListener, KeyListener, ComponentListener, MouseWheelListener { public static final String TITLE = "Subconscious"; public static final long RENDER_PERIOD_MS = 10; /* graphics */ private JFrame window; private Scene currentScene; private Graphics dbg = null; // double buffered graphics private Image dbImage = null; // double buffered image private Thread animator = null; /* game */ // private volatile boolean gamePaused = false; private volatile boolean gameOver = false; private volatile boolean running = false; public Subconscious() { createWindow(); // setup component addMouseListener(this); addKeyListener(this); addComponentListener(this); addMouseWheelListener(this); setFocusable(true); requestFocus(); // TODO remove demo currentScene = new WorldScene(new Dimension(200, 200), 50); } private void createWindow() { window = new JFrame(TITLE); window.setSize(new Dimension(800, 600)); window.setMinimumSize(getSize()); window.setLocationRelativeTo(null); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.add(this); } /* game logic */ private void gameLoop() { } private void gameRender() { if (dbImage == null) { dbImage = createImage(getWidth(), getHeight()); if (dbImage == null) { System.out.println("ERROR: Cannot create image"); return; } } dbg = dbImage.getGraphics(); dbg.fillRect(0, 0, getWidth(), getHeight()); currentScene.render(dbg); } public void gameStart() { if (animator == null || !running) { animator = new Thread(this); animator.start(); } } /* animator and game thread */ @Override public void run() { long beforeTime, afterTime, sleepTime; int skipFrame = 0; window.setVisible(true); beforeTime = System.currentTimeMillis(); running = true; while (running) { gameLoop(); gameRender(); repaint(); // could be better with NanoSeconds, but this is // probably enough for this afterTime = System.currentTimeMillis(); sleepTime = RENDER_PERIOD_MS - (beforeTime - afterTime); if (sleepTime < 0) { skipFrame++; continue; } if (skipFrame > 0) skipFrame--; try { Thread.sleep(sleepTime); } catch (InterruptedException ex) {} beforeTime = System.currentTimeMillis(); } window.dispose(); System.exit(0); } /* graphics */ @Override public void paintComponent(Graphics g) { if (dbImage != null) { g.drawImage(dbImage, 0, 0, null); } Toolkit.getDefaultToolkit().sync(); // needed on linux g.dispose(); } /* listeners */ @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} @Override public void mouseClicked(MouseEvent e) { currentScene.mouseClicked(e.getX(), e.getY()); } @Override public void keyPressed(KeyEvent e) {} @Override public void keyTyped(KeyEvent e) {} @Override public void keyReleased(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_Q && e.isControlDown()) { running = false; } if (keyCode == KeyEvent.VK_DOWN) { currentScene.pan(0, -10); //rerender dbImage = null; } if (keyCode == KeyEvent.VK_UP) { currentScene.pan(0, 10); //rerender dbImage = null; } if (keyCode == KeyEvent.VK_LEFT) { currentScene.pan(10, 0); //rerender dbImage = null; } if (keyCode == KeyEvent.VK_RIGHT) { currentScene.pan(-10, 0); //rerender dbImage = null; } } @Override public void mouseWheelMoved(MouseWheelEvent e) { int value = e.getWheelRotation(); currentScene.zoom(value * -1); //rerender dbImage = null; } @Override public void componentHidden(ComponentEvent e) {} @Override public void componentShown(ComponentEvent e) {} @Override public void componentMoved(ComponentEvent e) {} @Override public void componentResized(ComponentEvent e) { dbImage = null; // create new image with the correct size } /* main */ public static void main(String args[]) { Subconscious g = new Subconscious(); g.gameStart(); } }