// Load an image using BufferedImage, with optimization public BufferedImage loadImageBuffered (String imageName) { // Some preliminaries and setup GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration(); try { BufferedImage bi = ImageIO.read(getClass().getResource(imageName)); // imageName read into bi int transparency = bi.getColorModel().getTransparency(); BufferedImage copy = gc.createCompatibleImage(bi.getWidth(), bi.getHeight(), transparency); // buffered, optimized copy of bi made Graphics2D g2d = copy.createGraphics(); g2d.drawImage(bi, 0, 0, null); // bi drawn g2d.dispose(); return copy; } catch (IOException e) { System.err.println("Image loading error: " + e.toString()); return null; } }
while (game is running) { while (isPaused && isRunning) { sleep(someInterval); } updateState(); processInputs(); updateAI(); updatePhysicsAndCollisions(); updateAnimations(); playSounds(); updateVideo(); drawGraphics(); ... ... ... }
import java.awt.*; import javax.swing.*; // "Runnable" JPanel is a thread public class AnimationFramework extends JPanel implements Runnable { // http://www.javablogging.com/what-is-serialversionuid/ // Certain IDEs will warn that you are missing SerialVersionUID private static final long serialVersionUID = 1L; private Thread animator; public AnimationFramework() { } // start(), stop(), run() are Thread methods public void start() { animator = new Thread(this); animator.start(); } public void stop() { animator = null; } public void run() { long start = System.currentTimeMillis(); Thread current = Thread.currentThread(); while (current == animator) { try { Thread.sleep(0); } catch (InterruptedException e) { System.err.println("An error occurred: " + e.toString()); e.printStackTrace(); } // Draw something repaint(); // Figure out how fast it is running if (start + 1000 < System.currentTimeMillis()) { start = System.currentTimeMillis(); } } } public void paintComponent (Graphics g) { // Do your drawing stuff here } }
import java.awt.*; import javax.swing.*; public class AnimationFramework extends JPanel implements Runnable { private static final long serialVersionUID = 1L; private Thread animator; // Going to adjust frame delay private int fps, delay; public AnimationFramework() { // 30 frames per second; considered sort of a minimum acceptable frame rate fps = 30; // 1000 milliseconds = 1 second delay = 1000 / fps; // for 30 fps, delay will be about 33.3 ms. } public AnimationFramework (int fps) { this.fps = fps; delay = 1000 / this.fps; } public void start() { animator = new Thread(this); animator.start(); } public void stop() { animator = null; } public void run() { long start = System.currentTimeMillis(); Thread current = Thread.currentThread(); while (current == animator) { try { start += delay; // Delay next frame depending on how far behind current time we are. // For simple animations, incrementing start by the delay value // will probably keep pace with the current time, but if we're doing // a lot in this while loop, we'll eventually fall behind current time. // So to keep up, sleep(0) will be used. Also, see the if statement below. Thread.sleep(Math.max(0, start - System.currentTimeMillis())); } catch (InterruptedException e) { System.err.println("An error occurred: " + e.toString()); e.printStackTrace(); } // Draw something repaint(); // Figure out how fast it is running; // if start is more than 1000 ms behind current time, reset start // to current time if (start + 1000 < System.currentTimeMillis()) { start = System.currentTimeMillis(); } } } public void paintComponent (Graphics g) { // Do your drawing stuff in this routine } }
a) Multiple moving circles and squares using a GameSprite
class:
b) A snowfall using a GameSprite
class:
public ArrayList <BufferedImage> loadStripImageArray(String imageName, int numImages) { ArrayList<BufferedImage> list = new ArrayList<BufferedImage>(); GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration(); BufferedImage stripIm; if ( numImages > 0 ) { stripIm = loadImageBuffered( imageName ); if (stripIm != null) { int width = (int) stripIm.getWidth() / numImages; int height = stripIm.getHeight(); int transparency = stripIm.getColorModel().getTransparency(); Graphics2D stripGC; for (int i = 0; i < numImages; i++) { BufferedImage holder = gc.createCompatibleImage(width, height, transparency); list.add(holder); stripGC = holder.createGraphics(); stripGC.drawImage(stripIm, 0, 0, width, height, i * width, 0, (i * width) + width, height, null); stripGC.dispose(); } return list; } } return null; }
The loadStripImageArray()
method listed above is used in a GameSpriteAdvanced
class for the following demonstration:
c) Bats and fireballs using the GameSpriteAdvanced class: