import java.applet.*; import java.awt.*; import java.util.*; /** * General action game applet class-- has somewhat clever * desired framerate system, takes care of double buffering. * Games derived from it need to define setupGame() (run at begining) * and runGame() (run every tick of the clock, game must paint * current scene onscreen **/ abstract public class GameRunner extends Applet implements Runnable { Thread animation; Graphics offscreenGraphics; Image offscreenImage; int screenWidth, screenHeight; // applet dimensions Color screenColor = Color.black; //default color, can be changed by game long oldTime; //used for time keeping static final int REFRESH_RATE = 30; // in ms, target time between clicks static final int KEY_SPACE = 32; static final int KEY_ENTER = 10; static final int KEY_ESCAPE = 27; public void init() { screenWidth = bounds().width; // get applet dimensions screenHeight = bounds().height; offscreenImage = createImage(screenWidth,screenHeight); // make offscreenGraphics buffer offscreenGraphics = offscreenImage.getGraphics(); setupGame(); //run game setup routine setBackground(screenColor); // applet background oldTime = System.currentTimeMillis(); //setting clocktracker } /** * called when the game starts up (in init()) */ abstract void setupGame(); /** * called every time the screen goes to paint itself */ abstract void runGame(Graphics offG); public void paint(Graphics g) { offscreenGraphics.setColor(screenColor); offscreenGraphics.fillRect(0,0,screenWidth,screenHeight); // clear buffer runGame(offscreenGraphics); //game expected to drawitself g.drawImage(offscreenImage,0,0,this); } /* * Utility function for drawing centered text */ void centerString(Graphics g, String text, int centerX, int topY){ int textwidth = g.getFontMetrics().stringWidth(text); g.drawString(text,centerX-(textwidth/2),topY); // clear buffer } public void start() { animation = new Thread(this); if (animation != null) { animation.start(); } } // override update so it doesn't erase screen public void update(Graphics g) { paint(g); } /* * run routine tries to keep applet to certain framerate */ public void run() { while (true) { repaint(); Thread.currentThread().yield(); long newTime = System.currentTimeMillis(); // System.out.println("now:"+newTime+" then:"+oldTime+" diff:"+(newTime-oldTime)); try { //if we're done before the current time dictated //by the current framerate, sleep 'til that time // Thread.sleep (REFRESH_RATE); if(oldTime + REFRESH_RATE > newTime){ Thread.sleep (oldTime+REFRESH_RATE-newTime); } } catch (Exception exc) { }; oldTime = newTime; } } public void stop() { if (animation != null) { animation.stop(); animation = null; } } }