These 2 classes are basically the classes from the book developing games in java, without the fullscreen stuff. They are supposed to create an animation. They both compile fine but when I run I get an error message, an no animation, paint() is only called once. Here’s the error message:
Exception in thread “main” java.lang.IndexOutOfBoundsException: Index: 4, Size: 4
at java.util.ArrayList.RangeCheck(ArrayList.java:546)
at java.util.ArrayList.get(ArrayList.java:321)
at Animation.getFrame(Animation.java:60)
at Animation.update(Animation.java:43)
at AnimationTest1.animationLoop(AnimationTest1.java:58)
at AnimationTest1.run(AnimationTest1.java:44)
at AnimationTest1.main(AnimationTest1.java:10)
I think this means the program is trying to access frame 4 when there is none. Right? I just can’t get my brain around this. Any help would be great!
import java.awt.Image;
import java.util.ArrayList;
/* this class manages a serie of images (frames) and the amount of time to
display each frame */
public class Animation {
private ArrayList frames;
private int currFrameIndex;
private long animTime;
private long totalDuration;
//creates a new, empty animation, calls start().
public Animation() {
frames = new ArrayList();
totalDuration = 0;
start();
}
//adds an image to the animation, + how long to display the image.
public synchronized void addFrame(Image image, long duration) {
totalDuration += duration;
frames.add(new AnimFrame(image, totalDuration));
}
//starts this animation over from the beginning .
public synchronized void start() {
animTime = 0;
currFrameIndex = 0;
}
//updates this animations current frame if necessary
public synchronized void update(long elapsedTime) {
if (frames.size() >1) {
animTime += elapsedTime;
if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currFrameIndex = 0;
}
while (animTime > getFrame(currFrameIndex).endTime) {
currFrameIndex ++;
}
}
}
//gets the animations current frame. null if none availible.
public synchronized Image getImage() {
if (frames.size() == 0) {
return null;
}
else {
return getFrame(currFrameIndex).image;
}
}
private AnimFrame getFrame(int i) {
return (AnimFrame)frames.get(i);
}
private class AnimFrame {
Image image;
long endTime;
public AnimFrame(Image image, long endtime) {
this.image = image;
this.endTime = endTime;
}
}
}
import java.awt.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class AnimationTest1 {
public static void main (String args[]) {
AnimationTest1 test = new AnimationTest1();
test.run();
}
private static final long DEMO_TIME = 5000;
private JFrame frame;
private Animation anim;
public void loadImages() {
//load images
Image player1 = loadImage("gif1.png");
Image player2 = loadImage("gif2.png");
Image player3 = loadImage("gif3.png");
//create animation
anim = new Animation();
anim.addFrame(player1, 200);
anim.addFrame(player2, 200);
anim.addFrame(player3, 200);
anim.addFrame(player2, 200);
}
//loads image with ImageIcon
private Image loadImage(String filename) {
return new ImageIcon(filename).getImage();
}
public void run() {
try {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
frame.setVisible(true);
loadImages();
animationLoop();
}
finally {
}
}
public void animationLoop() {
long startTime = System.currentTimeMillis();
long currTime = startTime;
while (currTime - startTime < DEMO_TIME) {
long elapsedTime = System.currentTimeMillis() - currTime;
currTime += elapsedTime;
anim.update(elapsedTime);
//getContentpane.getgraphics??!!
Graphics g = frame.getGraphics();
draw(g);
g.dispose();
try {
Thread.sleep(20);
}
catch (InterruptedException ex) {}
}
}
//draw the animation
public void draw(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, 300, 300);
g.drawImage(anim.getImage(), 0, 0, null);
}
}