En esta entrada del blog,
voy a enseñarte cómo hacer imágenes con animación en Java. Para
ello, lo primero que vamos a necesitar son...lo has adivinado:
imágenes. Pueden ser fotos, o pueden ser dibujos sencillos, pero eso
sí, tienen que mostrar movimientos consecutivos; por ejemplo, un
pájaro subiendo y bajando las alas, o una cara abriendo y cerrando
los ojos.
Si sabes utilizar
Photoshop, Gimp o cualquier otro programa por el estilo, enhorabuena,
dale rienda suelta a tu imaginación para crear las imágenes que
desees (y ya puestos, compártelas con nosotros).
Si por el contrario, eres
como yo, que a lo más que llegas es a dibujar un círculo con Paint,
pues nada, le pones dos circulitos más pequeños dentro para simular
ojos abiertos y dos líneas para simular ojos cerrados y ya tienes
una carita que parpadea. Ahora guardas los dos dibujos como .png y
listo.
También puedes añadirle
una imagen de fondo que ocupe toda la pantalla: una foto en formato
.jpg, otro dibujo o un fondo liso, lo que quieras.
Lo que vamos a hacer con
estas imágenes es, primero, crear un ArrayList para contenerlas, y
después, asignarles a cada una una duración determinada en
milisegundos. Por último, vamos a mostrarlas en pantalla en un bucle
para conseguir ese efecto de animación.
Para ello vamos a crear
una clase, Animación (qué sorpresa de nombre, ¿eh?) que contendrá
los métodos necesarios. Despues haremos otra para probarla, y
originales como somos la llamaremos AnimaciónTest.
PruebaDeAnimación tampoco está mal, pero es que es más largo. Dentro de esta clase AnimaciónTest vamos a utilizar un objeto de la clase PantallaCompleta, que creamos en una entrada anterior y que utilizamos, nunca lo adivinarías, para visualizar el resultado en una pantalla completa . Aquí puedes ver el código de esa clase.
Para que luego no te líes
con el código, te voy a explicar el significado de algunas variables
que verás en él:
- frames, que en inglés viene siendo fotogramas, es el nombre del ArrayList
- actualFrame es el número de índice de un elemento de frames
- tiempoAnimación es el tiempo que dura toda la animación
- tiempoTotal es la suma de los milisegundos de duración que hemos asignado a cada imagen
Clase Animación.java
import java.awt.Image; import java.util.ArrayList; public class Animación{ private ArrayList frames; private int actualFrame; private long tiempoAnimación; private long tiempoTotal; public Animación(){ frames = new ArrayList(); tiempoTotal = 0; start(); } public synchronized void addFrame(Image image, long duración){ tiempoTotal += duración; frames.add(new AnimFrame(image, tiempoTotal)); } public synchronized void start(){ tiempoAnimación = 0; actualFrame = 0; } public synchronized void update(long tiempoTranscurrido){ if(frames.size()>1){ tiempoAnimación += tiempoTranscurrido; if(tiempoAnimación >= tiempoTotal){ tiempoAnimación = tiempoAnimación % tiempoTotal; actualFrame = 0; } while(tiempoAnimación > getFrame(actualFrame).endTime){ actualFrame++; } } } public synchronized Image getImage(){ if (frames.size() ==0){ return null; }else{ return getFrame(actualFrame).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; } } }
Clase AnimaciónTest.java
import java.awt.*; import javax.swing.ImageIcon; import javax.swing.JFrame; public class AnimaciónTest { public static void main(String args[]) { DisplayMode displayMode= new DisplayMode(1024, 768, 32, DisplayMode.REFRESH_RATE_UNKNOWN); AnimaciónTest test = new AnimaciónTest(); test.run(displayMode); } private static final long DEMO_TIME = 10000; private PantallaCompleta pc; private Image bgImage; private Animación animación; public void loadImages() { // cargamos las imágenes bgImage = loadImage("images/background.jpg"); Image cara1 = loadImage("images/cara1.png"); Image cara2 = loadImage("images/cara2.png"); Image cara3 = loadImage("images/cara3.png"); // creamos la animación animación = new Animación(); animación.addFrame(cara1, 250); animación.addFrame(cara2, 150); animación.addFrame(cara1, 150); animación.addFrame(cara2, 150); animación.addFrame(cara3, 200); animación.addFrame(cara2, 150); } private Image loadImage(String fileName) { return new ImageIcon(fileName).getImage(); } public void run(DisplayMode displayMode) { pc = new PantallaCompleta(); try { pc.setFullScreen(displayMode, new JFrame()); loadImages(); animationLoop(); } finally { pc.restoreScreen(); } } public void animationLoop() { long tiempoInicio = System.currentTimeMillis(); long tiempoActual = tiempoInicio; while (tiempoActual - tiempoInicio < DEMO_TIME) { long tiempoTranscurrido = System.currentTimeMillis() - tiempoActual; tiempoActual += tiempoTranscurrido; // actualizamos la animación animación.update(tiempoTranscurrido); // se dibuja en pantalla Graphics g = pc.getFullScreenWindow().getGraphics(); draw(g); g.dispose(); // una pequeña pausa try { Thread.sleep(20); } catch (InterruptedException ex) { } } } public void draw(Graphics g) { // se dibuja el fondo g.drawImage(bgImage, 0, 0, null); // se dibuja la imagen y la centramos más o menos g.drawImage(animación.getImage(), 300, 200, null); } }
Yo he utilizado una imagen de fondo y tres dibujos de una cara, pero tú puedes usar el número de imágenes que quieras. Fíjate que cada imagen se puede añadir más de una vez, en distinto orden y con distinto tiempo asignado, para crear distintas animaciones. Tú puedes jugar con ello hasta encontrar la que te gusta.
En otro momento te enseñaré a añadirle otros efectos y a utilizar la clase BufferStrategy para evitar que la imagen parpadee.
¡Si tienes alguna duda, ya sabes dónde estoy!
como hago que no parpadee una imagen por ejemplo este es mi codigo en java
ResponderEliminarprivate void render(){
Graphics g;
g=this.getGraphics();
if(g!=null){
g.setcolor(Color.black);
g.fillrect(0, 0, 400, 400);
g.drawImage(imagen.getImage(), x, y, 40, 40, null);
Toolkit.getDefaultToolkit().sync();
g.dspose();
}}