import java.awt.Canvas; import java.awt.Graphics2D; import java.awt.Dimension; import java.awt.BorderLayout; import java.awt.event.KeyListener; import java.awt.event.KeyEvent; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelListener; import java.awt.event.MouseWheelEvent; import java.awt.image.BufferStrategy; import javax.swing.JFrame; import javax.swing.JPanel; // TODO: implement pause (rendering) function public abstract class Scene extends JPanel implements Runnable, KeyListener, MouseListener, MouseMotionListener, MouseWheelListener { protected final long DESIRED_FPS = 60; protected final long DESIRED_DELTA_LOOP = (1000*1000*1000)/DESIRED_FPS; // TODO: lowercase not constant values protected int WIDTH; protected int HEIGHT; protected BufferStrategy buffer; // TODO: remove frame reference protected JFrame frame; protected boolean running; protected Canvas canvas; // TODO: make accessible from user settings protected int guiSize = 2; protected Scene(JFrame frame) { this.frame = frame; // getting window size this.WIDTH = (int) this.frame.getSize().getWidth(); this.HEIGHT = (int) this.frame.getSize().getHeight(); this.canvas = new Canvas(); this.canvas.setBounds(0, 0, this.WIDTH, this.HEIGHT); this.canvas.setIgnoreRepaint(true); this.canvas.addKeyListener(this); this.canvas.addMouseListener(this); this.canvas.addMouseMotionListener(this); this.canvas.addMouseWheelListener(this); } public void initCanvasBuffer() { this.canvas.createBufferStrategy(2); this.buffer = this.canvas.getBufferStrategy(); this.canvas.requestFocus(); } public void run() { long beginLoopTime; long endLoopTime; long currentUpdateTime = System.nanoTime(); long lastUpdateTime; long deltaLoop; this.initCanvasBuffer(); this.running = true; while (running) { beginLoopTime = System.nanoTime(); // TODO: use WindowEventListener to wait for changes //getting window size this.WIDTH = (int) this.frame.getSize().getWidth(); this.HEIGHT = (int) this.frame.getSize().getHeight(); this.render(); lastUpdateTime = currentUpdateTime; currentUpdateTime = System.nanoTime(); this.update((int) ((currentUpdateTime - lastUpdateTime)/(1000*1000))); endLoopTime = System.nanoTime(); deltaLoop = endLoopTime - beginLoopTime; if (deltaLoop > this.DESIRED_DELTA_LOOP) { // TODO: late => skip frame } else { try { Thread.sleep((this.DESIRED_DELTA_LOOP - deltaLoop)/(1000*1000)); } catch (InterruptedException e ) { } } } } protected abstract void render(); protected abstract void update(int deltaNanoTime); @Override public void keyTyped(KeyEvent e) {} public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseDragged(MouseEvent e) {} public void mouseMoved(MouseEvent e) {} public void mouseWheelMoved(MouseWheelEvent e) {} }