Un viaje a la luna
Para
crear animaciones con App Inventor utilizamos Sprites. Los sprites son
imágenes que puedes mover por la pantalla siempre dentro de un lienzo
(Canvas). Estas imágenes reaccionan a eventos como tocar (touch) o
arrastrar (drag) y se pueden mover por el lienzo a una velocidad y
dirección determinadas en sus propiedades. Vamos a verlo con un ejemplo.
1 Empieza un proyecto nuevo y llámalo "viaje_luna".
2 En las propiedades de la
pantalla (Screen) asegúrate de que la propiedad Scrollable está
desactivada. Además en la propiedad ScreenOrientation selecciona
Portrait (vertical).
3 Ahora añade los siguientes
componentes a tu programa: En primer lugar una etiqueta (label),
después un lienzo (canvas) y por último el componente OrientationSensor.
4 Selecciona la etiqueta y cambia su nombre por marcador. En la propiedad texto escribe 0.
5 Ahora selecciona el componente canvas y cambia la imagen de fondo (BackgroundImage) y selecciona la imagen estrellas.png que encontrarás en la carpeta de recursos.
6 Cambia también las propiedades Width (ancho) y Height (largo) a "fill parent".
7 Ahora vamos a añadir las
imágenes para nuestra primera animación. El componente que vamos a usar
se llama ImageSprite y lo encontrarás dentro de la categoría Drawing and
Animation (dibujos y animaciones). Vamos a necesitar dos, así que coge
dos componentes y ponlos dentro del canvas.
Animando el cohete
8 Selecciona el primer componente ImageSprite y cambia su nombre a cohete. Vamos a ver en detalle sus propiedades.
9 La primera propiedad que
nos interesa se llama Heading (ángulo de dirección) y nos indica la
dirección hacia la que queremos mover nuestra imagen. Podemos utilizar
un valor desde 0 hasta 360. 0 indica una dirección de izquierda a
derecha, 90 de abajo hacia arriba, 180 de derecha a izquierda y 270 de
arriba hacia abajo. Así:
10 En nuestro caso queremos
que nuestro cohete vaya subiendo por la pantalla de abajo hacia arriba,
por lo tanto pondremos en esta propiedad 90.
11 La siguiente propiedad se
llama Interval (intervalo) y representa cada cuanto tiempo vamos a
mover la imagen. Para nuestro ejemplo vamos a empezar poniendo 1000.
Este dato se representa en milisegundos. Por lo tanto 1000 milisegundos =
1 segundo.
12 En la propiedad Picture (imagen) vamos a seleccionar nuestra imagen para el cohete. Puedes encontrar la imagen que necesitas en la carpeta de recursos. Se llama cohete.png.
13 Desactiva la opción Rotates.
14 La siguiente propiedad
que nos interesa se llama Speed (velocidad) y nos indica el número de
pixeles que se va a mover nuestra imagen en el intervalo que hemos
definido antes. Para empezar pon 1.
15 Por último, cambia el ancho (width) y largo (height) de nuestro cohete por 50 x 50.
Si todo ha funcionado correctamente nuestro cohete se
debería de estar moviendo por la pantalla pero muy despacio. La
razón está en las propiedades Interval y Speed que hemos usado. Ahora
vamos a entender mejor cómo usarlas.
16 Antes de nada, si tu
cohete llega al margen superior de la pantalla se detendrá. Para volver a
ponerlo en su posición original basta con que lo muevas un poco desde
el Diseñador. De esta manera volverá a su posición original. Después
veremos cómo manejar esto desde el Editor de bloques.
17 Hasta ahora le hemos
pedido a nuestro cohete que cada segundo (Interval = 1000) se moviera 1
pixel (Speed = 1) Si cambias la propiedad interval y vas poniendo
valores cada vez más pequeños, el cohete avanza más rápido porque se
mueve cada menos tiempo. Si aumentas el número de pixeles que avanza
nuestra imagen (Speed) también avanzará más rápido porque los saltos
serán mayores. Recuerda que la velocidad depende de la distancia y del
tiempo. Prueba a cambiar estos valores hasta que encuentres el que más
te guste dependiendo de tu dispositivo. Un intervalo de 25 y una
velocidad de 5 suelen funcionar bien.
18 Ahora vamos al Editor de
bloques. En primer lugar vamos a colocar nuestro cohete en la posición
inicial que queremos. Como se trata de la posición inicial lo lógico es
hacerlo nada más arrancar nuestro programa, por lo tanto vamos a usar el
evento Screen1.Initialize que se activa al inicio como hemos visto ya.
Desde el componente Screen1 coge el evento Screen1.Initialize y ponlo en
tu programa.
19 Para colocar un sprite en
un punto en concreto de la pantalla podemos usar sus coordenadas como
hemos visto antes. Si seleccionas el componente cohete verás los bloques
verdes "set cohete.X to" y "set cohete.Y to" cógelos y ponlos dentro
del evento .Initialize.
20 Queremos poner el cohete
en el margen de abajo de la pantalla, pero tenemos el inconveniente de
que nuestra aplicación puede funcionar en muchos tipos distintos de
dispositivos (móviles, tablets, etc) y cada uno de ellos tendrá un
tamaño de pantalla distinto, por lo tanto tenemos que buscar una manera
de saber siempre cuál es el tamaño de la pantalla en la que está
funcionando nuestra aplicación. Para ello tenemos dos bloques dentro del
componente Canvas que se llaman Canvas.Height (alto) y Canvas.Width
(ancho) que nos dicen el alto y ancho del lienzo en cada momento. Esto
es importante también si el usuario cambia la orientación de la pantalla
en algún momento puesto que cambiará también el tamaño del lienzo. En
nuestro caso hemos desactivado la posibilidad de que el usuario lo haga,
pero esta sería la forma de hacerlo.
21 Como queremos colocar
nuestro cohete centrado en la pantalla, lo primero que tenemos que hacer
es fijar su propiedad cohete.X a la mitad del ancho del lienzo
(Canvas.Width / 2). Primero coge un bloque numérico de división "/" y
pégalo al bloque "set cohete.X to".
22 Ahora coge un bloque
Canvas.Width y ponlo como primer argumento de la división. El segundo
argumento será un 2. De esta manera conseguimos centrar el cohete.
23 Como el ancho de la
imagen del cohete (sprite) es 50. Su centro sería 25. Para centrar con
precisión el cohete en la pantalla habría que restar al cálculo anterior
estos 25 pixeles adicionales. Es decir el bloque "set cohete.X to"
sería igual a
[ (canvas.Width / 2) - 25] así:
No lo hagas ahora si no quieres, pero tenlo en cuenta en tus futuros proyectos.
24 Una vez centrado en el
eje horizontal ahora toca colocar el cohete en el margen inferior de la
pantalla, por lo que vamos a utilizar un truco parecido al anterior.
Como sabemos el tamaño vertical del lienzo, porque lo tenemos en la
propiedad Canvas.Height (Alto), basta con asignar este valor al cohete
en su coordenada Y. Así lo colocamos siempre al final del lienzo, sea
cual sea su tamaño.
25 Ya tenemos nuestro cohete
colocado en la posición inicial, ahora sólo queda que cuando llegue al
borde superior de la pantalla el cohete vuelva a su posición original.
Para detectar si un sprite ha llegado al borde de la pantalla tenemos un
evento llamado EdgeReached (Borde alcanzado). Este evento lo
encontrarás dentro de cada sprite que uses en tu programa. En nuestro
caso vamos a usar el del cohete. Selecciona el componente cohete y coge
el evento cohete.EdgeReached.
26 Verás que aparece una
propiedad (argumento) llamado edge (borde) que nos indica el borde al
que ha llegado el cohete. En este caso no lo vamos a usar.
27 Ya sabemos que este
evento se va a activar cuando nuestro cohete llegue al borde de la
pantalla. Sólo nos queda que cuando esto ocurra volvamos a situar el
cohete en su posición inicial, tal y como hemos hecho anteriormente en
el evento .Initialize. Coge un bloque "set cohete.Y to" y ponlo dentro
de este evento.
28 Ahora tenemos que tener
en cuenta un detalle importante. Al colocar de esta manera el cohete lo
que ocurre es que lo estamos poniendo en el mismo borde. Por lo tanto el
evento cohete.EdgeReached se va a activar de nuevo. Es decir, el cohete
siempre estará tocando el borde, por lo que el evento se activará de
forma continua y el cohete no se moverá porque entraremos en bucle
infinito. Para que entiendas esto mejor, haz lo siguiente: Dentro del
componente Canvas coge el bloque Canvas.Height y pégalo al bloque "set
cohete.Y". ¿Ves qué ocurre? El cohete no se mueve, ¿verdad? ¿Comprendes
lo que está ocurriendo? Vamos a repasarlo de nuevo.
29 El cohete está en el
borde, por lo tanto el evento cohete.EdgeReached se activa. Dentro del
evento hemos dicho que si llega al borde lo coloque de nuevo en la
posición canvas.Height que es el tamaño máximo del lienzo y es, por lo
tanto, el borde, con lo cual el evento se vuelve a activar. Al activarse
volvemos a colocar el cohete en el borde y así indefinidamente. ¿Cómo
lo solucionamos? Basta con que coloquemos el cohete un poco antes del
borde, de esta manera el evento no se activará. Como el tamaño del
sprite del cohete es 50 x 50, basta con que restemos el tamaño del
cohete (50) del borde. Es decir "set cohete.Y to" = (canvas.Height -
50). Así:
De esta forma estamos colocando el cohete 50 pixeles antes
del borde inferior y el evento no se activará más en este caso. Sin
embargo, al llegar al borde superior, el evento se vuelve a activar,
poniendo el cohete en su posición correcta. Haciéndolo así tu cohete
debería de despegar y volver a su posición original de forma continua.
Aunque podríamos saber cuál es el bloque contra el que
está chocando (parámetro edge del evento .EdgeReached) así nos ahorramos
un poco de trabajo.
Animando la luna
30 Ahora vamos con la luna. Vuelve al Diseñador y selecciona el componente ImageSprite2.
31 Vamos a cambiar sus propiedades. Para empezar cambia el nombre del componente y llámalo "luna".
32 Ahora cambia el valor de
la propiedad Heading y pon 0. Recuerda que un valor de 0 significa que
queremos que la imagen se mueva desde la izquierda hacia la derecha.
33 Cambia el intervalo de tiempo (Interval) a 100 y para la imagen (Picture) selecciona la imagen luna.png. Cambia la velocidad (speed) por 10 y el tamaño del sprite (imagen) por 50 x 50.
34 Ahora sitúa la imagen de la luna con el ratón arriba de la pantalla.
35 Vuelve al Editor de bloques.
36 Ahora la luna se mueve
por la pantalla desde la izquierda hacia la derecha y se detiene al
llegar al borde. Lo que vamos a aprender ahora es a hacer que una imagen
rebote cuando llega a un borde. Para empezar necesitamos el mismo
bloque evento que usamos antes para detectar cuando un sprite toca un
borde. Selecciona el componente luna y coge el evento luna.EdgeReached.
37 Ahora el bloque que
necesitamos para que un sprite rebote se llama "call luna.Bounce"
(rebotar). Cógelo y ponlo dentro del evento luna.EdgeReached.
38 Recuerda que el evento
.EdgeReached nos dice cual es el borde que ha tocado nuestra imagen a
través del parámetro edge. Así que tenemos que usar ese parámetro
también en el bloque .Bounce. Pega este parámetro al bloque luna.Bounce y
tu luna debería de rebotar de un lado a otro de la pantalla. ¿Funciona?
Añadiendo interactividad
39 Ya
tenemos dos sprites moviéndose por la pantalla, ahora vamos a añadirle
interactividad, es decir, la posibilidad de controlarlos de alguna
manera. Como nuestros dispositivos tienen sensores de movimiento, vamos a
controlar nuestro cohete inclinando nuestro móvil o tablet. Para esto
hemos añadido el componente OrientationSensor antes. Selecciona este
componente y coge el evento OrientationSensor.OrientationChanged.
Este evento nos dice si hemos movido el dispositivo y en
concreto nos dice si lo hemos inclinado en alguna dirección. Aunque lo
veremos en detalle más adelante de momento nos interesa el parámetro
"roll" que es el que nos indica la inclinación del dispositivo y la
dirección. Si inclinamos hacia la izquierda el valor de roll será
negativo y si lo inclinamos hacia la derecha el valor de roll será
positivo. Cuanto más inclinamos en una dirección u otra el valor de rol
será mayor o menor. Vamos a ver cómo usarlo.
40 Como queremos mover el
cohete inclinando nuestro dispositivo lo primero que necesitamos es el
bloque cohete.MoveTo. Cógelo y ponlo dentro del evento
OrientationChanged que acabamos de usar.
41 Ahora tenemos que decirle
al cohete cuáles son las coordenadas a las que queremos que se mueva.
Recuerda que las coordenadas actuales del cohete, es decir, su posición
en todo momento, las tenemos en las propiedades cohete.X y cohete.Y.
Como el cohete se mueve por sí mismo de abajo hacia arriba, la
coordenada Y no la vamos a tocar y vamos a dejar la que tenga en cada
momento. Busca la propiedad cohete.Y y ponla en el bloque .MoveTo.
42 Ahora la coordenada X, es
decir, la posición horizontal del cohete es la que queremos manejar
inclinando el dispositivo. Basta con que sumemos a la coordenada actual
cohete.X el valor de roll. Pega al valor de x del bloque .MoveTo la suma
de la propiedad cohete.X más roll. Así:
43 Ahora deberías poder controlar tu cohete inclinando el dispositivo. ¿Funciona?
44 Por último queremos que
cuando nuestro cohete toque la luna sumemos un punto a nuestro marcador.
Es decir, cada vez que consigamos llevar el cohete a la luna ganamos un
punto. Para detectar cuando un sprite toca a otro tenemos un
evento llamado .CollideWith (colisiona con..). Para nuestro ejemplo
podríamos usar el evento CollideWith tanto de la luna como del cohete
puesto que el uno toca al otro indistintamente. Vamos a usar el evento
del cohete. Busca el evento cohete.CollideWith y ponlo en tu programa.
45 Verás que el evento nos
pasa un parámetro llamado "other" que nos dice contra qué otro sprite
nos hemos tocado. Para este caso no vamos a usarlo puesto que ya sabemos
que sólo podemos haber chocado contra la luna. Ahora dentro de este
evento vamos a sumar un punto a nuestro marcador. Selecciona el
componente marcador y coge el bloque "set marcador.Text to".
46 Como en el Diseñador
habíamos puesto un valor de 0 a nuestro marcador, ahora sólo tenemos que
sumarle un punto más. Coge un bloque suma y como primer parámetro usa
el bloque marcador.Text porque es donde tenemos guardado el valor de
nuestro marcador.
47 Como segundo valor de la suma pon un 1. Así vamos sumando un punto más cada vez que nuestro cohete llegue a la luna.
48 Finalmente tenemos que
volver a poner el cohete en su posición original, de lo contrario
nuestro cohete al tocar la luna la atravesaría sin más. Puedes duplicar
el bloque "set cohete.Y to" que usamos dentro del evento
cohete.EdgeReached para hacer esto. El programa final quedaría así:
Ya tenemos nuestra pequeña aplicación terminada y funcionando. ¿Te atreves a añadirle sonidos?
Más información:
Más información: