1. EJEMPLO 18 ANIMACIÓN USANDO GAMECANVAS
http://programacion-j2me.blogspot.com/2010/08/ejemplo-18-animacion-usando-
gamecanvas.html
La animación es un proceso de movimiento de imágenes o dibujos, hoy se muestra un pelotita o
bolita o circulo, rebotando por toda la pantalla del celular, esa es la primera animación de varias que
se van a realizar. La animación siguiente muestra lo que se pretende hacer con Java en el celular:
Como hacer la pelotita
Recuerde que la clase Graphics contiene métodos para dibujar ya se han visto algunas de estos
métodos, hay una función que me permite dibujar arcos se llama así
fillArc
Es posible realizar un círculo con esta función, esto se hace así porque la clase Graphics no tienen
ninguna instrucción para directamente crear un círculo. La función anterior requiere de 4
parámetros, estos se puede ver en la ayuda de J2ME para la clase Graphics, los parámetros son así:
fillArc(int x, int y, intwidth, intheight, startAngle, arcAngle);
Una imagen vale más que 1000 palabras, así que muestro un par de imágenes con la instrucción
fillArc.
2. Aquí hay otra imagen, que muestra incluso dos líneas para que quede bien claro donde se ubica el
circulo cuando se dibuja.
El lector puede seguir experimentando con los parámetros si así lo desea. Note que el primer par de
parámetros, que en el ejemplo son (10, 10) ubican la posición de una esquina de un rectángulo
imaginario, ese es el punto de referencia para iniciar el dibujo del círculo, después siguen las
coordenadas (30, 30) que es el ancho y el alto del circulo, y luego va el ángulo de inicio y el ángulo
del arco, para que sea un circulo completo se inicia con el ángulo en 0 y se termina con el ángulo en
360.
Por otro lado, en ese par de imágenes anteriores se puede ver que si la bolita se “desplaza” (primero
se puso en la coordenada (0,0) y luego en la (10,10) ), podemos decir que la bolita “se movio”, eso es
3. la animación, sensación de movimiento.
Ciclo para la animación
La animación, se puede resumir en lo siguiente: dibujar la pelota en una posición, borrar la pantalla
y volver a dibujarla ahora en otra posición, y repetir todo, una y otra vez, ¿Cómo se hace esto? Bien
simple con un ciclo, dando clic aquí para ver el post de los ciclos, si así lo deseas.
Por facilidad se usa el ciclo while(), la condición la colocamos en “true”, con eso basta para lograr un
ciclo infinito, después de todo se desea que la pelotita rebote “siempre”, entonces el código para el
ciclo es así:
while (true) {
// código para la animación
}
Pero ¿Dónde va el ciclo? Sencillo, en el método run(), después de todo
este ciclo se ejecuta cuando se inicia el subproceso, y como se vio en la
entrada anterior aquí es donde van las instrucciones para graficar, así
que el método run se va formando así:
publicvoidrun() {
while (true) {
// Código para la animación
}
}
El método “sleep” del subproceso
Se mencionó arriba que la animación es simplemente dibujar, borrar, volver a dibujar en otra
posición, borrar, y repetirlo, pero necesito hacerlo en pausas, es decir, dibujar por un tiempo
(algunos milisegundos), luego borrar todo y volver a dibujar en otra posición después de otro
tiempo, esto se puede realizar por medio del subproceso, ya se vio en el post anterior algo de los
subprocesos, al crear y después de iniciar el subproceso, se puede hacer uso de sus métodos, hay un
método llamado “sleep” (ver la documentación de la clase Thread, si se desean ver más detalles),
este método me permite hacer una pausa, un ejemplo en código puede ser el siguiente:
subproceso.sleep(100);
Al ejecutar esa instrucción el programa se detiene durante 100 milisegundos, este método debe ser
4. encerrado en un par de instrucciones así:
try {
subproceso.sleep(10);
} catch (InterruptedException e) { }
El “try y catch” son requeridos por el programa, si no se agregan hay un
error de compilación y nunca podre ejecutar el programa. Esas
instrucciones, me permiten capturar algún error, en java se llaman
excepciones, ya que el método sleep, puede crear errores por eso se usa
el “try” y el “catch”, el código va dentro del ciclo while y va quedando
así:
publicvoidrun() {
while (true) {
// Código para la animación
try {
subproceso.sleep(100);
} catch (InterruptedException e) { }
}
}
No se profundizará sobre las excepciones quizá más adelante se haga un post de esto, por lo pronto
nos interesa la animación, así que continuamos.
Variables usadas en la animación
Se vio en la sección anterior, que la pelotita se “mueve” con solo mover el parámetro x y el
parámetro y de fillArc, entonces, como inicio se pueden declarar esos parámetros con una variable
para después cambiarlos, así:
intcoordX = 0;
intcoordY = 0
Recuerde que la declaración va al inicio del método, ya con las variables declaradas, se puede crear
el circulo con la instrucción fillArc, en este caso es un circulo con 20 pixeles de ancho y alto, esta es
la instrucción
g.fillArc(coordX, coordY, 20, 20, 0, 360)
La instrucción va dentro del ciclo, el código toma la forma siguiente:
5. publicvoidrun() {
intcoordX = 0;
intcoordY = 0
while (true) {
g.fillArc(coordX, coordY, 20, 20, 0, 360)
try {
subproceso.sleep(100);
} catch (InterruptedException e) { }
}
}
¿Ahora que se necesitará para mover la pelotitia? Simplemente desplazar las coordenadas, estas que
son variables se pueden desplazar sumandoles un valor, así:
coordX = coordX + 1
coordY = coordY + 1
Otro ejemplo sería así:
coordX = coordX + 5
coordY = coordY + 5
O uno con desplazamientos diferentes,
coordX = coordX + 5
coordY = coordY + 3
Vea los ejemplos, en el primero solo se desplaza la pelotita 1 pixel, el segundo 5 pixeles ¿Qué
diferencia hay? Entre 1 pixel o 5 pixeles en el desplazamiento, la animación siguiente nos da la
respuesta:
6. Nota: La animación es para fines ilustrativos solamente, está realizada con un programa llamado
SwishMax 2, por lo que no se si vaya más rápido o más lento cuando se programe en Java.
Obviamente la pelotita va más rápido con 5 pixeles que con 1, por que los incrementos en las
coordenadas son mayores, podemos entonces decir que el sumarle una variable a la coordenada
hace que se cambie su velocidad, por comodidad se va a almacenar este desplazamiento en variables
también, se declaran así:
intvelX = 5;
intvelY = 5;
Yo las inicie en 5, el lector puede hacerlo en 1 o en otro valor, queda el código así:
publicvoidrun() {
intcoordX = 0;
intcoordY = 0;
intvelX = 5;
intvelY = 5;
while (true) {
g.fillArc(coordX, coordY, 20, 20, 0, 360)
try {
subproceso.sleep(100);
} catch (InterruptedException e) { }
coordX = coordX + velX;
7. coordY = coordY + velY;
}
}
Es obvio también, que si se ejecuta este código la pelotita se va de largo ¿Por qué? Ya se imaginará el
lector que falta agregar un código que haga que la pelotita rebote esto es que cambie de dirección
como se ve en la figura:
Aparte, en la figura se observa donde está el punto (0,0) en el sistema de coordenadas de Java para
que el lector lo recuerde, también se muestra el alto y ancho de la pantalla, que es donde la pelotita
rebota, entonces bastaría con que yo compare la posición de la pelotita para saber si llego a lo alto
de la pantalla (o a lo ancho) y simplemente cambio de dirección.
Entonces, una simple comparación puede detectar si la pelotita llego a lo alto del panel, primero
pues vamos a usar un par de variables para obtener el alto y ancho del panel así:
int ancho = getWidth();
int alto = getHeight();
Ahora sí, se inician las comparaciones, que tal un if para “ver “ si ya toco el alto así:
8. if (coordY> alto) {
// código para cambiar de dirección
}
Pero vea la figura y recuerde lo que se menciono arriba, el círculo se dibuja tomando como
referencia la esquina de un rectángulo, que justo son las coordenadas x e y:
¿Cómo se cambia la dirección?
La respuesta es bien simple, para el ejemplo que se muestra, la pelotita se desplaza hacia abajo por
que se suma se suma la velocidad (variable velY) pero que tal si envés de sumar se resta la velocidad,
la pelotita se iría hacia arriba.
Entonces para que la pelotita cambie la dirección basta con restar la velocidad, esto se hace
simplemente con cambiar el signo de la variable así:
velY = -velY;
Con esa instrucción la pelotita rebotará al llegar a lo alto de la pantalla, el código del método run
queda de la siguiente forma al agregar el primer if:
9. publicvoidrun() {
intcoordX = 0;
intcoordY = 0;
intvelX = 5;
intvelY = 5;
while (true) {
g.fillArc(coordX, coordY, 20, 20, 0, 360)
try {
subproceso.sleep(100);
} catch (InterruptedException e) { }
coordX = coordX + velX;
coordY = coordY + velY;
if ((coordY + 20) > alto) {
velY = -velY;
}
}
}
Ahora vea en la figura el siguiente caso que tiene que ver con la
coordenada Y todavía:
10. La pelotita se dirige a la coordenada 0, de Y, para ese momento la
velocidad es negativa obviamente deseamos que rebote de ahí, entonces se
requiere otra comparación para hacerlo, así:
if (coordY < 0) {
velY = -velY;
}
Con eso basta para que detecte el límite de la pantalla y al cambiar de
signo la velocidad, la pelotita cambia de dirección.
Es posible unir los dos if’s para la coordenada Y usando el operador OR (operador lógico) de Java, el
operador OR en Java es así || el código queda entonces con un solo if de esta forma:
if ((coordY + 20) > alto || (coordY < 0 ))
velY = -velY;
También quitamos las { }, puesto que sigue solo una instrucción no son necesarias.
Todo lo que se hizo para la coordenada Y se aplica para la coordenada X y
el ancho de la pantalla , así que les dejo como va quedando el código
para el método run ya con los if’s para las ambas coordenadas
publicvoidrun() {
intcoordX =0, coordY=50;
intvelX = 5;
intvelY = 5;
int ancho = getWidth();
int alto = getHeight();
while(true) {
g.fillArc(coordX,coordY,20,20,0,360);
try {
subproceso.sleep(30);
} catch (InterruptedException e) { }
coordX = coordX + velX;
coordY = coordY + velY;
if ((coordX + 20) > ancho || (coordX < 0) )
velX = -velX;
if ((coordY + 20) > alto || (coordY < 0 ))
velY = -velY;
flushGraphics();
}
}
11. También en el código anterior se agrego el método flushGraphics al final
del código.
Recuerde la animación es un ciclo de dibujar, borrar, dibujar en otra
posición, borrar…. Y así sucesivamente, para terminar falta el borrado el
código anterior, no funcionaría como se desea si no es borrada la
pantalla, esto se hace colocando el fondo del color que se quiera, en
este caso es en color negro, aparte se agrega el código para pintar la
pelotita en color azul.
g.setColor(0x000000); //color negro
g.fillRect(0, 0, ancho, alto);
g.setColor(0x0000FF); //color azul
Por fin se muestra el código completo para el método run(), el código para borrar se coloca después
del while
publicvoidrun() {
intcoordX =0, coordY=50;
intvelX = 5;
intvelY = 5;
int ancho = getWidth();
int alto = getHeight();
while(true) {
g.setColor(0x000000); //color negro
g.fillRect(0, 0, ancho, alto);
g.setColor(0x0000FF); //color azul
g.fillArc(coordX,coordY,20,20,0,360);
try {
subproceso.sleep(30);
} catch (InterruptedException e) { }
coordX = coordX + velX;
coordY = coordY + velY;
if ((coordX + 20) > ancho || (coordX < 0 )
velX = -velX;
if ((coordY + 20) > alto || (coordY < 0 ))
velY = -velY;
flushGraphics();
}
}
12. Vaya este post se me hizo larguísimo, pero ya es todo, fiel a mi costumbre se muestra el video-
tutorial completito para que no haya errores de ningún tipo y el lector pueda implementarlo con
toda la confianza del mundo.
http://www.youtube.com/watch?feature=player_embedded&v=P05F-C5VnBY#t=0