Saltar la navegación

3.1 Processing. Aprendiendo líneas de código.

Empezamos

https://ctc101.arduino.cc/ctc101/module/module-1/lesson/processing

Las instrucciones de programación son comprensibles para los humanos pero los ordenadores solo entienden ceros y unos. Estas instrucciones tienen que transformarse en código que los ordenadores entienden. Por ello, los programas se escriben en un editor de texto siguiendo unas reglas específicas, para poder transformarlos. El editor es el software de desarrollo llamado Entorno de Desarrollo Integrado, IDE (Integrated Development Environment) abreviado por sus siglas en inglés. Compilar es transformar el código a lenguaje máquina. Aquí puedes ver el aspecto que tiene el entorno de desarrollo de Processing:

Cada ordenador, smartphone, servidor de internet, ascensor, horno - actualmente cualquier dispositivo inteligente - tiene diferentes capacidades y por lo tanto requiere de un lenguaje máquina algo diferente al resto. Existe un lenguaje de programación llamado Java que, una vez compilado, es capaz de utilizarse fácilmente en diferentes dispositivos. Hay muchas maneras diferentes de programar en Java, pero nosotros nos centraremos en utilizar Processing.

Processing es software libre y gratis, esto significa que se puede descargar de internet, instalar y modificar su código sin coste alguno. Processing funciona en cualquier tipo de ordenador y sistema operativo: Windows, Mac OS X y Linux.

El IDE de Processing es muy sencillo, hay una barra de herramientas que puedes utilizar para:

Compilar y ejecutar un programa

Detener un programa

En el IDE de Processing hay un área para mensajes, cuando compilas un programa, si hay errores aparecerán ahí.

Processing crea programas que se ejecutan directamente dentro de tu ordenador. También puedes exportarlos y enviarlos a los ordenadores de otras personas. Los programas, una vez exportados en código máquina, se llaman aplicaciones. Puedes exportar el mismo programa para que se ejecute en un ordenador, en un teléfono, o en un sitio web.

Para hacer tus propios programas, primero aprenderás cómo funciona la pantalla del ordenador y sobre píxeles y colores. Esto te será útil cuando escribas tus propios programas interactivos.

Instalar Processing

Mac OS X / Windows
Descarga Processing de la página de descargas de Processing.
Descomprime el archivo .zip y mételo en tu carpeta de programas / aplicaciones.
Haz clic en processing.exe para empezar.

Linux
Descarga Processing de la página de descargas de Processing, a tu directorio principal.
Abre la ventana del terminal y escribe en ella: tar xvfz processing-xxxx.tgz
Reemplaza el texto xxxx con el resto del nombre del archivo, es decir, el número de la versión. Esto creará una carpeta llamada processing-2.0 o similar. A continuación, ve a este directorio: cd processing-xxxx
Ejecuta Processing: ./install.sh

Instalar los ejemplos de CTC
Ve a CTC - Processing ejemplos en Github, y elige 'Download ZIP'.
Localiza la carpeta “CTC-Processing-master” en tu carpeta de descargas y descomprimela. Una vez hecho, muevela a la carpeta Usuarios/Documentos/Processing en tu ordenador.
Reinicia el IDE de Processing antes de usar los ejemplos.

Pantalla y píxeles

https://ctc101.arduino.cc/ctc101/module/module-1/lesson/screens-and-pixels

Las pantallas se utilizan para representar imágenes. Esas imágenes pueden ser dinámicas, como en las películas, o estáticas, como en las fotografías. Se puede incluir texto, como en los documentos, o solo gráficos. Mayormente, las imágenes en la pantalla son una mezcla de muchas cosas; incluyen animaciones, textos, estadísticas, etc.

Píxeles y Resolución
Las pantallas están hechas de un conjunto de puntos que llamamos píxeles. Por lo general, cuantos más píxeles tenga una pantalla, mejor será. Expresamos la calidad de la pantalla en función de la cantidad de píxeles que tiene, esa cantidad es lo que llamamos resolución.

Normalmente, hablamos de una pantalla en función de su anchura y altura. Por ejemplo, muchos proyectores tienen una resolución de 1024 x 768 píxeles. Esto significa que tiene 1024 píxeles de ancho y 768 píxeles de alto.

Colores
Cada píxel se puede iluminar de muchos colores diferentes. Una vez más, de cuantos más colores se pueda pintar el píxel, mejor será la pantalla. Los colores en la pantalla del ordenador se expresan como una combinación de tres componentes diferentes: rojo (R), verde (G) y azul (B). Cualquier color que representes en una pantalla, se puede hacer mezclando las componentes RGB en diferentes cantidades.

La cantidad de color para cada componente se expresa con un número entre 0 y 255. 0 representa el valor mínimo de un color, por ejemplo, si tiene 0 del componente rojo, significa que ese color no contiene rojo, sin embargo, si tiene 255 del componente rojo, significa que está saturado de color rojo.

Si las componentes son 255,255,255 - los píxeles producirán blanco. Si son 0,0,0 - los píxeles mostrarán negro. Si gradualmente cambias los valores R,G,B en la misma proporción desde 255,255,255 a 0,0,0, verás que el color cambia de blanco a negro.

La siguiente imagen muestra cómo el color de un píxel cambia de blanco a negro y cómo varían los valores RGB:

Coordenadas
Puedes escribir programas que cambien los píxeles de la pantalla. Puedes incluso cambiar un solo píxel. La acción de acceso a un solo píxel en la pantalla es lo que llamamos direccionar un píxel. La ubicación de un píxel se determina mediante coordenadas.

Cada píxel tiene 2 coordenadas:

La coordenada horizontal es la que llamamos coordenada X (anchura, o en inglés width).
La coordenada vertical, es la que llamamos coordenada Y (altura, o en inglés height).
Si recuerdas lo que aprendiste en clase de matemáticas y física, puedes dibujar gráficos, puntos, líneas y curvas usando coordenadas. Esta misma idea se aplica a la pantalla del ordenador, la única diferencia, es que el llamado origen de coordenadas de la pantalla del ordenador es la esquina superior izquierda, como puedes ver en la siguiente imagen.

Línea

https://ctc101.arduino.cc/ctc101/module/module-1/lesson/line

La mejor manera de aprender sobre programación es escribiendo tus propios programas. Vamos a empezar por hacer el programa lo más corto posible usando Processing.

Nota: Ahora vas a empezar a utilizar el Processing IDE.

Ejemplo 1.1
En este ejemplo, escribirás un programa para dibujar una línea en la pantalla.

INSTRUCCIONES
Abre el IDE de Processing y escribe el siguiente programa:

line(0, 0, 100, 100);
 1. Ejecutar el programa haciendo clic en el icono 

RESULTADO
Al ejecutar el programa verás como aparece una línea en la ventana de programa.

COMANDOS
line(x1, y1, x2, y2) : Dibuja una línea desde las coordenadas x1,y1 hasta x2,y2.
También necesitas saber:

Cada línea de código termina con un puto y coma, ';'. Si te olvidas de ponerlo, el código no podrá ser compilado ni ejecutado.
Por defecto, las ventanas de Processing son de 100 x 100 píxeles.
Por defecto, el color del fondo es gris y para dibujar es el negro. Pero por supuesto, todo esto se puede cambiar.
CÓMO FUNCIONA
Se dibuja una línea desde las coordenadas (0, 0), esquina superior izquierda de la ventana, hasta las coordenadas (100, 100) – esquina inferior derecha.
Funciones y parámetros
En el ejemplo anterior, dibujaste una línea con el siguiente comando line(x1, y1, x2, y2). Este comando se llama función. Una función contiene un conjunto de comandos o instrucciones en tan sólo una línea de código. La ejecución de esas instrucciones depende de los parámetros de la función. En line(x1, y1, x2, y2) los parámetros son x1, y1, x2 y y2. La línea que se dibuja cuando llamas a la función line() depende de los parámetros que le pasas a esta función. Cada función puede tener un número diferente de parámetros.

Muchas funciones devuelven un valor cuando las llamamos. Por ejemplo, en el proyecto del reloj de Post-it® emplearás una función llamada hour() que devuelve la hora actual, un número entre 0 y 23.

En el siguiente ejemplo aprenderás como usar otras dos funciones. Todos estos ejemplos están basados en funciones, lo que significa que los comandos que se ejecutan cuando las llamamos están incluidos en Processing. Puedes escribir tus propias funciones, aprenderás como hacerlo en los proyectos del segundo módulo.

Ejemplo 1.2
En este ejemplo, escribirás un programa que dibuje dos líneas de diferentes colores sobre un fondo blanco.

INSTRUCCIONES
Escribe y ejecuta el siguiente programa:

