// 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: