Академический Документы
Профессиональный Документы
Культура Документы
DÍA 2
Introducción
Bienvenido al segundo dı́a del taller Programa Tus Ideas.
Los juegos y las aplicaciones de fuerte contenido audiovisual pueden ser una forma muy
apropiada de introducir a tus alumnos a los conceptos básidos de la programación en el Taller
de Aplicaciones. De hecho, una gran cantidad de las aplicaciones móvilles más populares hoy
en dı́a son juegos. El dı́a de hoy veremos cómo programar este tipo de aplicaciones en App
Inventor.
Comenzaremos a trabajar con el componente Lienzo, que permite dibujar lı́neas y cı́rculos,
y mostrar imágenes y animaciones. En el primer tutorial desarrollarás una aplicación estilo
“Paint”, donde puedes tomar una foto con la cámara y luego editarla usando lı́neas, cı́rculos y
distintos colores. Luego, aprenderás a programar animaciones básicas implementado el juego
Atrapa el Topo, inspirado por el clásico juego mecánico del mismo nombre. En tercer
lugar, presentamos un breve tutorial para programar el clásico juego Pong .
El resto de este documento consiste en material de apoyo sobre los siguientes conceptos
fundamentales: el componente Lienzo, el uso de temporizadores, y cómo programar usando
variables (donde se enseña el concepto de variables locales). En conjunto, estos componentes
de AppInventor permiten programar juegos bastante sofisticados.
1
1. tutorial: pintafotos
1. Tutorial: PintaFotos
En este tutorial presentaremos el componente Lienzo para crear aplicaciones con gráficos
y animaciones simples en 2 dimensiones (2D). Construiremos la aplicación PintaFotos que
permite al usuario dibujar en la pantalla usando distintos colores, usando una imagen de
fondo y dibujando sobre ella.
Un dato histórico: PintaFotos fue uno de los primeros programas desarrollados para
demostrar el potencial de los computadores, en la decada de 1970. En aquel entonces, hacer
algo tan simple como esta aplicación de dibujo era algo muy complejo, y los resultados
no eran perfectos. Pero ahora, con AppInventor, cualquiera puede rápidamente armar una
aplicación de dibujo bastante buena, lo que sirve de excelente punto de partida para luego
hacer juegos 2D.
La interfaz de usuario de PintaFotos se muestra en la Figura 1.1.
2
1. tutorial: pintafotos
Tocar la pantalla para hacer puntos.
Sacar una foto con la cámara y luego dibujar encima de esta foto.
Qué Aprenderás
Siguiendo este tutorial aprenderás a:
Definir variables para recordar cosas como el tamaño de un punto elegido por el usuario
para dibujar.
Para Empezar
Asegúrate que tu computador y teléfono están configurados para usar AppInventor. Crea
un nuevo proyecto y nómbralo PintaFotos. Abre el Editor de Bloques y comprueba que
puedes probar tu aplicación en tu dispositivo mediante la conexión USB. Consulta con tu
tutor ante cualquier problema.
Para empezar, ve al panel de propiedades a la derecha del Diseñador y cambia el tı́tulo
de la pantalla a “PintaFotos”. Deberı́as ver este cambio reflejado en el teléfono, con el nuevo
tı́tulo apareciendo en la barra de tı́tulos de tu app.
Si estás preocupado por confundir el nombre de tu proyecto con el nombre de la pantalla,
¡no te preocupes! Hay tres nombres claves en AppInventor:
El nombre que eliges para tu proyecto mientras trabajes en él. También será el nombre
de la aplicación cuando la quieras publicar. Nota que puedes hacer click en “Archivo”
y seleccionar “Guardar Como” en el Diseñador para crear una nueva versión o cambiar
el nombre de un proyecto.
3
1. tutorial: pintafotos
El nombre de la componente, Screen1, que verás en el panel que contiene el listado
de los componentes de la app. No puedes cambiar este nombre en esta versión de
AppInventor.
El tı́tulo de la pantalla, él que ves en la barra de tı́tulo del teléfono. Empieza siendo
Screen1, que es el tı́tulo que usaste en HolaGatito. Pero lo puedes cambiar, como
lo hicimos en PintaFotos.
Tres componentes Botón para seleccionar pintura roja, azul o verde y un componente
DisposiciónHorizontal para organizarlos.
Un componente Botón para limpiar el dibujo, y otros dos para cambiar el tamaño de
los puntos.
Un componente Lienzo, que es la superficie para dibujar. El Lienzo tiene una pro-
piedad ImagenDeFondo, que configuraremos como gatito.png desde el tutorial Hola
Gatito. Más adelante, modificarás la app para que la imagen de fondo pueda ser una
foto sacada por el usuario.
De la misma manera, crea dos botones adicionales para azul y verde, nombrados
BotónAzul y BotónVerde respectivamente. Ponlos debajo del botón rojo. Chequea
tu trabajo comparándolo con la Figura 1.2.
4
1. tutorial: pintafotos
¡Importante! Observa que en este proyecto cambias los nombres de los componentes en vez
de dejarlos con sus nombres por defecto, como lo hiciste en Hola Gatito. El usar nombres
más significativos hace que tus proyectos sean más fáciles de leer, y realmente ayuda en el
momento de pasar al Editor de Bloques cuando tendrás que referirte a los componentes por
su nombre. A partir de ahora y en el resto del taller usaremos la convención de que cada
nombre de componente empiece por su tipo (por ejemplo: BotónRojo).
Ahora deberı́as tener tres botones alineados verticalmente. Sin embargo para esta app,
vas a necesitar que estén en fila horizontal arriba de la pantalla, como en la Figura 1.3. Para
ello debes usar el componente DisposiciónHorizontal.
5
1. tutorial: pintafotos
1. Desde la categorı́a “Disposición” en la Paleta, arrastra un componente DisposiciónHo-
rizontal y ponlo debajo de los botones.
3. Mueve los tres botones uno después del otro al interior de la DisposiciónHorizon-
tal. Truco: Verás una lı́nea vertical azul que indica dónde irá el elemento que estás
arrastrando.
Si miras en la lista de componentes del proyecto, verás tres botones listados bajo el
componente DisposiciónHorizontal, lo que muestra que se trata de sus subcomponentes.
Asimismo, observa que todos los componentes están listados bajo el componente Screen1.
¡Prueba tu Aplicación! Deberı́as ver tus tres botones en una fila horizonal en la pantalla,
a pesar de que puedan verse un poco diferente a como se ven en el Diseñador. Por ejemplo,
el borde de DisposiciónHorizontal no aparece en el dispositivo.
En general, se usan los componentes de “Disposición” como opciones de diseño para crear
disposiciones simples, verticales, horizontales o en tablas. También puedes crear disposiciones
más complejas insertando componentes de disposición unos dentro de otros.
Agregar el Lienzo
6
1. tutorial: pintafotos
Cambia el ColorDePintura en el LienzoDeDibujo al color rojo para que cuando
el usuario inicie la app pero todavı́a no ha presionado ningun botón, sus dibujos sean
rojos. Comprueba si lo que has hecho es parecido a la Figura 1.4.
2. Luego arrastra dos componentes Botón adicionales en el Visor y ponlos dentro del
DisposiciónHorizontal que acabas de agregar. Cambia el nombre del primer botón
por BotónCámara y su Texto a “Sacar Foto”. Cambia el nombre del segundo botón
por BotónLimpiar y su Texto por “Limpiar”.
7
1. tutorial: pintafotos
5. Desde la sección Medios de la Paleta, arrastra un componente Cámara hacia el Visor.
Aparecerá en la sección de los componentes no-visibles.
Una vez completados estos pasos, tu aplicación deberı́a verse como en la Figura 1.5.
¡Prueba tu Aplicación! ¿Aparece la foto del gatito debajo de los botones de la primera
fila? ¿Aparece la última fila de botones abajo?
8
1. tutorial: pintafotos
En el Diseñador, agregaste un componente Lienzo llamado LienzoDeDibujo. Como
todos los componentes de ese tipo, LienzoDeDibujo tiene un evento Tocar y un evento
Arrastrado. Programarás el evento LienzoDibujo.Tocar de tal manera que llame a la fun-
ción LienzoDibujo.DibujarCı́rculo. Programarás el evento LienzoDibujo.Arrastrado
de tal manera que llame a la función LienzoDibujo.DibujarLı́nea. Programarás luego los
botones para configurar la propiedad ColorDePintura usando el bloque poner LienzoDi-
bujo.ColorPintura, y para limpiar el LienzoDeDibujo; y finalmente, programarás como
cambiar la ImagenDeFondo del lienzo por una foto sacada con la cámara del dispositivo.
Figura 1.6: El evento viene con información sobre la ubicación del toque en la pantalla
Nota. Si completaste la aplicación Hola Gatito, ya estás familiarizado con los eventos
de Botón.Click, pero no con los eventos del lienzo. Los eventos Botón.Click son
bastante sencillos porque no hay nada más que saber del evento aparte del hecho que
ocurrió. Algunos controladores de eventos, sin embargo, vienen con información sobre
los argumentos para llamar al evento. El evento LienzoDibujo.Tocar te entrega las
coordenadas x e y del toque dentro del LienzoDeDibujo. También te dice si un
objeto dentro del LienzoDeDibujo (lo que se conoce como Sprite) fue tocado, pero
este punto se abordará más adelante. Las coordenadas x e y son los argumentos que
usaremos para grabar dónde el usuario tocó la pantalla, de manera de poder dibujar
el punto en este lugar.
9
1. tutorial: pintafotos
2. Arrastra un bloque LienzoDeDibujo.DibujarCı́rculo desde el bloque y ponlo dentro
del controlador de eventos LienzoDeDibujo.Tocar, como se ilustra en la Figura 1.7.
10
1. tutorial: pintafotos
Figura 1.8: Para acceder al parámetro de un evento, arrastra un bloque tomar desde el
bloque LienzoDeDibujo.Tocar
Figura 1.9: La aplicación sabe donde dibujar (x,y), pero todavı́a necesitamos especificar cuán
grande deberı́a ser el cı́rculo.
4. Ahora necesitas especificar el radio del cı́rculo a dibujar. El radio se mide en pixeles,
que es el punto más pequeño que puede ser dibujado en la pantalla. Por ahora, ponle
como valor el número 5: haz click en una zona blanca de la pantalla y tipea 5, luego
presiona Enter para crear automáticamente un bloque numérico, y conecta este bloque
en el espacio para el parámetro r. Cuando hagas esto, el signo amarillo en la esquina
inferior se pondrá en 0 nuevamente, dado que todos los espacios abiertos habrán sido
completados. La Figura 1.10 muestra como debiera verse el controlador de eventos
LienzoDeDibujo.Tocar.
11
1. tutorial: pintafotos
Figura 1.10: Cuando el usuario toca el LienzoDeDibujo, un cı́rculo de radio 5 será dibujado
en las coordenadas (x, y) correspondientes.
Un touch es cuando pones tu dedo en la pantalla y solo lo levantas para tocar, sin
desplazarlo.
12
1. tutorial: pintafotos
pequeñas lı́neas rectas; cada vez que mueves tu dedo, incluso un poco, extiendes la lı́nea
desde la última posición de tu dedo hacia su nueva posición.
Figura 1.11: Un evento de arrastre tiene más argumentos que un evento de touch.
13
1. tutorial: pintafotos
LienzoDeDibujo.Arrastrado se activará cada vez que arrastres tu dedo en el Visor,
por lo tanto la aplicación dibuja una pequeña lı́nea cada vez que mueves tu dedo, desde
(XPrevio, YPrevio) hacia (XActual, YActual). Agreguemos esto a nuestro bloque
LienzoDeDibujo.DibujarLı́nea:
3. Arrastra los bloques tomar para los argumentos que vas a necesitar. Los valores
XPrevio e YPrevio deberı́an ir conectados en los espacios para los argumentos x1
e y1, respectivamente, como se ilustra en la Figura 1.13.
Figura 1.13: Cuando el usuario arrastre el dedo, la aplicación dibujará una lı́nea desde el
punto anterior hacia el actual.
La aplicación que has construido hasta ahora permite al usuario dibujar, pero siempre
estos dibujos usan el color rojo. El próximo paso consiste en agregar controladores de eventos
para los botones de colores, para que el usuario pueda cambiar el color de la pintura, y otro
para el BotónLimpiar para que pueda limpiar la pantalla y ası́ volver a empezar a dibujar.
En el Editor de Bloques:
3. Abre la sección “Colores” y arrastra el bloque de color rojo para conectarlo con el
bloque poner LienzoDeDibujo.ColorDePintura.
14
1. tutorial: pintafotos
4. Repite los pasos anteriores para los botones azul y verde.
Figura 1.14: Cuando el usuario hace click en los botones de colores cambia el color para
dibujar en el lienzo. Hacer click en “Limpiar”, borra el contenido del lienzo.
Las aplicaciones hechas con AppInventor pueden interactuar con las funcionalidades de
los dispositivos Android, incluyendo la cámara. Para personalizar la aplicación, se permite
al usuario fijar la imagen de fondo de su dibujo con una foto tomada con la cámara.
15
1. tutorial: pintafotos
4. Arrastra el bloque poner LienzoDeDibujo.ImagenDeFondo y ponlo en las acciones
de Cámara1.DespuésDeTomarFoto.
Figura 1.15: Cuando se saca la foto, se configura como la imagen de fondo del lienzo.
¡Prueba tu Aplicación! Haz una prueba al hacer click en “Tomar Foto” y saca una
foto. El gatito deberı́a cambiar por la foto que acabas de sacar, y luego podrás dibujar
encima de la foto que sacaste.
16
1. tutorial: pintafotos
Para usar distintos valores en el argumento radio, la aplicación necesita saber cuál que-
remos aplicar. Necesitamos pedirle usar un valor especı́fico, y tiene que memorizar este valor
de manera a poder seguir usándolo. Cuando tu aplicación necesita guardar algo en memoria
que no sea una propiedad, puedes definir una variable. Una variable es una celda de memoria.
Es como un balde donde puedes almacenar datos variables, como el tamaño del punto.
Empezamos por definir una variable Tama~
noPunto:
2. Fı́jate que el bloque Inicializar global TamañoPunto tiene un espacio abierto. Ahı́
es donde puede especificar el valor inicial de la variable, o su valor por defecto al iniciar
la aplicación. Para esta aplicación, inicializa el Tama~
noPunto en 2 creando un bloque
con el número 2, y conectándolo en Inicializar global TamañoPunto como se ilustra
en la Figura 1.16.
17
1. tutorial: pintafotos
Figura 1.17: Ahora el tamaño de cada cı́rculo depende de lo que está guardado en la memoria
de la variable TamañoPunto.
Figura 1.18: Hacer click en los botones cambia el tamaño del punto. Los toques que siguen
serán con este tamaño de punto.
¡Prueba tu Aplicación! Intenta hacer click en los botones de tamaño y luego toca el
lienzo. ¿Se dibujan cı́rculos de distintos tamaños? ¿Las lı́neas? El tamaño de las lı́neas no
18
1. tutorial: pintafotos
deberı́a cambiar porque programaste Tama~
noPunto solamente para ser usado en el bloque de
DibujarCı́rculo. En base a esto, ¿podrı́as ahora cambiar tus bloques para que el usuario
también pueda cambiar el tamaño de la lı́nea? (Nota que el lienzo tiene una propiedad
llamada AnchodeLinea)
Resumen
Las ideas claves que hemos visto en este tutorial son las siguientes:
Algunos controladores de eventos vienen con información sobre el evento, como las
coordenadas de donde la pantalla fue tocada. Esta información está representada por
19
2. discusión y ejercicios de personalización
argumentos. Cuando arrastras un controlador de eventos que tiene argumentos, Ap-
pInventor crea ı́tems “poner a” y “tomar”, dentro del bloque seleccionado, para ası́
poder referirse a estos argumentos.
Crear variables al usar bloques poner global nombre, desde la categorı́a “Variables”.
Las variables permiten guardar información en memoria, como el tamaño del punto,
que no está guardado en una propiedad de un componente.
Para cada variable que definas, AppInventor automáticamente provee una referencia
“tomar global” que entrega el valor de la variable, y una referencia “poner global a”
para cambiar el valor de la variable. Para acceder a esto, arrastra un bloque “poner a”
o “tomar” desde el mismo bloque donde declaras la variable.
El componente Lienzo también se puede usar para programar animaciones como las que
ves en juegos en 2D.
20
2. discusión y ejercicios de personalización
2. Los parámetros de evento son distintos de los parámetros para llamar funciones. ¿Cómo
se llaman los parámetros para llamar funciones en el controlador de eventos de la ???
¿Quién especifica los parámetros de función? Quién especifica parámetros de eventos?
3. ¿Cuál es el propósito de definir una variable para el Tamaño de Punto en la App Pinta
Fotos? Si quieres permitir cambiar el grosor de las lı́neas, ¿necesitarás una variable?
4. Define lo que es una variable. ¿Cuáles son sus puntos en común con una propiedad?
¿Cómo se diferencia de una propiedad?
Ejercicios de Personalización
1. La interfaz de usuario de PintaFoto no permite mostrar con qué color se está dibu-
jando. El usuario sólo se da cuenta al dibujar. ¿Puedes agregar esta información para
el usuario de tal manera que cuando él hace click para cambiar el color, la interfaz
cambia y le indica qué color fue elegido?
2. El tamaño del punto para dibujar un cı́rculo sólo puede ser de 2 o 8. ¿Puedes cam-
biar esto para permitir al usuario elegir entre distintas opciones con un componente
Deslizador o un CampoDeTexto?
3. Permitir al usuario controlar el grosor de las lı́neas, de la misma manera que pue-
de cambiar el tamaño del punto. El lienzo tiene una propiedad AnchoDeLinea que
controla esta caracterı́stica.
21
3. tutorial: atrapa el topo
3. Tutorial: Atrapa el Topo
En este tutorial desarrollarás el juego Atrapa el Topo, inspirado en las salas de juegos
clásicas, en las que unos topos mecánicos saltan fuera de su hueco, y los jugadores ganan
puntos golpeándolos con un mazo. El juego fue creado por Ellen Spertus, un miembro del
equipo de AppInventor en Google, para implementar la funcionalidad Sprite. El término
Sprite apareció en la comunidad de informáticos en los años 70, y se referı́a a imágenes
capaces de moverse en la pantalla de un computador (para videojuegos).
Qué Construirás
Para la aplicación Atrapa el Topo, ilustrada en la Figura 3.1, implementarás las si-
guientes funcionalidades:
Tocar el topo hace vibrar el teléfono, y aumenta el marcador de puntos (un punto por
topo tocado), y el topo se mueve de inmediato a otro lugar.
Tocar la pantalla sin alcanzar a tocar el topo provoca que el marcador de toques
perdidos aumente.
22
3. tutorial: atrapa el topo
Qué Aprenderás
Este tutorial cubre los siguientes componentes y conceptos:
El componente Lienzo que funciona como una superficie sobre la cual se pone el
SpriteImagen.
23
3. tutorial: atrapa el topo
Procedimientos para implementar comportamientos repetitivos, como desplazar el to-
po.
Para empezar
Conéctate al sitio de AppInventor y crea un nuevo proyecto. Llamálo “AtrapaElTopo” y
también cambia el tı́tulo de la pantalla como “AtrapaElTopo”. Abre el Editor de Bloques y
conéctate a tu dispositivo Android.
Descarga la imagen ProgramaTusIdeas/Dia2/topo.png. Luego vé a la sección de Medios
del Diseñador de Componentes y súbela a AppInventor.
Un SpriteImagen que representa la foto del topo y que puede moverse y sentir cuando
el topo fue tocado.
Un Reloj para hacer que el topo se desplace una vez por segundo.
24
3. tutorial: atrapa el topo
Ubicar los Componentes de Acción
En esta sección crearemos los componentes necesarios para que funcione el juego. En la
siguiente sección, crearemos los componentes para mostrar el marcador de puntos.
Tu pantalla deberı́a verse como en la Figura 3.2 (aunque tu topo puede estar en una
posición distinta).
25
3. tutorial: atrapa el topo
Ahora pondremos los componentes para mostrar el marcador de puntos del usuario, más
especı́ficamente los golpes exitosos y fallidos.
26
3. tutorial: atrapa el topo
puntos).
Cambia el nombre de la etiqueta derecha por “EtiquetaPuntosGanados” y confi-
gura su Texto como “0”.
27
3. tutorial: atrapa el topo
Agregar comportamientos a los componentes
Luego de crear los componentes anteriores, tienes que ir al Editor de Bloques para im-
plementar el comportamiento del programa. En particular, queremos que el topo se mueva
cada segundo de manera aleatoria en el lienzo. El objetivo del jugador es pegar al topo donde
aparezca, y la aplicación mostrará el número de veces que el jugador logró tocar o no al topo.
Pinchar en el botón “Reinicializar”, reinicializa el marcador.
Desplazar el Topo
En los programas que creaste hasta ahora, usaste procedimientos preexistentes como el
vibrador en Hola Gatito. Serı́a maravilloso poder tener un procedimiento que mueve un
SpriteImagen de forma aleatoria en la pantalla! La mala noticia es que no existe! La buena
noticia: puedes crear tus propios procedimientos! Como los preexistentes, tu procedimiento
aparecerá en una sección y podrá ser usado en cualquier lugar de la app.
En particular, crearemos un procedimiento para mover el topo a un lugar aleatorio en la
pantalla, que llamaremos MoverTopo. Vamos a activar MoverTopo al inicio del juego, cuando
el usuario logra tocar el topo, y una vez por segundo.
Para comprender cómo mover el topo, necesitamos ver cómo funcionan los gráficos de
Android.
El lienzo (y la pantalla) son como una cuadrı́cula con coordenadas x (horizontal) e y (ver-
tical), donde las coordenadas (x,y) de la esquina superior izquierda son (0,0). El x aumenta
cuando mueves hacia la derecha, y la y aumenta cuando vas hacia abajo, como se ilustra en
la Figura 3.4. Las propiedades X e Y de un SpriteImagen indican dónde deberı́a estar su
esquina superior izquierda; es decir, el topo en la esquina superior izquierda tiene valores de
0 para X e Y.
Para determinar los valores máximos para X e Y de tal manera que el topo no se salga
de la pantalla, necesitamos estar seguros de usar las propiedades Ancho y Alto del Topo
y del Lienzo1. Las propiedades de Ancho y Alto del Topo son las mismas que el tamaño
de la foto que subiste. Cuando creaste el Lienzo1, configuraste su Alto a 300 pixeles y su
Ancho a “Ajustar al Contenedor”). Si el Topo tiene un Ancho de 36 pixeles y el Lienzo
200, la coordenada X del lado izquierdo del topo puede ir hasta 0 (borde izquierdo) o con
28
3. tutorial: atrapa el topo
un alto de hasta 164 (200 - 36, o Lienzo1.Ancho − Topo.Ancho) sin que el topo pase el
borde derecho de la pantalla.
De forma similar, la coordenada Y del lado superior del topo puede ir desde 0 hasta
Lienzo1.Alto − Topo.Alto.
Figura 3.4: Posiciones del topo en la pantalla, con información de ancho, coordenadas y
altura. La información de la coordenada x está en azul, y la de la coordenada y está en
naranjo.
Para dar una posición aleatoria al topo, vamos a seleccionar una coordenada X entre
0 y Lienzo1.Ancho − Topo.Ancho. Ası́mismo, la coordenada Y tiene que estar en un
rango de entre 0 y Lienzo1.Alto − Topo.Alto. Podemos generar un número aleatorio
con el procedimiento preexistente entero aleatorio entre, que se encuentra en la sección
“Matemáticas”. Tendrás que cambiar los parámetros como se muestra en la Figura 3.5.
La figura muestra además comentarios descriptivos que puedes opcionalmente agregar a tu
procedimiento.
29
3. tutorial: atrapa el topo
Figura 3.5: El procedimiento MoverTopo, que pone el Topo en una ubicación aleatoria.
4. Dado que queremos mover el topo, arrastra dentro del procedimiento el bloque lla-
mar Topo.MoverA, a la derecha de “ejecutar”. Observa que se requiere indicar las
coordenadas x e y donde se moverá el topo.
5. Para especificar que la nueva coordenada x para el topo deberı́a ser entre 0 y Lienzo1.Ancho−
Topo.Ancho, debes hacer lo siguiente:
30
3. tutorial: atrapa el topo
Selecciona la sección “Matemáticas” y arrastra un bloque de resta (-) al espacio
de trabajo.
Selecciona el bloque Lienzo1.Ancho y arrástralo al argumento izquierdo del
bloque de resta.
De manera muy similar, arrastra el bloque Topo.Ancho hacia el argumento
derecho del bloque de resta.
Sigue un procedimiento similar para especificar que la coordenada y, que deberı́a ser
un entero aleatorio entre 0 y Lienzo1.Alto − Topo.Alto.
Compara tus resultados con lo ilustrado en la Figura 3.5 que está más arriba.
Ahora que escribiste el procedimiento MoverTopo, ¡usémoslo! Es muy común que los
programadores quieran que pase algo cuando se inicia la aplicación, y es por eso que hay un
bloque para esto: Pantalla1.Inicializar.
Hacer que el topo se mueva cada 1 segundo requiere que usemos el componente Re-
loj. Dejamos la propiedad IntervaloDelTemporizador en su valor por defecto de 1000
milisegundos (o sea 1 segundo). Esto significa que cada 1 segundo se ejecutará un evento
Reloj1.Temporizador. Estos eventos los usaremos para mover el topo cada 1 segundo, de
la siguiente manera:
31
3. tutorial: atrapa el topo
1. Selecciona la sección Reloj1, y arrastra el controlador de eventos Reloj1.Temporizador
hacia el espacio de trabajo.
Figura 3.7: Procedimiento para llamar a MoverTopo cada 1 segundo, cada vez que se activa
el temporizador.
Llevar el Puntaje
Figura 3.8: Se incrementa el número de éxitos o fallidos cuando el lienzo está tocado.
32
3. tutorial: atrapa el topo
el Topo es tocado, suma 1 al número en EtiquetaPuntosGanados.Texto; sino, suma 1 al
número en EtiquetaPuntosFallados.Texto. El valor de SpriteTocado es falso si ningun
sprite fue tocado.
Los bloques se crean de la siguiente manera:
3. Arrastra un bloque tomar SpriteTocado, y ponlo en el espacio abierto del bloque si.
Abstracción procedural
33
3. tutorial: atrapa el topo
Se llama abstracción porque el que llama el procedimiento (quien, en el mundo real, por
lo general es una persona distinta a la que es el autor del procedimiento) solamente necesita
saber qué hace el procedimiento (mover el topo), pero no cómo lo hace (al hacer dos llamados
al generador de números aleatorios). Sin la abstracción procedural, grandes programas de
computación no serı́an posibles porque contienen demasiado código para que lo memorice
una sola persona. Se puede hacer una analogı́a con la división del trabajo en una planta por
ejemplo, donde distintos ingenieros diseñan diferentes partes de un auto, ninguno de ellos
entendiendo todos los detalles, y el conductor sólo tiene que comprender la interfaz (por
ejemplo apretar el freno para detener el auto), y no toda la ingenierı́a que hay por detrás.
Algunas ventajas de la abstracción procedural en comparación con copiar y pegar código
son:
Es más fácil probar el código si está nı́tidamente separado del resto del programa.
Para cambiar el desarrollo, como por ejemplo programar que el topo no se mueva al
lugar donde justo estuvo antes, solamente modificas el código en un lugar.
Los procedimientos pueden ser juntados en una librerı́a y usados en distintos programas
(aunque no se puede hacer esto todavı́a con AppInventor).
Elegir buenos nombres para los procedimientos ayuda a documentar el código, ha-
ciéndolo más fácil de leer para otra persona que lo tomará después.
Reinicializar el Puntaje
En una aplicación como esta, es razonable pensar que habrá más de un usuario. Por
lo tanto, es bueno tener una manera de reinicializar el marcador de puntos en 0. Puede
ser que logres hacer esto sin leer estas indicaciones. Intenta hacerlo solo antes de leer las
instrucciones.
34
3. tutorial: atrapa el topo
Lo que necesitamos es un bloque BotónReinicializar.Click que ponga el marcador
de EtiquetaPuntosGanados.Texto y EtiquetaPuntosFallidos.Texto en 0. Crea los
bloques de la misma manera que en la Figura 3.9.
En esta etapa del taller, no deberı́as necesitar instrucciones paso a paso para crear un
controlador de eventos que responde al click de un botón, pero aquı́ va un consejo para
acelerar el proceso: en vez de sacar tu número de la sección “Matemáticas”, solamente tipea
0, y el bloque deberı́a crearse. (Estos atajos existen para otros bloques también.)
Dijimos antes que queremos que vibre el dispositivo cuando se toca el topo, lo que pode-
mos hacer con el bloque Sonido1.Vibrar, como se ve en la Figura 3.10.
La Figura 3.11 muestra cómo se ven los bloques para la versión completa de Atrapa el
Topo.
35
3. tutorial: atrapa el topo
Variantes
Aquı́ vienen algunas ideas para agregar más funcionalidades a Atrapa el Topo:
Agregar una etiqueta para recordar y mostrar cuántas veces apareció el topo.
Agregar un segundo SpriteImagen con una foto de algo que el jugador NO deberı́a
tocar, como una flor o una bomba por ejemplo. Si lo toca, será penalizado con puntos
o puede que termine el juego.
En vez de usar la foto de un topo, deja que el usuario seleccione una foto con el
componente SelectorDeContacto.
36
4. animaciones usando sprites
4. Animaciones Usando Sprites
Ejemplo 2: ¿Cómo hacer rebotar una pelota? AppInventor tiene un bloque Botar
que provoca que una pelota rebote en el borde del lienzo. Tı́picamente se usa Botar dentro
37
4. animaciones usando sprites
del controlador de eventos Pelota.TocarBorde, dado que este controlador de eventos indica
cual borde ha sido alcanzado, como parámetro, por lo que puedes conectar este parámetro
en la función Botar—que necesita saber desde que borde rebotar.
También puedes hacer rebotar otros objetos (sprites o pelotas). El controlador de eventos
EnColisiónCon se activa cuando dos objetos chocan. Sin embargo, la función Botar sola-
mente funciona en el borde de un lienzo, ası́ que no puede usarse para colisiones en general.
Lo que sı́ puedes hacer es hacer rebotar el sprite o pelota en la dirección opuesta a la que
tenı́a antes de la colisión, configurando su Orientación como 360 menos el valor actual.
Esto se ilustra en la Figura 4.3.
Figura 4.3: Programando una Pelota para que rebote al tocar el borde, y para que invierta
su dirección al chocar con otro sprite u objeto animado.
Desafı́os Animados
Desafı́o 1: Animación Básica Para los siguientes desafı́os, necesitarás un componente
Lienzo que ocupe todo lo ancho de la pantalla y que tenga unos 300 pixeles de Alto. Agrega
un botón con texto “Iniciar!” abajo del lienzo. Crearás dos aplicaciones distintas:
38
4. animaciones usando sprites
usa sólo 1 componente Reloj y NO uses las propiedades de animación internas del
componente Pelota (velocidad etc.).
2. ¿Cómo determinar la velocidad de tus objetos cuando usas: a) una animación Sprite
b) un contador de tiempo?. Indica una fórmula para cada caso.
3. Los Cuadros por Segundo (CPS) es una medición usada en pelı́culas y animaciones.
Indica cuantas veces por segundo la pelı́cula se actualiza. ¿Qué CPS se necesita para
que el cambio no sea notado por el ojo humano? (Puedes buscarlo en Google)
5. Ejercicio de código: modifica uno de tus aplicaciones para que un objeto se mueva 50
pixeles por segundo y otro objeto se mueva a 100 pixeles por segundo.
Desafı́o 2: Ida y Vuelta Crea nuevas aplicaciones para los comportamientos siguientes:
1. Cuando se presiona un botón, una pelota hace idas y vueltas perpetuas en la pantalla.
2. Cuando se presiona un botón, una pelota se mueve haciendo idas y vueltas perpetuas
desde el borde izquierdo de la pantalla hasta la mitad de la pantalla.
39
5. tutorial: pong
5. Tutorial: Pong
En este tutorial aprenderás a programar una versión sencilla del clásico juego Pong .
Hacer este juego te ayudará a familiarizarte con la animación de sprites, a manejar colisiones,
y a definir procedimientos para que ası́ puedas programar mejor!
A diferencia de los tutoriales anteriores, en este tutorial te entregaremos un esqueleto
de la aplicación, con la interfaz de usuario ya desarrollada. Tu misión es programar los
comportamientos de los distintos elementos del juego.
La interfaz de usuario final para la aplicación se muestra en la Figura 5.1:
1. Programa una Pelota que se mueva en dirección hacia abajo. La pelota inicia su
movimiento cuando se presiona el botón “Empezar” (Figura 5.2).
40
5. tutorial: pong
Figura 5.4: La pelota rebota al tocar los bordes y al colisionar con la barra.
41
5. tutorial: pong
4. Programa la barra para que se mueva cuando el usuario arrastre el dedo. La barra sólo
se mueve horizontalmente (o sea, sólo en la coordenada X) (Figura 5.5).
Figura 5.5: La barra se mueve según el usuario arrastre el dedo sobre ella.
5. Modifica el programa para obtener 1 punto cada vez que la barra golpea la pelota. Para
esto vas a usar un procedimiento con argumentos, averigua por ti mismo, o consulta a
tu tutor al respecto (Figura 5.6).
Figura 5.6: Aumentando el puntaje cada vez que se golpea la pelota con la barra.
6. Modifica el programa para que el juego termine si la pelota choca con el borde de abajo
(Figura 5.7).
42
5. tutorial: pong
Figura 5.7: El juego termina cuando la pelota choca con el borde de abajo.
Figura 5.8: Efectos de sonido para las colisiones, toque de bordes y fin del juego.
43
5. tutorial: pong
44
6. proyecto: crea tu propio juego o aplicación
6. Proyecto: Crea tu Propio Juego o Aplicación
Crea una aplicación con animaciones similares–pero más complejas—que en el juego
Atrapa el Topo y Pong .
La aplicación debe tener las siguientes funcionalidades:
Objetos que se mueven en el tiempo (por ejemplo una nave espacial que atraviesa la
pantalla).
Objetos que se mueven o son transformados en reacción a la actividad del usuario (por
ejemplo el sensor de orientación para controlar el movimiento).
Objetos que aparecen o desaparecen en reacción a las actividades del usuario (por
ejemplo, un asteoride que desaparece cuando recibe un disparo).
¡Se creativo! No necesitas crear un juego, puedes crear lo que tu quieras mientras muestre
todos los comportamientos listados arriba. Comparte tu idea con tu tutor y aseguráte que
tienes todos los comportamientos requeridos.
45
7. material de apoyo
7. Material de Apoyo
El Componente Lienzo
El componente Lienzo es una subsección dentro de tu aplicación. El lienzo se usa para
dibujar y hacer animaciones—tu app puede dibujar objetos, y puedes dar al usuario la
capacidad de dibujar objetos.
Normalmente vas a necesitar que el lienzo llene por completo el ancho de la pantalla
de la app, entonces tendrás que ajustar la propiedad Ancho con la opción “Ajustar al
contenedor”. Por lo general vas a necesitar tener otros elementos abajo o arriba, por lo que
configurarás el Alto como un número fijo de pixeles.
La ubicación de un objeto en el lienzo se define con coordenadas X, Y relativas a la
esquina arriba e izquierda del lienzo. X es la ubicación horizontal del objeto, siendo 0 el
borde izquierdo y X creciendo cuando el objeto se mueve hacia la derecha. Y es la ubicación
vertical, con 0 siendo el borde superior e Y creciendo cuando el objeto se mueve hacia abajo.
Conceptualmente el lienzo se comporta como una rejilla, tal como se ilustra en la Figura 7.1.
Figura 7.1: Un lienzo con ancho de 19 pixeles y altura de 12 pixeles. Se muestran los puntos
en coordenadas (0,0), (3,3) y (19, 0).
46
7. material de apoyo
Figura 7.2: Dibujando un cı́rculo en el lienzo, en la coordenada (10,10) y con radio 5 pixeles.
Ejemplo: ¿Cómo mover una imagen al centro del lienzo? Los bloques de la Fi-
gura 7.4 ubican el SpriteImagen1 en el centro del lienzo usando las propiedades Ancho
y Alto. Dichas referencias abstractas significan que el código funcionará aunque el lienzo
cambie de tamaño.
47
7. material de apoyo
Una alternativa es poner números fijos para X e Y, después del bloque SpriteIma-
gen1.MoverA. Es muy similar a como (10, 10) fue usado en el ejemplo anterior. ¿Sabes
porqué es sustraı́da la mitad del alto y ancho del sprite?
Fijáte que no existe un bloque DibujaImagen como DibujarCı́rculo. En vez de eso,
con el Diseñador arrastras los componentes SpriteImagen en un lienzo y especificas la
imagen (una foto) que define su apariencia. No hay forma de crear sprites dinámicos con
bloques, sólo se pueden hacer visibles o invisibles, y se puede cambiar su ubicación, tal como
se muestra en este ejemplo.
Variables
¿Cuándo defines una variable? Una aplicación memoriza cosas, tiene una memoria
“escondida”. Puedes imaginártelo como una hoja de cálculo (o planilla) dentro del “cerebro”
privado de la aplicación. Tú, el programador, controlas su memoria. Cuando arrastras un
componente en tu aplicación (por ejemplo un botón, un cuadro de texto), cada componente
tiene una serie de propiedades. Estas propiedades son celdas de tu hoja de cálculo que puedes
modificar.
También puedes definir nuevas celdas en tu planilla, cuando necesitas recordar algo: se
llaman variables. Defines una variable cuando no existe en el componente una propiedad
para almacenar la información que necesitas.
Ejemplo: ¿Cómo hacer para que cada vez que el usuario hace click se agranda
el cı́rculo? Como se ilustra en la Figura 7.5, cuando se toca el Lienzo1 se llama a Lien-
zo1.DibujarCı́rculo para dibujar un cı́rculo donde se hizo el touch, en las coordenadas (x,
y). El radio r no puede ser un número fijo si queremos un tamaño de cı́rculo distinto cada
vez. La variable Tama~
noCı́rculo se usa para seguir y recordar el tamaño de los cı́rculos cada
48
7. material de apoyo
vez que se dibuja uno. Se inicializa Tama~
noCı́rculo en 1 para que el primer cı́rculo que se
dibuje sea solo un pequeño punto. Luego, al final del controlador de eventos Lienzo1.Tocar
el tamaño del cı́rculo se duplica. Entonces la segunda vez el cı́rculo tendrá un radio 2, luego
4, luego 8, etc. La variable Tama~
noCı́rculo se necesita porque no hay ninguna propiedad
del componente que se pueda usar. Por ejemplo, el componente Lienzo tiene una propiedad
AnchoDeLı́nea, entonces si estuvieses dibujando lı́neas no necesitarı́as definir una varia-
ble porque podrı́as usar esta propiedad. Pero el lienzo no tiene una propiedad “Tamaño de
Cı́rculo”, por lo que debes definirla tú mismo usando una variable.
Figura 7.5: Usando una variable para controlar el radio de los cı́rculos dibujados.
Temporizadores
Actividades Temporizadas
Ejemplo: ¿Cómo tocar un sonido cada 1 segundo? Como muestra la Figura 7.6 esto
se puede hacer cuando se activa el evento Reloj.Temporizador de manera repetida. Convie-
ne pensar en el temporizador como una alarma, donde la propiedad Reloj.IntervaloDelTemporizador
determina cada cuanto se toca el sonido (por defecto son 1000 milisegundos, o 1 segundo).
49
7. material de apoyo
Entonces si no lo cambias el sonido se escuchará cada segundo. Puedes configurar esta pro-
piedad en el Diseñador o dinámicamente usando bloques.
Puede ser un poco confuso e indirecto tener que cambiar el intervalo en el Diseñador
para luego especificar el comportamiento en el Editor de Bloques. La clave es comprender
que el temporizador se gatillará como un evento cada Reloj.IntervaloDeTemporizador
milisegundos.
Ejemplo 3: ¿Cómo desplazas una nave espacial suavemente por la pantalla? Asu-
mamos que tienes un SpriteImagen que representa una nave espacial. La coordenada X de
la nave espacial define su posición horizontal. Para generar el movimiento hay que hacer que
cada evento del temporizador aumente la coordenada X, para que ası́ la nave aparezca un
poco más a la derecha, como se muestra en la Figura 7.8. Si el IntervaloDelTemporiza-
dor tiene su propiedad por defecto en 1000 milisegundos, entonces la nave se moverá cada
segundo. Para este tipo de animación, configurarás el intervalo en 40 milisegundos.
50
7. material de apoyo
De la misma manera que puedes activar y apagar una alarma, puedes activar y desactivar
el componente Reloj. Mira los siguientes ejemplos:
51
7. material de apoyo
Figura 7.10: Moviendo la nave cuando el usuario habla, y deteniéndola cuando se agita el
dispositivo.
52
7. material de apoyo
y detalle. Como vimos anteriormente, la idea esencial de usar variables es programar una
aplicación para que recuerde información.
Cuando alguien te dice el número de teléfono de una pizzerı́a, tu cerebro lo almacena
en una celda de memoria. Si alguien menciona algunos números para que tú los sumes, tú
también almacenas estos números y los resultados intermedios en una celda de memoria.
En estos casos, no estás totalmente conciente de cómo tu cerebro almacena o recuerda la
información.
Una aplicación también tiene memoria, pero su funcionamiento interno es mucho menos
misterioso que el de tu cerebro. Ahora veremos en detalle cómo manejar la memoria de una
aplicación, cómo almacenar información en ella, y cómo recuperar esa información en un
momento posterior.
Propiedades
Tú, como usuario de una aplicación, puedes ver componentes visibles como botones, cua-
dros de texto y etiquetas. Pero adentro, cada componente es completamente definido por una
serie de propiedades. Los valores almacenados en la memoria de cada propiedad determina
cómo aparece el componente. Tú configuras los valores de las propiedades directamente en
el Diseñador de Componentes. Por ejemplo, la Figura 7.11 muestra el panel para modificar
las propiedades de un componente Lienzo.
53
7. material de apoyo
El componente Lienzo tiene varias propiedades de distintos tipos. Por ejemplo el Co-
lorDeFondo y el ColorDePintura son celdas de memoria que contienen un color. La
propiedad ImagenDeFondo contiene un nombre de archivo (como gatito.png).
La propiedad Visible contiene un valor booleano (verdadero o falso, dependiendo si se
selecciona la opción o no). El Ancho y Alto contienen un número o una designación especial
(por ejemplo, “Ajustar al Contenedor”).
Cuando configuras una propiedad en el Diseñador de Componentes, especificas el valor
inicial de está propiedad, o sea su valor cuando se inicia la aplicación. Los valores de las
propiedades también pueden ser modificados cuando la aplicación se ejecuta, mediante el
uso de bloques. Pero, al cambiar los valores durante la ejecución, los valores que aparecen en
el Diseñador de Componentes no cambian—estas propiedades siempre muestran solamente
los valores iniciales. Esto puede confundir cuando pruebas una aplicación, pues el valor actual
de las propiedades de la aplicación cuando se ejecuta no son visibles.
54
7. material de apoyo
Definir Variables
Al igual que las propiedades, las variables son celdas de memoria, pero que no están
asociadas a un componente en particular. Se define una variable cuando necesitas que tu
aplicación guarde algo en memoria que no haya sido guardado ya en una propiedad de un
componente. Por ejemplo, puede ser que un juego tenga que recordar el nivel alcanzado por
el usuario. Si el número del nivel apareciera en un componente Etiqueta, no necesitarı́as
una variable, porque podrı́as simplemente almacenar el nivel en la propiedad de Texto de
la etiqueta. Pero si el número de nivel no es algo que será visible por el usuario, necesitas
definir una variable para guardar esta información.
Otra diferencia es que mientras que las propiedades se crean automáticamente cuando
arrastras un componente en el Diseñador, las variables se definen explı́citamente en el Editor
de Bloques al arrastrar un bloque “inicializar global nombre”. Puedes nombrar la variable
al hacer click en el texto que dice “nombre” dentro del bloque, y puedes especificar un
valor inicial al arrastrar un bloque (número, texto, color, lista) y conectarlo al bloque de
inicialización. Por ejemplo, para crear una variable llamada “marcador” con un valor inicial
de 0, sigue los siguientes pasos, que se muestran en la Figura 7.12:
Cuando defines una variable, pides a la aplicación crear una celda de memoria para
guardar un valor. Estas celdas de memoria, como las propiedades, no son visibles por el
usuario cuando funciona la aplicación.
55
7. material de apoyo
El bloque de inicialización que conectas en la declaración de la variable especifica el valor
que estará en la celda cuando se inicia la aplicación. A parte de inicializar con números
o texto, también puedes inicializar la variable con un bloque crear una lista vacı́a o
construye una lista. Esto indica a la aplicación que la variable guardará un listado de
celdas de memoria en lugar de un solo valor. Trabajaremos con listas en el Dı́a 4 del taller.
Figura 7.13: El bloque de inicialización contiene bloques de configurar y obtener para esta
variable.
El bloque tomar global marcador permite obtener o rescatar el valor de una variable.
Por ejemplo, si quieres chequear si el valor dentro de la celda de memoria era superior a 100,
tienes que conectar el bloque tomar global marcador en un bloque condicional, tal como
se muestra en la Figura 7.15.
56
7. material de apoyo
Figura 7.15: Usando el bloque marcador global para obtener el valor almacenado en la
variable.
Si puedes entender este tipo de bloques, vas bien encaminado para convertirte en un
programador!
Estos bloques se leen de la siguiente manera: “configurar el marcador como 5 veces más
que su valor actual”, que es una manera para decir, incrementa la variable en 5. El código
funciona de la siguiente manera: los bloques se leen de adentro hacia afuera—no de izquierda
57
7. material de apoyo
a derecha. Entonces se lee primero el bloque “tomar global marcador” y el número 5. Luego
el bloque de suma es ejecutado y el resultado se pone en la variable marcador.
Suponiendo que hubiera un 10 en la celda de memoria para marcador antes de ejecutar
estos bloques, la aplicación ejecutarı́a los siguientes pasos:
58
7. material de apoyo
Puedes usar estos bloques para construir una expresión compleja y conectarla en el lado
derecho de un bloque poner global. Por ejemplo, para mover un sprite a una columna
aleatoria dentro de los bordes de un lienzo, tienes que configurar una expresión que consiste
de una multiplicación, una resta, una propiedad Lienzo.Ancho, una propiedad SpriteI-
magen.Ancho y un bloque entero aleatorio, como se muestra en la Figura 7.18.
Figura 7.18: Puedes usar bloques de “Matemáticas” para construir expresiones complejas.
Al igual que el ejemplo anterior sobre cómo incrementar una variable, los bloques se leen
desde adentro hacia afuera. Suponiendo que el Lienzo tiene un Ancho de 300 pixeles y el
SpriteImagen tiene un Ancho de 50 pixeles, la aplicación ejecutarı́a los siguientes pasos:
3. Llamar a la función entero aleatorio para obtener un número entre 0 y 1 (por ejemplo
0,5).
59
7. material de apoyo
Esta es una de las ventajas de guardar datos en una variable, en comparación con la
propiedad de un componente: te permite mostrar los datos que quieres en el momento que
elijas. También te permite separar la parte computacional de tu aplicación de la interfaz de
usuario, facilitando cambios posteriores de dicha interfaz.
Por ejemplo, en un juego podrı́as guardar el marcador directamente en una Etiqueta o
en una variable. Si lo guardas en una etiqueta, tienes que incrementar las propiedades de
texto de la etiqueta cuando se marcan puntos, y el usuario verá los cambios directamente.
Si guardaste el marcador en una variable y se incrementa la variable cada vez que se marcan
puntos, tendrı́as que incluir bloques para también escribir el valor de la variable en una
etiqueta.
Sin embargo, si decidieras cambiar la aplicación para mostrar el marcador de una manera
distinta, por ejemplo con una barra de color, la opción de una variable serı́a más fácil de
cambiar. No necesitarı́as modificar todos los lugares donde aparece el marcador sino que
solamente tendrı́as que modificar los bloques que muestran el marcador.
Variables locales
Hasta el momento hemos hablado de variables globales que se definen con un bloque
inicializar global. Global se refiere al hecho que la variable se puede usar en todos los
procedimientos y controladores de eventos de la aplicación. AppInventor también te permite
definir variables locales, es decir, variables cuyo uso es restringido a un solo controlador de
eventos o procedimiento, como se muestra en la Figura 7.19.
Si la variable es requerida en un sólo lugar, es una buena idea definirla como local en vez
de global. Al proceder de tal manera, limitas las dependencias en tu aplicación y te aseguras
de que no modificarás una variable por error. Imagina que una variable local es como tu
memoria privada en tu cerebro—no quieres que otros cerebros puedan tener acceso a ella!
60
7. material de apoyo
Resumen
Cuando inicias una aplicación, ésta empieza a ejecutar sus operaciones y a responder a
eventos que ocurren. Al responder a eventos, la aplicación a veces necesita recordar cosas.
Para un juego, puede ser que tenga que recordar el marcador de cada jugador o la dirección
en la cual se mueve un objeto.
Tu aplicación recuerda cosas con propiedades de componentes, pero cuando necesitas
memoria adicional no asociada a un componente, puedes definir variables. Puedes almacenar
valores dentro de una variable y recuperar el valor actual, de la misma manera que con las
propiedades. Como los valores de propiedades, los valores variables no son visibles para el
usuario final. Si quieres que el usuario final vea la información almacenada en una variable,
agregas bloques que muestran esta información en una etiqueta u otro componente de la
interfaz de usuario.
61