background(255);
line(0, 0, 100, 100);
stroke(0, 0, 255);
line(0, 100, 100, 0);


RESULTADO
En este caso dos líneas, una azul y una negra aparecen dibujadas en la ventana de programa.

COMANDOS
background(gray): Establece el color de fondo desde 0 - negro, hasta 255 - blanco. También puedes utilizar background(red, green, blue)para establecer el color que tú quieras.
stroke(red, green, blue): Establece el color de la línea. Cada componente de color puede ser un número desde 0 hasta 255.
CÓMO FUNCIONA
Tus programas se ejecutarán siempre de arriba a abajo línea por línea. Lo que este programa hace es:

Establece el color de fondo a blanco.
Dibuja la línea negra igual que en el ejemplo anterior, desde la coordenada (0, 0) - esquina superior izquierda, a (100, 100) - esquina inferior derecha.
Establece el color de línea a azul.
Se dibuja la segunda línea desde la coordenada (0, 100) – esquina inferior izquierda, a (100, 0) – esquina superior derecha con color azul.


¡Sigue experimentando!
Añade más líneas de diferentes colores y cambia el color de fondo.
Cambia el orden del programa. ¿Qué ocurre si, por ejemplo, cambias el color de fondo al final?

Variables

https://ctc101.arduino.cc/ctc101/module/module-1/lesson/variables

Las variables son algo que usas todo el tiempo en programación. Son como un contenedor para diferentes tipos de datos. Para cada variable, necesitas especificar qué tipo de datos contendrán, cuál es el nombre de la variable y qué valor se le asigna.

Imagina las variables como botes. Digamos que tienes dos botes, uno para galletas y otro para palabras, estos son los tipos de datos. Ahora hay que darles un nombre a cada bote; cookieJar (bote de galletas) y jarOfWord (bote de palabras). Ahora tú decides que poner en cada bote. En el cookieJar pones una galleta de doble chocolate y en el jarOfWord decides poner "hello". Ahora cada bote tiene un valor.

Puedes cambiar el contenido de los botes, su valor, en cualquier momento, pero siempre y cuando sea del mismo tipo. Por ejemplo, puedes cambiar la galleta de doble chocolate por una oreo y "hello" por "spaceinvader".

Para hacerlo más claro, vamos a escribir un programa utilizando variables. Escribiremos un programa que dibuje, de nuevo, dos líneas, pero esta vez utilizaremos variables.

Ejemplo 1.3
En este ejemplo, dibujarás dos líneas como hicimos en el ejemplo 1.2 pero esta vez, usando variables para almacenar las coordenadas.

INSTRUCCIONES
Escribe y ejecuta el siguiente programa:

int value1 = 0;
int value2 = 100;
line(value1, value1, value2, value2);
line(value1, value2, value2, value1);


RESULTADO
Aparecen las mismas dos líneas del ejemplo 1.2 pero esta vez hemos empleado variables y no hemos modificado el color del fondo.

COMANDOS
int variableName = value: Crea una variable del tipo "int", del inglés integer, que representa números enteros. variableName puede ser cualquier nombre de tu elección, pero para hacerlo más sencillo, asegúrate que el nombre va acorde con el contexto en el que se usa la variable. value es el valor que quieres almacenar en la variable.
COMANDOS
Se declara la variable value1 y se inicializa a 0. En cualquier lugar del programa donde escribas value1, será lo mismo que escribir 0.
Se declara otra variable, value2 y se inicializa a 100. En cualquier lugar del programa donde escribas value2, será lo mismo que escribir 100.
Se dibuja una línea desde las coordenadas (value1, value1) = (0, 0), a (value2, value2) = (100, 100).
Se dibuja otra línea desde las coordenadas (value1, value2) = (0, 100), a (value2, value1) = (100, 0).
Modifica el valor de las variables para ver qué pasa con las líneas.
Tipos de datos
Los tipos de datos que más utilizarás son los siguientes:

int: Número entero, por ejemplo, 2, 99 o 532.
float: Número decimal, por ejemplo, 2.76, 8.211 o 900.3.
boolean: Puede ser verdadero o falso.
char: Un caracter, por ejemplo, ‘r’, ‘2’ o ‘%’.
String: Una secuencia de carateres, por ejemplo, "hola", "¡Me encanta programar!" o "&%!@¤".
Variables del sistema
Processing incluye algunas variables de sistema para hacerlas más accesibles dentro de tus programas. Por ejemplo, width y height. Estas variables devuelven la anchura (width) y altura (height) de la ventana de tu programa.

Ejemplo 1.4
En este ejemplo, dibujarás una elipse cuyo tamaño depende del tamaño de tu ventana de programa.

INSTRUCCIONES
Escribe y ejecuta el siguiente programa:

size(400, 200);
ellipse(width/2, height/2, width, height);


RESULTADO
Usando las variables width y height del sistema, la elipse se ajusta al tamaño de la ventana. No importa el tamaño de la ventana, el elipse la llenará siempre por completo. Intenta cambiar el tamaño de la ventana.

COMANDOS
size(windowWidth, windowHeight): Establece el tamaño de la ventana de programa en píxeles.
ellipse(x, y, xDiameter, yDiameter): Dibuja un elipse centrada en las coordenadas x e y. El tamaño se establece con xDiameter e yDiameter. Cuando estos dos parámetros son iguales, el resultado es un círculo.
width: Devuelve la anchura de la ventana de programa en píxeles.
height: Devuelve la altura de la ventana de programa en píxeles.
COMANDOS
Se establece el tamaño de la ventana de programa a 400 x 200 píxeles.
Dibuja una elipse con centro en las coordenadas (width/2, height/2) = (200, 100). Lo que significa que estará centrada en la ventana de programa.
El diámetro x de la elipse se fija al mismo tamaño que la anchura de la ventana (400 píxeles).
El diámetro y de la elipse se fija al mismo tamaño que la altura de la ventana (200 píxeles).

¡Sigue experimentando!
Dibuja una cara sonriente empleando líneas y elipses.
Haz que la cara sonriente se ajuste al tamaño de tu ventana.

Setup y Draw

https://ctc101.arduino.cc/ctc101/module/module-1/lesson/setup-and-draw

Los programas que hemos hecho hasta ahora son llamados programas estáticos. Esto significa que nunca cambian. Se ejecutan una única vez y cuando llegan a la última línea de código, se paran. Si queremos que un programa sea interactivo, tenemos que habilitar la entrada de datos continuamente mientras el programa se ejecuta. Esto sólo es posible si la ejecución es continua.

Con Processing, puedes crear programas que se ejecuten continuamente utilizando la función draw(). Esta función repetirá el bloque de código una y otra vez hasta que el programa se pare. Sin embargo, no todo el código escrito necesita ser repetido continuamente. Para el código que sólo necesita ser ejecutado una única vez, debes usar la función llamada setup().

Ejemplo 1.5
En este ejemplo, dibujarás una línea como ya hiciste en el ejemplo 1.1 pero esta vez empleando las funciones setup() y draw().

INSTRUCCIONES
Escribe y ejecuta el siguiente programa:

void setup() {
size(300, 300);
}

void draw() {
line(0 ,0, width, height);
}


RESULTADO
Realmente no podemos ver que la línea se está dibujando una y otra vez ya que está exactamente en la misma posición todo el tiempo.

COMANDOS
void: Se emplea cuando se declara una función que no devuelve nada.
void setup() { code }: El código entre llaves se ejecuta una única vez cuando el programa empieza.
void draw(){ code }: El código entre llaves se ejecuta una y otra vez. Se ejecuta línea por línea, de arriba a abajo hasta la última línea, donde vuelve a empezar desde el principio de la función draw().
COMANDOS
Se establece el tamaño de la ventana a 300 x 300 píxeles. Sólo se hace una vez, al principio del programa, por ello está en la función setup().
Se dibuja una línea en la función draw(), de esquina a esquina de la ventana.
Se ejecuta de nuevo la función draw(), dibujando otra línea exactamente en el mismo sitio.
Repite la función draw(), dibujando una línea en cada iteración.
Ejemplo 1.6
En este ejemplo, aprenderás las funciones mouseX y mouseY, y entenderás mejor la función draw().

INSTRUCCIONES
Escribe y ejecuta el siguiente programa:

void setup() {
size(300,300);
}

void draw() {
line(0, 0, mouseX, mouseY);
}


RESULTADO
Este programa te permite interactuar con la pantalla. Si mueves el puntero del ratón en la ventana del programa, verás que dibuja diferentes líneas. Si te fijas, se deja un rastro de líneas por donde vas moviendo el ratón, esto se debe a qué cada línea que el programa dibuja, nunca se borra.

