Gå til innhold

Jeg lærer meg grafikkprogrammering: Animering av bilder [part 2]


Anbefalte innlegg

I forrige tråd foregrep jeg framtiden litt. I denne tråden går jeg litt tilbake, og viser hvordan man kan bruke en bildeserie, til å skape en animasjon. De 3 bildene som er vedlagt passer fint til dette.

 

Aller først trenger vi en Animation klasse, som vi kan bruke om og om igjen til alle våre animasjoner :).

 

Animation.java:

 

package grxTest;

import java.awt.*;
import java.util.*;

import javax.swing.ImageIcon;

public class Animation {
private ArrayList<AnimFrame> frames; // les på generics om du ikke forstår denne
private int currFrameIndex; // gjeldene bildeindex (0,1,2)
private long animTime; // hvor lenge animasjonen har pågått
private long totalDuration; // hvor lang DENNE animasjonen faktisk er

public Animation() {
	frames = new ArrayList<AnimFrame>();
	totalDuration = 0;
	start();
}

public synchronized void addFrame(Image image, long duration) {
	totalDuration += duration;
	frames.add(new AnimFrame(image, totalDuration));
}

public synchronized void start() {
	animTime = 0;
	currFrameIndex = 0;
}

public synchronized void update(long elapsedTime) {
	if(frames.size() > 1) {
		animTime += elapsedTime;

		if(animTime >= totalDuration) { // dersom animeringen er ferdig, start på nytt
			animTime = 0;
			currFrameIndex = 0;
		}

		if(animTime > getFrame(currFrameIndex).endTime) {
			currFrameIndex++;
		} 
	}
}

public synchronized Image getImage() {
	if(frames.size() == 0)
		return null;

	return getFrame(currFrameIndex).image;
}

private AnimFrame getFrame(int i) {
	return frames.get(i);
}

private class AnimFrame {
	Image image;
	long endTime;

	public AnimFrame(Image image, long endTime) {
		this.image = image;
		this.endTime = endTime;
	}
}

public static Image loadImage(String s) {
	return new ImageIcon(s).getImage();
}
}

 

Koden er ganske rett fram, og greia er at update(elapsedTime) blir kallt på kontinuerlig av en gameLoop(), slik at animeringen skjer. Koden som tegnet bildet, kaller bare på animasjonen sin getImage() metode, da denne vil returnere bilder slik at en animasjon vil forekomme.

 

Her er rammeverket jeg bruker for å teste Animation klassen:

 

package grxTest;

import java.awt.*;

import javax.swing.JFrame;

public class Test extends JFrame{

private Animation anim;
private Image player1;
private Image player2;
private Image player3;

private Graphics graphicsBuffer;
private Image imageBuffer;

public static void main(String[] args) {
	new Test();
}

public Test() {
	setSize(500, 500);
	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	setIgnoreRepaint(true);
	setVisible(true);

	player1 = AnimationPractice.loadImage("/home/nab/Pictures/java/player1.png");
	player2 = AnimationPractice.loadImage("/home/nab/Pictures/java/player2.png");
	player3 = AnimationPractice.loadImage("/home/nab/Pictures/java/player3.png");

	anim = new Animation();
	anim.addFrame(player1, 300);
	anim.addFrame(player2, 600);
	anim.addFrame(player3, 100);

	gameLoop();
}

private void gameLoop() {

	long startTime = System.currentTimeMillis();
	long currTime = startTime;

	while(currTime - startTime < 5000) { // skal vare i 5 sekunder
		long elapsedTime = System.currentTimeMillis() - currTime;
		currTime += elapsedTime;

		anim.update(elapsedTime);
		paintScreen();

		try { Thread.sleep(20); } catch(InterruptedException e) { }
	}

	System.exit(0);
}

private void paintScreen() {
	// draw on buffer
	if(imageBuffer == null)
		imageBuffer = createImage(500, 500);

	graphicsBuffer = imageBuffer.getGraphics();
	// graphicsBuffer.drawImage(Animation.loadImage("/home/nab/Pictures/java/mario_bg.jpg"), 0, 0, null);

	graphicsBuffer.drawImage(anim.getImage(),100,100, null);
	graphicsBuffer.dispose();

	// draw on the screen
	Graphics g = getGraphics();
	g.drawImage(imageBuffer, 0, 0, null);
}
}

 

Studer koden inni gameLoop() nøye, fordi den er litt tricky å forstå ved første øyekast. Prøv å print ut elapsedTime eller currTime i loopen, og du vil forstå hensikten, og hva som skjer når du kaller på update(elapsedTume).

 

Igjen er det brukt double buffering for å forhindre flickering(at bildet blinker).

post-195530-1276837277,8586_thumb.png

post-195530-1276837282,9962_thumb.png

post-195530-1276837294,2522_thumb.png

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...