COMANDOS
mouseX: Devuelve la coordenada X del puntero del ratón.
mouseY: Devuelve la coordenada Y del puntero del ratón.
CÓMO FUNCIONA
Se establece el tamaño de la ventana a 300 x 300 píxeles en la función setup().
Se dibuja una línea en la función draw() desde las coordenadas (0, 0) hasta (mouseX, mouseY). El fin de la línea depende de dónde se encuentra el puntero del ratón.
Se ejecuta de nuevo la función draw(), dibujando otra línea desde (0, 0) hasta (mouseX, mouseY). Si has movido un poco el puntero del ratón, verás que está línea es diferente a la primera.
Repite la función draw(), dibujando una línea en cada iteración.
Ejemplo 1.7
En este ejemplo, vas a modificar ligeramente el ejemplo anterior. ¿Qué ocurre cuando ejecutas el nuevo programa?

INSTRUCCIONES
Escribe y ejecuta el siguiente programa:

void setup() {
size(300,300);
}

void draw() {
background(255);
line(0, 0, mouseX, mouseY);
}


RESULTADO
En este caso, el rastro de líneas desaparece quedando una única línea.

CÓMO FUNCIONA
Se establece el tamaño de la ventana a 300 x 300 píxeles en la función setup().
En la función draw() se configura el color del fondo blanco.
Se dibuja una línea en la función draw() desde las coordenadas (0, 0) hasta (mouseX, mouseY).
Se ejecuta de nuevo la función draw(), pintando de nuevo el fondo de blanco. Esto reescribe cualquier cosa que hubiese en la ventana de programa, haciendo que la línea desaparezca.
Se dibuja otra línea desde las coordenadas (0, 0) hasta (mouseX, mouseY). Si mueves un poco el cursor del ratón, la línea nueva aparece en una posición diferente.
Repite la función draw(), coloreando el fondo y dibujando una línea en cada iteración.

¡Sigue experimentando!
Dibuja una elipse y modifica su diámetro con el movimiento del puntero del ratón.
Cambia el color del fondo según mueves el puntero del ratón.

Actividades.

A ver hasta dónde llegas

Aprende a tu ritmo.

Las actividades tienen un grado creciente de dificultad. No pases a la siguiente hasta no haber completado la anterior.

Ánimo!

1. Serpiente Roja

Pincha aquí

En este miniproyecto vas a aprender a programar un objeto que se mueve en la pantalla y va dejando rastro del movimiento del ratón. Iremos escribiendo el código paso por paso, añadiendo nuevas funcionalidades en cada uno.

1. Dibuja un círculo
Empezaremos dibujando un círculo rojo.


/*
* _01_Red_Snake
*
* How to program a moving object leaving traces of the mouse movement on the screen.
*
* (c) 2013-2016 Arduino LLC.
*/

void setup() {
size(400, 400);
}

void draw() {
noStroke(); // Draw borderless shapes
fill(255, 0, 0); // Fill shapes with pure red color
ellipse(100, 100, 30, 30); // Circle of 30 pixels diameter
}


RESULTADO
Se dibuja un círculo en las misma posición una y otra vez mientras el programa esté ejecutándose.

COMANDOS
noStroke(): Se emplea para no dibujar el contorno de las siguientes figuras.
fill(red, green, blue): Establece el color utilizado para rellenar las siguientes figuras. Cada color (red, green, blue) puede ser un color entre 0 y 255.
Comandos relacionados:

size(ancho, alto): Establece el tamaño de la ventana del programa en píxeles.
ellipse(x, y, diametroX, diametroY): Dibuja un elipse con centro en x,y. El tamaño se establece con diametroX y diametroY. Cuando estos dos parámetros son iguales, el resultado es un círculo.
CÓMO FUNCIONA
Se establece el tamaño de la ventana a 400 x 400 píxeles en la función setup().
En la función draw(), se llama a la función noStroke() para dibujar las figuras sin contorno.
Se configura el color para rellenar las figuras a rojo.
Se dibuja un circulo en las coordenadas (100, 100) con un diámetro x e y de 30 píxeles. Debido a la configuración anterior, el círculo será rojo y sin contorno.
Repite la función draw() y como no hay ningún cambio en ningún parámetro el programa se comporta de forma estática.
2. Haz que el círculo se mueva
En este paso haremos que el círculo se mueva con el ratón, dejando un rastro en la pantalla.


/*
* _01_Red_Snake
*
* How to program a moving object leaving traces of the mouse movement on the screen.
*
* (c) 2013-2016 Arduino LLC.
*/

void setup() {
size(400, 400);
}

void draw() {
noStroke();
fill(255, 0, 0);
ellipse(mouseX, mouseY, 30, 30); // Circle's placement following the mouse pointer
}


RESULTADO
En este paso lo que hemos hecho ha sido reemplazar las coordenadas del círculo por mouseX y mouseY. El punto rojo sigue ahora al ratón, haciendo que el programa se comporte como una aplicación de dibujo cualquiera.

CÓMO FUNCIONA
Cada vez que se ejecuta la función draw(), las coordenadas de la elipse se sitúan en mouseX y mouseY haciendo que el círculo siga el puntero del ratón.
Como el fondo no se pinta de nuevo en cada iteración, cada círculo permanece en la pantalla dejando su trazo.
3. Cambia gradualmente el color
En este paso haremos que el color cambie mientras se ejecuta el programa, y para hacerlo, emplearemos una variable para el color en lugar de un número constante.


/*
* _01_Red_Snake
*
* How to program a moving object leaving traces of the mouse movement on the screen.
*
* (c) 2013-2016 Arduino LLC.
*/

int red = 255;

void setup() {
size(400, 400);
}

void draw() {
noStroke();
fill(red, 0, 0);
ellipse(mouseX, mouseY, 30, 30); // Circle according to the mouse coordinates
}


RESULTADO
Como verás, este programa produce el mismo resultado que el programa del paso anterior solo que está vez empleamos una variable para definir el color.

CÓMO FUNCIONA
Antes de la función setup(), se declara una variable tipo integer (red) y se inicializa a 255.
Cuando configuramos el color en la función draw(), empleamos la variable red en lugar del número 255.
4. Cambia gradualmente el color II
El cambio de color puede hacerse de diferentes maneras. El color puede cambiar entre 0 y 255 (negro y rojo respectivamente). En este paso se muestra como reducir la cantidad de rojo cada vez que se ejecuta la función draw().


/*
* _01_Red_Snake
*
* How to program a moving object leaving traces of the mouse movement on the screen.
*
* (c) 2013-2016 Arduino LLC.
*/

int red = 255;

void setup() {
size(400, 400);
}

void draw() {
red = red - 1; // Make the red a little darker
if (red < 0){
red = 255; // Once it reaches black, make it light red again
}

noStroke();
fill(red, 0, 0);
ellipse(mouseX, mouseY, 30, 30);
}

Resultado
Como ves, esta vez el color del círculo varía mientras se ejecuta el programa.

Comandos
if( test ){ statements }: Comprueba si la condición (test) es cierta. Si lo es, se ejecuta el código entre llaves. Si no lo es, el programa salta y el ejecuta el código después de las llaves.En este ejemplo, si rojo es menor que 0. Si es así, los statements entre llaves son ejecutados. En este ejemplo, establece red a 255 de nuevo. Si por el contrario, test es falso, el programa procede a ejecutar el código después de las llaves. Utilizando declaraciones "if" te permite decir al programa que código ejecutar
CÓMO FUNCIONA
En la función draw() se resta una unidad a la variable red, red = red-1. La primera vez que la función draw() se ejecuta, la variable red valdrá 254.
Empleando el símbolo < o "menor que", la sentencia if comprueba si red es menor que 0. La primera vez que la función draw() se ejecuta, esto será falso.
El color para rellenar las figuras se configura con la variable red, esta vez un poco más oscuro que en el paso anterior, fill(254, 0, 0).
Con cada iteración de la función draw(), red estará más cerca de valer 0, haciendo el color cada vez más oscuro.
En la iteración 255, al restar 1 a la variable red, esta valdrá 0.
La condición sigue siendo falsa ya que 0 no es menor que cero.
Se configura el color de relleno a negro, fill(0, 0, 0).
En la iteración 256 de la función draw(), al restar 1 de la variable red esta valdrá -1.
La sentencia if es cierta, -1 es menor que 0.
Se ejecuta el código entre llaves, haciendo que la variable red valga 255 de nuevo.
Se configura el color de relleno a rojo, fill(255, 0, 0).

¡Sigue experimentando!
La modificación más sencilla que puedes hacer es cambiar el color de la serpiente.

2. Reloj de Post-it

Pincha aquí

En este miniproyecto vas a crear un reloj donde los números estarán hechos a partir de fotografías de notas adhesivas o Post-it. Para ello, aprenderás a utilizar imágenes en tus programas y almacenarlas en arrays (luego entenderás lo que son). De nuevo, iremos avanzando paso por paso.

1. Añadir imágenes
El primer paso es dar al programa acceso a la imagen. Para ello, primero descarga la imagen aquí. A continuación, debes arrastrar el fichero de la imagen en el IDE de Processing, como muestra la siguiente captura.

La imagen se almacena en una subcarpeta del programa llamada data. Esta captura de pantalla muestra la estructura de los ficheros donde puedes encontrar el archivo de la imagen. También puedes encontrarlo abriendo la carpeta desde el menú 'Sketch>Mostrar carpeta del Sketch'.

2. Mostrando una imagen
En este programa vamos a crear una variable Pimage para mostrar una imagen.


/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/

PImage im;

void setup() {
size(400, 400); // We make the sketch the size of the image
im = loadImage("photo.jpg"); // Image name
}

void draw() {
image(im, 0, 0); // To show the image on the screen at the coordinates 0, 0
}


RESULTADO
Al ejecutar el programa verás que muestra la imagen.

COMANDOS
PImage imageName: crea una variable del tipo PImage llamada imageName. Una variable PImage puede almacenar una imagen.
loadImage(imageFile): Carga la imagen imageFile desde el directorio de datos del programa. imageFile debe escribirse exactamente como se llama el archivo.
image(imageName, x, y): Muestra la imagen PImage imageName. La esquina superior izquierda de la imagen se sitúa en las coordenadas x e y.
CÓMO FUNCIONA
Se crea una variable del tipo PImage llamada im.
En la función setup(), se establece el tamaño de la ventana a 400 x 400 píxeles. El mismo tamaño que tiene la imagen empleada en el programa.
La imagen photo.jpg, se carga y almacena en la variable im.
En la función draw(), se muestra la imagen (im). La esquina superior izquierda de la imagen se sitúa en las coordenadas 0, 0 - la esquina superior izquierda de la ventana del programa. Dado que la ventana del programa y la imagen son del mismo tamaño, la imagen se ajusta perfectamente.
3. Mostrando dos imágenes
En este paso, añadirás otra imagen para mostrar dos, una al lado de la otra.

Descarga las fotos photo.jpgphoto2.jpg


/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/


PImage im;
PImage im2;

void setup() {
size(800, 400); // Make the sketch twice the image's width
im = loadImage("photo.jpg");
im2 = loadImage("photo2.jpg"); // Load the second image
}

void draw() {
image(im, 0, 0);
image(im2, 400, 0); // To show the second image use coordinates 400, 0
}


RESULTADO
El programa mostrará dos imágenes.

CÓMO FUNCIONA
Se declara la segunda variable del tipo PImage llamada im2.
En la función setup() se establece el tamaño de la ventana a 800 x 400 píxeles, el doble de anchura que antes, para que quepan las dos imágenes.
La imagen photo2.jpg se carga y se almacena en la variable im2.
En la función draw(), im2 se muestra después de im. La esquina superior izquierda se sitúa en las coordenadas (400, 0) - la mitad superior de la ventana del programa, y a su vez, la esquina superior derecha im.
4. Arrays I
En este paso vamos a modificar el paso anterior y usaremos un array para mostrar dos imágenes. Primero, aprenderás qué es un array.

Un array es como una caja con muchos compartimentos. Cada compartimento puede almacenar varios objetos y todos los objetos de un mismo compartimento tienen que ser del mismo tipo. Cada objeto se puede encontrar referenciando el compartimento dónde está almacenado.

Por ejemplo, un array llamado "FruitContainer" (caja de fruta) tiene 3 compartimentos y puede contener 3 objetos. El compartimento 1 tiene un plátano, el compartimento 2 tiene una cereza y el compartimento 3 tiene una fresa. Si quieres encontrar la cereza, mirarás en el compartimento 2 de la caja. El orden de los arrays siempre empieza en 0, por lo que FruitContainer[0] contiene el plátano, FruitContainer[1] contiene la cereza y FruitContainer[2] la fresa.

Los arrays pueden ser de muchos tipos, como entero (int) o cadena (String). El máximo número de variables que pueden almacenar debe ser declarado con el array – 3 en el ejemplo anterior.

5. Arrays II
En este paso, vas a modificar el programa del paso 3 y usarás un array del tipo PImage para mostrar dos imágenes.


/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/

PImage im[] = new PImage[2]; // Declare an array to contain 2 images

void setup() {
size(800, 400);
// The first image goes into the first position of the array img[]
im[0] = loadImage("photo.jpg");
// The second image goes into the second position of the array
im[1] = loadImage("photo2.jpg");
}

void draw() {
image(im[0], 0, 0);
image(im[1], 400, 0);
}


RESULTADO
Como puedes ver, los cambios en el programa no cambian nada en el resultado.

COMANDOS
datatype arrayName\[ \] = new datatype\[ numberOfElements \]: Declara un array del tipo datatype, con el nombre arrayName. numberOfElements es el número de elementos o compartimentos de datos.
arrayName\[ index \]: Accede al elemento index del array arrayName. El índice del primer elemento es 0, del segundo 1, etc.
Puedes encontrar más información en inglés aquí.
CÓMO FUNCIONA
Se declara un array del tipo PImage para almacenar dos imágenes, en lugar de emplear dos variables del tipo PImage.
En la función setup(), se carga la foto photo.jpg y se almacena en im\[0\], también se carga photo2.jpg y se almacena en im\[1\].
En la función draw(), se muestra la imagen im\[0\] con la esquina superior izquierda en las coordenadas (0, 0).
Se muestra la imagen im\[1\] con la esquina superior izquierda en las coordenadas (400, 0).
6. Usando dos Arrays
Para simplificar aún más la asignación de las variables imagen, el truco es almacenar los nombres de todas las imágenes en un array de strings (cadenas de texto). Aquí un ejemplo:


/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/

PImage im[] = new PImage[2];
String imFile[] = {"photo.jpg", "photo2.jpg"}; // Array with the file names

void setup() {
size(800, 400);
im[0] = loadImage(imFile[0]); // Use 'loadImage()' to load the first image file
im[1] = loadImage(imFile[1]); // Second image file
}

void draw() {
image(im[0], 0, 0);
image(im[1], 400, 0);
}


RESULTADO
Como podrás observar cuando ejecutes este programa, el resultado es el mismo. Esta forma de programar te facilitará seguir trabajando ya que añadir más imágenes es muy sencillo.

CÓMO FUNCIONA
Se declara otro array de tipo String. Se llama imFile y almacena los nombres de los dos archivos de las imágenes; photo.jpg, y photo2.jpg.
En la función setup(), se carga la imagen imFile\[0\] y se almacena en im\[0\].
Se carga la imagen imFile\[1\] y se almacena en im\[1\].
7. El bucle for()
En este paso aumentarás el número de imágenes que se muestran de dos a cuatro. Todavía utilizarás los dos arrays de los pasos anteriores, pero para hacer el código aún más eficiente, emplearás el bucle for().

Descarga las imágenes one.jpg, two.jpg, three.jpg y four.jpg

/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/

PImage im[] = new PImage[4]; // Make your array bigger for it to contain 4 images
String imFile[] = {"one.jpg", "two.jpg", "three.jpg", "four.jpg"};

void setup() {
size(800, 800); // Make your sketch bigger to show all the images at once
for (int i = 0; i < 4; i = i + 1) {
im[i] = loadImage(imFile[i]); // Load images according to the counter 'i'
}
}

void draw() {
image(im[0], 0, 0); // Show the images
image(im[1], 400, 0);
image(im[2], 0, 400);
image(im[3], 400, 400);
}

Resultado
Al ejecutar el programa, se mostrarán cuatro imágenes.

Comandos
for(initializer; test; update){ statements }: Permite repetir una parte del código tantas veces como necesites. El bucle se ejecuta siguiendo los siguientes pasos:Ejecuta la inicialización: Normalmente, esto se hace con la declaración de una variable tipo entero llamada i.
Comprueba si la condición en test es verdadera o falsa. Normalmente esto es comprobar si la variable i es mayor que un valor determinado.
Si la comprobación es falsa, se sale del bucle. Si la comprobación es verdadera, se ejecuta el código entre llaves.
Ejecuta la actualización. Normalmente esto es incrementar o decrementar la variable i en 1.
Vuelve a repetir todo desde el paso 2.
CÓMO FUNCIONA
Se modifican los cuatro arrays para almacenar 4 elementos cada uno.
En la función setup(), se establece el tamaño de la ventana a 800 x 800 píxeles para que quepan las cuatro imágenes.
Se emplea un bucle for para cargar y almacenar los archivos de las imágenes en el array im:Se declara la variable i tipo entero y se inicializa a 0.
Se realiza la comprobación, i<4, y es cierta, 0 es menor que 4.
Se emplea la variable i para acceder a los elementos de los arrays. En la primera iteración, i es igual a 0, lo que significa que imFile\[0\] (one.jpg se carga y se almacena en im\[0\].
Se ejecuta la actualización, es decir, se incrementa en 1 la variable i, i = i+1.
Se realiza la comprobación de nuevo y sigue siendo verdadera, 1 es menor que 4.
Se carga la imagen imFile\[1\], two.jpg, y se almacena en im\[1\].
Se ejecuta de nuevo la actualización.
Este bucle itera hasta que la variable i es igual a 4, entonces la comprobación será falsa, 4 es no menor que 4.
En la función draw() las cuatro imágenes se muestran en una cuadrícula.
8. Múltiples imágenes
Puesto que el objetivo de este programa es crear un reloj, en este paso, mostrarás las diferentes imágenes que usarás después para representar el tiempo.

Descarga las imágenes que representan los números: 0, 1, 2, 3, 4, 5, 6, 7, 8 y 9.

/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/

PImage im[] = new PImage[10]; // Array for 10 images
String imFile[] = {"0.jpg", "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "9.jpg"};

void setup() {
size(700, 95); // 10 images of 70 pixels wide and 95 pixels high
for (int i = 0; i < 10; i = i + 1) {
im[i] = loadImage(imFile[i]);
}
}

void draw() {
for (int i = 0; i < 10; i = i + 1) {
image(im[i], 70 * i, 0); // Show the images in sequence
}
}

Resultado
 

El programa muestra las imágenes de los números 0 al 9.

Cómo funciona
Se modifican los dos arrays para almacenar cada uno diez elementos.
En la función setup(), se establece el tamaño de la ventana a 700 x 95 píxeles, para mostrar diez imágenes de 70 x 95 píxeles en fila .
Un bucle for se ejecuta diez veces para cargar todos los archivos de las imágenes en el array im.
En la función draw() otro bucle for se ejecuta diez veces para mostrar las imágenes:En la primera iteración, cuando la variable i es igual a 0, la imagen en im\[0\] se muestra con la esquina superior izquierda en las coordenadas (0, 0), ya que 70\*0 = 0.
En la segunda iteración, cuando la variable i es igual a 1, la imagen en img\[1\] se muestra en las coordenadas (70, 0), ya que 70\*1 = 70.
Esto se ejecuta continuamente hasta que la variable i es igual a 10.
9. El Tiempo
En este paso mostrarás la hora actual.

/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/

PImage im[] = new PImage[10]; // Array for 10 images
String imFile[] = {"0.jpg", "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "9.jpg"};

void setup() {
size(140, 95); // 2 digits of 70x95 pixels
for (int i = 0; i < 10; i = i + 1) {
im[i] = loadImage(imFile[i]);
}
}

void draw() {
int h = hour(); // Take the hour from the computer and store it into a variable
int h_dec = int(h / 10); // Get the most significant digit
int h_uni = h - h_dec * 10; // Get the least significant digit

image(im[h_dec], 0, 0); // Show the most significant digit
image(im[h_uni], 70, 0); // Show the least significant digit
}


Resultado
El programa muestra dos imágenes basadas en la hora actual.

Comandos
hour(): Devuelve la hora actual como un número entre 0 y 23.
CÓMO FUNCIONA
En la función setup() se establece el tamaño de la ventana a 140 x 95 píxeles, para mostrar dos imágenes, una junto a la otra.
En la función draw(), se declaran tres variables nuevas: h, h\_dec y h\_uni. h se emplea para almacenar la hora actual. h\_dec y h\_uni se emplean para acceder a las posiciones del array en el que están las imágenes que quieres mostrar.
Cuando la hora actual es 14:30, se hacen los siguientes cálculos:h =hour() = 14
h\_dec = int( h/10 ) = int( 1.4 ) = 1
h\_uni = h-h\_dec \*10 = 14-1\*10 = 14-10 = 4
Cuando la hora actual es 02:00 se hacen los siguientes cálculos:h = hour() = 2
h\_dec = int( 2/10 ) = int( 0.2 ) = 0
h\_uni = h-h\_dec \*10 = 2-0\*10 = 2-0 = 2
Se muestran las imágenes im\[h\_dec\] y im\[h\_uni\] una junto a la otra.
10. El reloj final
Este es el último paso del proyecto. En este paso añadirás los minutos y los segundos al reloj.

/*
* _02_PostIt_Clock
*
* Create a clock where the numbers are represented by photographs ​of digits made out of Post-its
*
* (c) 2013-2016 Arduino LLC.
*/

PImage im[] = new PImage[10]; // Array for 10 images
String imFile[] = {"0.jpg", "1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg", "6.jpg", "7.jpg", "8.jpg", "9.jpg"};

void setup() {
size(140, 285); // 6 digits in three rows and two columns
for (int i = 0; i < 10; i = i + 1) {
im[i] = loadImage(imFile[i]);
}
}

void draw() {
int h = hour();
int h_dec = int(h / 10);
int h_uni = h - h_dec * 10;

image(im[h_dec], 0, 0);
image(im[h_uni], 70, 0);

int m = minute(); // Take the minutes from the computer's clock and store it in a variable
int m_dec = int(m / 10); // Get the most significant digit
int m_uni = m - m_dec * 10; // Get the least significant digit

image(im[m_dec], 0, 95); // Show the most significant digit
image(im[m_uni], 70, 95); // Show the least significant digit

int s = second(); // Take the seconds from the computer's clock and store it in a variable
int s_dec = int(s / 10); // Get the most significant digit
int s_uni = s - s_dec * 10; // Get the least significant digit

image(im[s_dec], 0, 190); // Show the most significant digit
image(im[s_uni], 70, 190); // Show the least significant digit
}


RESULTADO
El programa muestra seis imágenes, basadas en el tiempo actual en horas, minutos y segundos.

COMANDOS
minute(): devuelve los minutos actuales como un valor entre 0 y 59.
second(): devuelve los segundos actuales como un valor entre 0 y 59.
CÓMO FUNCIONA
Una vez que se muestra la hora en la función draw(), se declaran tres variables nuevas, m, m\_dec y m\_unit para almacenar los minutos.
Cuando la hora actual es 14:30, se hacen los siguientes cálculos:m = minute() = 30
m\_dec = int( m/10 ) = int( 3 ) = 3
m\_uni = m-m\_dec \*10 = 30-3\*10 = 30-30 = 0
Se muestran las imágenes im\[m\_dec\] y im\[m\_uni\] una junto a la otra, debajo de las imágenes de la hora.
Se declaran tres variables nuevas, s, s\_dec y s\_uni, para almacenar los segundos.
Se muestran las imágenes im\[s\_dec\] y im\[s\_uni\] una junto a la otra, debajo de las imágenes de los minutos.

Sigue experimentando
Usando las mismas variables de sistema, crea un temporizador para la cocina, por ejemplo un reloj que cuente hacia atrás con imágenes.
Toma tus propias fotos de los dígitos y úsalas en tu programa.

3. Caza la manzana

Pincha aquí

En este proyecto vas a llevar la programación un poco más lejos y crearás un pequeño videojuego donde nuestro aguerrido héroe, el famoso científico Newton, intenta no perder la oportunidad de que la manzana le caiga en la cabeza.

Vamos a crear, paso a paso, un programa en el que Newton coleccione puntos durante medio minuto, al recibir tantos manzanazos en la cabeza como sea posible.

1. Crea una manzana y un científico
Empezarás creando una manzana y un científico. Las manzanas, por ahora, serán círculos que caen del cielo, mientras que Newton será un cuadrado al fondo de la pantalla.


/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

void setup() {
size(400, 400); // Make the screen of an average size
}

void draw() {
ellipse(15, 15, 20, 20); // Draw the apple at the top of the screen
rect(width / 2, height - 25, 20, 20); // Draw Newton at the bottom of the screen
}


RESULTADO
Se dibuja un circulo que representa la manzana, y un cuadrado para marcar la posición del personaje Newton.

COMANDOS
rect(x, y, rectWidth, rectHeight): Dibuja un rectángulo. x e y establecen la posición de la esquina superior izquierda, rectWidth y rectHeight establecen el tamaño en píxeles.
CÓMO FUNCIONA
En la función setup() se establece el tamaño de la ventana a 400 x 400 píxeles.
En la función draw() se dibuja un círculo en las coordenadas (15, 15), con x e y de 20 píxeles de diámetro.
Se dibuja un cuadrado en la esquina superior izquierda con las coordenadas (width/2, height-25) de 20 x 20 píxeles de tamaño.
2. Controla a Newton con el teclado
En este paso, harás que Newton (el cuadrado) se mueva a la derecha y a la izquierda con las flechas del teclado.


/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0;

void setup() {
size(400, 400); // Draw the sketch at a not-too-small size
}

void draw() {
background(200); // Clear the screen
ellipse(15, 15, 20, 20);
rect(nX, height - 25, 20, 20); // Draw Newton with a varaible X coordinate
}

void keyPressed() {
// If the right key was pressed, increase the X coordinate in 3 units
if (keyCode == RIGHT) {
nX = nX + 3;
}
// If the left key was pressed, decrease the X coordinate in 3 units
if (keyCode == LEFT) {
nX = nX - 3;
}
}


RESULTADO
Pulsa las flechas del teclado y verás cómo se mueve el cuadrado.

COMANDOS
keyPressed(){ statements }: Esta función se llama cada vez que se pulsa una tecla. Es decir, cualquier código escrito dentro de esta función será ejecutado al pulsar una tecla.
keyCode: Es una variable interna del sistema que se emplea para detectar qué tecla ha sido pulsada.
RIGHT: Constante que contiene el valor del código de la tecla "flecha derecha".
LEFT: Constante que contiene el valor del código de la tecla "flecha izquierda".
CÓMO FUNCIONA
Se declara la variable nX, tipo int, y se inicializa a 0. Esta variable almacenará la posición X de Newton (el cuadrado).
En la función draw(), se configura el color del fondo a gris claro. Al pintar de nuevo el fondo en cada iteración de la función draw() se elimina el rastro del cuadrado cuando se mueve.
La posición X del cuadrado se fija con la variable nX. La posición Y es aún fija y vale height-25.
Se llama a la función keyPressed() cada vez que se pulsa una tecla.
Si se pulsa la tecla "fecha derecha", if( keyCode == RIGHT), se suman 3 a la variable nX. Haciendo que el cuadrado se mueva 3 píxeles a la derecha.
Si se pulsa la tecla "fecha izquierda", if( keyCode == LEFT), se restan 3 a la variable nX. Haciendo que el cuadrado se mueva 3 píxeles a la izquierda.
3. Limita los movimientos del cuadrado
En este paso, emplearás el condicional if, para limitar los movimientos de Newton en el eje X haciendo que esté siempre dentro de la ventana del programa. Es decir, tendrá que ser mayor que 0 y menor que la anchura de la ventana (width).


/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0;

void setup() {
size(400, 400);
}

void draw() {
background(200);
ellipse(15, 15, 20, 20);
rect(nX, height - 25, 20, 20);
}

void keyPressed() {
// Increment the coordinates in 3
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrement the coordinates in 3 u
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the valu of the X coordinate
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) { // Check the size of the square on the right side
nX = width - 20;
}
}


RESULTADO
En este caso, el resultado es casi el mismo, con la excepción de que el cuadrado ya no saldrá fuera de la ventana de programa.

CÓMO FUNCIONA
Al final de la función keyPressed(), hay dos nuevas sentencias if:Si la variable nX es menor de 0, if( nX<0 ), nX se pone a 0. Haciendo así, que el cuadrado no pueda pasar el límite izquierdo.
Si la variable nX es mayor que "width - 20", if( nX>width-20 ), nX se pone a width-20. Haciendo que el cuadrado no supere el límite derecho. Se comprueba si nX es mayor que "width-20" en vez de mayor que width para asegurar que el cuadrado completo se ve, ya que su tamaño es de 20 píxeles de ancho.
4. Manzanas que caen
En este paso, modificarás el programa para hacer que la manzana (círculo) caiga de lo alto de la pantalla (cielo). Para esto, crearás una variable que almacene la coordenada Y del círculo y, la incrementarás hasta que la manzana toque el suelo, es decir, la parte baja de la ventana del programa.

/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0;
int aY = 0; // Apple's Y coordinate

void setup() {
size(400, 400);
}

void draw() {
background(200);

aY = aY + 1; // Increase apple's coordinate
if (aY > height) {
aY = 15; // If the apple touches the ground, lift it again
}
ellipse(15, aY, 20, 20); // Make the Y coordinate into a variable
rect(nX, height - 25, 20, 20);
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}

RESULTADO
Los círculos, o las manzanas, caen del cielo.

CÓMO FUNCIONA
Se declara la variable aY, tipo int, para almacenar la posición del círculo (manzana) en el eje Y y se inicializa a 0.
Cada vez que la función draw() se ejecuta, se suma 1 a la variable aY, aY=aY+1, haciendo que el círculo esté un píxel más cerca del suelo.
Una sentencia if comprueba si la variable aY es mayor que height, if( aY>height ). Si lo es, significa que el círculo ha alcanzado la parte baja de la ventana de programa, y la variable se pone nuevo a 0.
5. Un poco de azar
Hasta ahora, las manzanas siempre salen de la misma posición en lo alto de la pantalla, esto es bastante predecible. En este paso, vas a generar un número aleatorio para cambiar la X de origen y que cada vez salgan de un sitio distinto.


/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0;
int aY = 0;
int aX = 15; // Apple's X coordinate

void setup() {
size(400, 400);
}

void draw() {
background(200);

aY = aY + 1;
if (aY > height) {
aY = 15;
aX = int(random(width - 20)); // Initialize the X coordinate of the apple to a random number
}
ellipse(aX, aY, 20, 20); // Include the changes to the X coordinate to the circle's movement
rect(nX, height - 25, 20, 20);
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}

RESULTADO
Con este cambio en el programa, podrás ver que las manzanas salen desde cualquier punto en lo alto de la pantalla.

COMANDOS
random(max): Genera un número aleatorio entre 0 y max-1. También puedes usar random(min,max) para generar un número aleatorio entre min y max-1.
CÓMO FUNCIONA
Se declara aX, una variable tipo int, para almacenar el valor de la posición X de los circulos (manzanas) y se inicializa a 15. Ten en cuenta que la coordenada habrá que cambiarla solo cuando la manzana llegue al suelo, si no cambiará aleatoriamente durante su caída.
Cuando el círculo alcanza la parte baja de la ventana (suelo), if( aY>height), se fija una nueva coordenada X. Un número aleatorio entre 0 y width-20, aX = int( random( width-20 ) ).
Se dibuja el círculo utilizando aX cómo coordenada X, ellipse( aX, aY, 20, 20).
6. Detección de colisión
La acción de detectar que dos objetos se chocan en la pantalla se llama detección de colisión. En este paso, vas a detectar si la manzana choca con la cabeza de Newton empleando una sentencia if. Al detectar colisión, se cambia el color del cuadrado y del círculo a rojo.

/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0;
int nY = 0; // Y coordinate for the square
int aY = 0;
int aX = 15;

void setup() {
size(400, 400);
nY = height - 25; // Init the coordinate Y for the square to be at the end of the screen
}

void draw() {
background(200);

aY = aY + 1;
if (aY > height) {
aY = 15;
aX = int(random(width - 20));
}

fill(255); // By default fill in the shapes white

// Collision detection
if (aY + 10 > nY && aY - 10 < nY + 20) { // Is the circle at the same height as the square?
if (aX + 10 > nX && aX - 10 < nX + 20) { // Is the circle on top of the square?
fill(255, 0, 0); // Change the filling color to red
}
}

// Lines to understand collision detection
// uncomment them to test how things work
//line(0,aY-10,width,aY-10);
//line(aX-10,0,aX-10,height);
//line(0,aY+10,width,aY+10);
//line(aX+10,0,aX+10,height);

ellipse(aX, aY, 20, 20);
rect(nX, nY, 20, 20); // Include a variable to control the Y coordinate
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}


RESULTADO
Cuando las manzanas (círculos) colisionan con el cuadrado (Newton) ambos se vuelven rojos.

COMANDOS
if(test1 && test2){ statements }: Esto se utiliza para realizar varias comprobaciones en un único if(). En este ejemplo, comprobamos si aY+10 > nY y si aY-10 < nY+20. Si estas dos comprobaciones son ciertas simultáneamente, se ejecuta el código entre llaves.
CÓMO FUNCIONA
Se declara la variable nY, tipo int, para almacenar la coordenada Y de la posición del cuadrado (Newton) y se inicializa a 0. Esta variable facilita la comprobación de las colisiones.
En la función setup(), se asigna a la variable nY el valor width-20. Esto se tiene que hacer en la función setup() después de ajustar el tamaño de la ventana. En caso contrario, width no tomará el valor correcto.
El color de relleno se fija a blanco, fill(255), así se puede cambiar cuando se detecta una colisión.
La detección de colisión se realiza con dos sentencias if, una dentro de otra:La primera, comprueba si el circulo se encuentra a la misma altura que el cuadrado, if( aY+10 > nY && aY-10 < nY+20). Es decir, si la zona inferior del círculo (aY+10) está por debajo de la superior del cuadrado (nY), y la superior del círculo (aY-10) está por encima de la inferior del cuadrado (nY+20). Si esta condición es cierta, se comprueba la segunda.
La segunda, comprueba si el círculo se encuentra en la misma posición X que el cuadrado.
Además, si activas las siguientes líneas en el programa. Verás una serie de líneas en la pantalla enmarcando el movimiento de los objetos. Puedes emplearlas para ver cómo funciona la detección de colisión.

// lines of code to understand how collision works
// erase the comment in order to see the code
line(0,aY-10,width,aY-10);
line(aX-10,0,aX-10,height);
line(0,aY+10,width,aY+10);
line(aX+10,0,aX+10,height);

7. Más rápido
Para hacer el juego más interesante, en este paso harás que las manzanas caigan más rápido.

/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0;
int nY = 0;
float aY = 0; // Make aY into a float
int aX = 15;
float aV = 3; // Apple's falling speed

void setup() {
size(400, 400);
nY = height - 25;
}

void draw() {
background(200);

// Apple's movement
aY = aY + aV; // Introduce the speed as an increment
if (aY > height) {
aY = 15;
aX = int(random(width - 20));
}

fill(255);

// Collision detection
if (aY + 10 > nY && aY - 10 < nY + 20) {
if (aX + 10 > nX && aX - 10 < nX + 20) {
fill(255, 0, 0);
}
}

ellipse(aX, aY, 20, 20);
rect(nX, nY, 20, 20);
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}

RESULTADO
Las manzanas caen más rápido.

CÓMO FUNCIONA
Para preparar el siguiente paso, la variable aY se hace de tipo float en lugar de tipo int
Se declara la variable aV, tipo float, para almacenar el valor 3. Esto es la velocidad de la manzana.
En la función draw(), la posición Y de la manzana, se fija incrementando la variable aY con la velocidad, aV.
8. A Newton le gusta la gravedad, dale más
En este paso, modificarás la caída de las manzanas para que responda a la aceleración de la gravedad. De este modo, las manzanas irán cada vez más rápido cuanto más cerca estén del suelo.

/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0;
int nY = 0;
float aY = 0;
int aX = 15;
float aV = 0; // Apple's initial speed is zero
float aA = 0.05; // Apple's intial accerlation (0.98 would be too much)

void setup() {
size(400, 400);
nY = height - 25;
}

void draw() {
background(200);

// Apple's movement
aV = aV + aA; // EstiaAte the speed according to the acceleration
aY = aY + aV; // EstiaAte the position according to the speed
if (aY > height) {
aY = 15;
aX = int(random(width - 20));
aV = 0; // Apples start falling at zero speed
}

fill(255);

// Collision detection
if (aY + 10 > nY && aY - 10 < nY + 20) {
if (aX + 10 > nX && aX - 10 < nX + 20) {
fill(255, 0, 0);
}
}

ellipse(aX, aY, 20, 20);
rect(nX, nY, 20, 20);
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}


RESULTADO
Las manzanas caen dependiendo de la aceleración y la gravedad.

CÓMO FUNCIONA
Cuando se declara la variable de la velocidad, aV, se le asigna el valor 0.
Se declara una variable, aA, tipo float, para almacenar un valor de aceleración de 0.05 (en el mundo real esto es 0.98, pero poner ese valor haría muy difícil el juego.)
En la función draw(), la velocidad de la manzana se configura incrementando aV con aA. Esto aumenta la velocidad cada vez que la función draw() se ejecuta.
La posición Y de la manzana, se fija incrementando la variable aY con aV. Esto hace que la manzana se mueva distancias más grandes cada vez que la función draw() se ejecuta.
Cuando se lanza una nueva manzana, esto se hace en la sentencia if donde se comprueba si la variable aY es mayor que height, la velocidad se fija 0.
9. Cuenta los puntos
En este paso, implementarás un contador que cuente cuántas manzanas golpearon a Newton.

Nota: como empiezas a tener muchas variables en tu programa, es recomendable añadir comentarios para recordar qué hace cada una.

 
 

/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0; // X coordinate, Newton
int nY = 0; // Y coordinate, Newton
float aY = 0; // Y coordinate, apples
int aX = 15; // X coordinate, apples
float aV = 0; // Y speed, apples
float aA = 0.05; // Y acceleration, apples
int p = 0; // Points

void setup() {
size(400, 400);
nY = height - 25;
}

void draw() {
background(200);

// Apple's movement
aV = aV + aA;
aY = aY + aV;
if (aY > height) {
aY = 15;
aX = int(random(width - 20));
aV = 0;
}

fill(255);

// Collision detection
if (aY + 10 > nY && aY - 10 < nY + 20) {
if (aX + 10 > nX && aX - 10 < nX + 20) {
fill(255, 0, 0);
// If collision increase the points
p = p + 1;
}
}

ellipse(aX, aY, 20, 20);
rect(nX, nY, 20, 20);

// Show the points on the screen
fill(0);
text("Hits: " + p, 3 * width / 4, 20); // Text to the right on the screen
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}

RESULTADO
La cantidad de manzanas que golpeen la cabeza de Newton se contarán y se mostrarán en la ventana del programa.

COMANDOS
text( text, x, y ): escribe un texto (text) en la pantalla en las coordenadas x e y.
CÓMO FUNCIONA
Se declara la variable, p, tipo int para almacenar los puntos.
En la sentencia if para la detección de colisión, una vez que el color de relleno se fija a rojo, la variable p se incrementa en 1.
En las últimas líneas de la función draw(), se fija el color de relleno a negro.
Se sitúa un texto en las coordenadas ( 3\*width/4, 20). El texto dice “Hits:“ y el valor de la variable p. Ten en cuenta que "hits" es "golpes" en español.
10. Uoops, error
Te habrás dado cuenta que tu programa ahora mismo está contabilizando puntos de más. Cada vez que la manzana cae sobre la cabeza de Newton, cuando el círculo toca el cuadrado, tu contador sube más o menos 5 puntos. Esto se debe a que el contador continúa contando hasta que la mazana se solapa con Newton por completo.

Para corregir esto, crearás una variable de tipo boolean (una variable que puede ser verdadero (true) o falso (false)) para decirle al programa si contar puntos o no.

/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0; // X coordinate, Newton
int nY = 0; // Y coordinate, Newton
float aY = 0; // Y coordinate, apples
int aX = 15; // X coordinate, apples
float aV = 0; // Y speed, apples
float aA = 0.05; // Y acceleration, apples
int p = 0; // Points
boolean pCount = true; // Check whether to count points or not

void setup() {
size(400, 400);
nY = height - 25;
}

void draw() {
background(200);

// Apple's movement
aV = aV + aA;
aY = aY + aV;
if (aY > height) {
aY = 15;
aX = int(random(width - 20));
aV = 0;
// When throwing a new apple it will be possible
// to start counting points again
pCount = true;
}

fill(255);

// Collision detection
if (aY + 10 > nY && aY - 10 < nY + 20) {
if (aX + 10 > nX && aX - 10 < nX + 20) {
fill(255, 0, 0);
// If collision increase the points
if (pCount) p = p + 1;
pCount = false; // Whenever you make it at this point, do not
// count any more points
}
}

ellipse(aX, aY, 20, 20);
rect(nX, nY, 20, 20);

// Show the points on the screen
fill(0); // Text color
text("Hits: " + p, 3 * width / 4, 20); // Text alligned to the right
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}

RESULTADO
El contador ha cambiado, ahora solo cuenta una colisión cada vez.

COMANDOS
if( boolean ){ statements }: Comprueba si una variable tipo boolean es true, si lo es ejecuta el código entre llaves statements. Puedes también comprobar si es false escribiendo if( !boolean ).
CÓMO FUNCIONA
Se declara la variable pCount, tipo boolean. Los puntos solo se cuentan cuando esta variable es true.
Justo después de fijar la velocidad a 0, en la sentencia if que comprueba si la variable aY es mayor que height, la variable pCount se pone a true.
Cuando se detecta una colisión, se incrementa en 1 la variable p, siempre y cuando pCount valga true.
A continuación, pCount se pone a false.
Cuando se lanza una nueva manzana, la variable pCount se pone de nuevo a true.
11. Y el tiempo empieza
El objetivo del juego es recibir tantas manzanas en la cabeza de Newton como sea posible en medio minuto. En este paso, crearás un temporizador de cuenta atrás y lo mostrarás en la ventana del programa.

/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

int nX = 0; // X coordinate, Newton
int nY = 0; // Y coordinate, Newton
float aY = 0; // Y coordinate, apples
int aX = 15; // X coordinate, apples
float aV = 0; // Y speed, apples
float aA = 0.05; // Y acceleration, apples
int p = 0; // Points
boolean pCount = true; // Check whether to count points or not
long t = 0; // Store the time

void setup() {
size(400, 400);
nY = height - 25;
t = millis(); // Initialize the time counter
}

void draw() {
background(200);

// Apple's movement
aV = aV + aA;
aY = aY + aV;
if (aY > height) {
aY = 15;
aX = int(random(width - 20));
aV = 0;
// When throwing a new apple it will be possible
// to start counting points again
pCount = true;
}

fill(255);

// Collision detection
if (aY + 10 > nY && aY - 10 < nY + 20) {
if (aX + 10 > nX && aX - 10 < nX + 20) {
fill(255, 0, 0);
// If collision increase the points
if (pCount) p = p + 1;
pCount = false; // Whenever you make it at this point, do not
// count any more points
}
}

ellipse(aX, aY, 20, 20);
rect(nX, nY, 20, 20);


// Count the time
float timer = (millis() - t) / 1000; // Count how much time has passed in seconds

// GAME OVER
if (timer >= 30) { // If time reaches 30 seconds, end the game
noLoop();
}

// Show the time on the screen
fill(0);
text("Time: " + (30 - timer), 10, 20);

// Show the points on the screen
fill(0);
text("Hits: " + p, 3 * width / 4, 20);
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}


RESULTADO
Verás el temporizador en la ventana del programa.

COMANDOS
long: Este es un tipo de datos para números enteros muy grandes. Es conveniente usarlos cuando manejamos variables temporales, porque estos datos pueden ser muy grandes. ¿Recuerdas que una variables es cómo un contenedor de datos? Bien, se puede decir que long es un contenedor más grande que int. Un int se queda sin espacio antes que un long.
noLoop(): Detiene la ejecución continua de la función draw. Para volver a ejecutar el programa tendrás que llamar a loop().
millis(): Esta función devuelve el tiempo en milisegundos que ha pasado desde la última vez que se llamó. Si es la primera vez que la llamas, entonces desde que comenzó el programa.
CÓMO FUNCIONA
Se declara la variable, t, tipo long para almacenar el tiempo.
En la función setup(), se asigna a la variable t el valor que devuelve millis(). Como el valor a t se asigna al final de setup(), este valor será próximo a 0, pero aún más próximo a cuando el juego comienza realmente.
En la función draw(), una vez dibujados el cuadrado y el círculo, se declara la variable timer tipo float.
Se asigna a timer el valor (millis()-t) / 1000. Al dividirlo entre 1000, esta variable tendrá un valor en segundos en lugar de en milisegundos.
Si la variable timer es igual o mayor que 30, han pasado 30 segundos y entonces se llama a la función noLoop() la cual detendrá el programa.
Se muestra un texto en las coordenadas (10, 20). El texto dice: “Time:“ y el valor 30 - t. Es decir, se muestra la cuenta atrás. Ten en cuenta que "time" es "tiempo" en español.
12. Añade imágenes al juego
En el último paso, añadirás imágenes (tipo PNG) para el fondo las manzanas y Newton. Las puedes crear tú, o buscarlas en Internet.

 Nota: Es importante que las imágenes sean de tipo PNG si quieres que haya transparencia entre las imágenes y el fondo. Ten en cuenta que, al cambiar las formas por imágenes, las proporciones también cambian, por lo que tendrás que hacer encajar esos valores en la parte del programa dedicado a la detección de colisiones.


/*
* _03_Catch_The_Apple
*
* Create the game step-by-step, adding complexity as you move along.
* The aim is for Newton to collect points by getting bumped on the head
* by as many apples as possible in half a minute.
*
* (c) 2013-2016 Arduino LLC.
*/

String[] imFiles = {"fondo.png", "manzana.png", "newton1.png", "newton2.png"};
PImage[] im = new PImage[4];

int nX = 0; // X coordinate, Newton
int nY = 0; // Y coordinate, Newton
float aY = 0; // Y coordinate, apples
int aX = 15; // X coordinate, apples
float aV = 0; // Y speed, apples
float aA = 0.05; // Y acceleration, apples
int p = 0; // Points
boolean pCount = true; // Check whether to count points or not
long t = 0; // Store the time

void setup() {
size(400, 400);
nY = height - 135;
t = millis();

// Load the images
for(int i = 0; i < 4; i = i + 1) {
im[i] = loadImage(imFiles[i]);
}
}

void draw() {
background(200);
image(im[0], 0, 0, width, height); // Background image

// Apple's movement
aV = aV + aA;
aY = aY + aV;
if (aY > height) {
aY = 15;
aX = int(random(width - 20));
aV = 0;
// When throwing a new apple it will be possible
// to start counting points again
pCount = true;
}

fill(255);

// Collision detection
if (aY + 50 > nY && aY < nY + 135) {
if (aX + 40 > nX && aX < nX + 128) {
fill(255, 0, 0);
// If collision increase the points
if (pCount) p = p + 1;
pCount = false; // Whenever you make it at this point, do not
// count any more points
}
}

image(im[1], aX, aY); // Apple
if(pCount) {
image(im[2], nX, nY); // Newton looking for apples
} else {
image(im[3], nX, nY); // Newton got an apple
}

// Count the time
float timer = (millis() - t) / 1000; // Count how much time has passed in seconds

// GAME OVER
if (timer >= 30) { // If time reaches 30 seconds, end the game
noLoop();
}

// Show the time on the screen
fill(0);
textSize(20); // Increase the font size
text("Time: " + (30 - timer), 10, 20);

// Show the points on the screen
fill(0);
textSize(20); // Increase the font size
text("Hits: " + p, 3 * width / 4, 20);
}

void keyPressed() {
// Increase the coordinates in 3 pixels
if (keyCode == RIGHT) {
nX = nX + 3;
}
// Decrease the coordinates in 3 pixels
if (keyCode == LEFT) {
nX = nX - 3;
}
// Limit the X coordinates
if (nX < 0) {
nX = 0;
}
if (nX > width - 20) {
nX = width - 20;
}
}

RESULTADO
Como ves, ahora los círculo son manzanas, el cuadrado es Newton, y en el fondo hay un árbol.

Para cargar las imágenes utilizamos el mismo método que en los proyectos anteriores, utilizando arrays. En lugar de cambiar el color de las formas cuando una colisión sea detectada, utilizamos el boolean pCount para decidir qué imagen de Newton mostrar.

CÓMO FUNCIONA
Se declara el array imFiles\[\], tipo String, para almacenar los nombres de los archivos de las imagenes que se van a utilizar.
Se declara el array im\[\], tipo tipo PImage, para almacenar las imágenes que se van a utilizar.
En la función setup(), se utiliza un bucle for para recorrer los nombres de los archivos de las imágenes del array imFiles\[\], y cargar las mismas en el array im\[\].
im\[0\] contiene la imagen de fondo y se mostrará ajustada al tamaño de la ventana, esto se hace al empezar la función draw().
im\[1\] contiene la imagen de la manzana y se mostrará después de la detección de colisión.
im\[2\] y im\[3\] contienen las imágenes de Newton, la primera es Newton normal y la segunda es Newton después de ser golpeado en la cabeza. La variable pCount, tipo boolean se utiliza para decidir qué imagen se mostrará.
Si pCount es true, significa que el programa está listo para contar los puntos si una colisión es detectada, y se muestra la imagen de Newton normal,(im\[2\]).
Si pCount no es true, significa que se detecta una colisión y que suma un punto, entonces se muestra la imagen de Newton golpeado (im\[3\]).
En las sentencias if que comprueban la colisión, los valores se han modificado para encajar los tamaños en las imágenes en vez de las formas utilizadas anteriormente.

¡SIGUE EXPERIMENTANDO!
Para mejorar este juego puedes hacer varias cosas:

Imágenes personalizadas: Crea tus propias imágenes.
Pantalla de inicio: Crea una pantalla de inicio y que se pase al juego una vez se presione un botón.
Pantalla final: Crea una pantalla que muestre el resultado una vez se haya terminado el tiempo.
Reinicio: Haz posible reiniciar el juego cuando el tiempo haya terminado. No te olvides de reiniciar todas las variables necesarias.
Modifica los movimientos: Haz que la manzana se mueva modificando la aceleración en lugar de la velocidad.