Combinando Pong y Arkanoiv
Hay muchas formas de crear algo similar a Pong o Breakout en P5*Js, de hecho hay formas de detectar colisiones de forma más "moderna", pero usaremos una forma más acorde a un ejercicio matemático para mover y detectar si la pelota que rebota da contra la barra o se sale del campo de juego.
Antes que nada, debemos descargar este archivo, y decomprimirlo (que contiene las imágenes, las librerías P5, el html y el sketch.js) y cargar la carpeta en Brackets.
Como se ve en la imagen, se ha agregado la linea 3 y 4 donde creamos 2 variables (sumax y sumay) luego en la linea 17 y 18 le indicamos que x vale x mas el valor de sumax. En cada ciclo, el valor de x se incrementara como ya vimos antes (incrementadores) pero el valor del mismo es sumax o sea 5.
El valor de y en este caso se mantiene porque sumay vale 0, entonces cuando la imagen se dibuje como se pone en la linea 22, el personaje avanzara hacia la derecha hasta salir de la pantalla, ya que cuando empieza el programa x vale 200, luego 205, 210, 215, 220, 225...
REBOTE CONTRA EL BORDE
Como no deseamos que el personaje se salga de la pantalla (ya que el valor de x seguirá incrementandose y Raven se saldrá de la pantalla), entonces usamos 2 IF (ver condicionales) que preguntaran cada vez que se repita el function draw, si x es mayor a 1000 o menor a 0 (cero), en ambos casos, invierte el signo de sumax.

Cuando x llegue a valer 1000 y este en el margen derecho, el primer IF hará que en vez de seguir sumándole 5 en cada ciclo, le sume -5 o sea que x ira descendiendo de 1000, 9995, 9990, 9985, 9980, 9975... o sea que raven se movera a la izquierda hasta que el valor de x sea 0 (cero).
Cuando x llegue a valer 0 y Raven este en el margen izquierdo, el segundo IF de nuevo revierte el signo del valor dentro de sumax que es negativo. Por lo tanto si hacemos negativo un numero negativo, obtenemos un positivo (menos con menos es mas, recuerdan?).
De tal manera, Raven quedara rebotando horizontalmente ya que el valor de x nunca puede superar 1000 (margen derecho) o ser menor a 0 (margen derecho).
En este punto le pido a los chicos que hagan los mismo para los valores verticales, y rápidamente se dieron cuenta que simplemente debemos copiar ambas lineas y reemplazar las x por y sumax por sumay, y en el tercer condicional usar el valor 600 ya que el canvas tiene ese valor de alto.
Si somos obsesivos de la optimizacion (y debemos serlo supongo), notemos que lo que esta entre las llaves de ambos condicionales es identico, por lo tanto no tiene sentido hacer la pregunta 2 veces y escribir lo mismo. Para ello se unen los 2 primeros IF y los 2 de abajo en uno, pero con los simbolos || representamos el operador "o".
Entonces podemos leerlo así:
Si (x es mayor a 1000 o es menor a 0 ) { cambiar el signo de sumax }
Si (y es mayor a 600 o es menor a 0) { cambiar el signo de sumay }
Creando la Paleta
Necesitamos crear una paleta contra la cual va a rebotar nuestra pelota, para ello usaremos provisoriamente un rectángulo (RECT), supongo que sería más fácil usar una imagen, y lo haremos más adelante, pero justamente prefiero hablar más en términos que nos obliguen a usar la matemática.
El rectángulo se dibuja desde su esquina superior izquierda, por ello si deseamos que esté centrado en el mouse, debemos usar mouseX y restarle la mitad del ancho. Como en éste caso es 400, el primer valor de posición de éste punto es mouseX-200, luego 550 es cuan hacia abajo queremos el mismo y los 2 últimos números el ancho y el alto del rectángulo.
Si toca fuera de la paleta MUERE
Para matar al personaje, usaremos el margen inferior, por lo tanto debemos hacer una pregunta dentro de otra, o sea un IF dentro de otro IF.
Como cuando vamos al FastFood y nos preguntan que queremos, si decimos una hamburguesa, entonces SOLO ENTONCES hay una pregunta dentro de ella que es si deseamos condimentarla o agrandar el combo. Pero si la primer pregunta no es respondida hamburguesa, no tiene sentido preguntar si querés ketchup con tu helado.
Para ello debemos saber si la "pelota" (Raven) ha llegado a la parte inferior de la pantalla, si eso ha ocurrido, debemos DENTRO de esa pregunta saber si el valor de x (que es la posición horizontal del personaje) está afuera de la barra amarilla que va desde mouseX-200 hasta mouseX+150.
Entonces sería algo así:
SI (y es mayor a 600) {
SI (x es menor a mouseX-200 o es mayor a mousex+200 ) { el personaje murio }
}
En el nuestro código sería de esta manera:
El valor de x e y se vuelven a CERO en caso de perder (lineas 26 y 27), o sea que cuando uno pierde, el personaje vuelve a aparecer por el margen superior izquierdo.
Además, queremos que el personaje tenga una nueva velocidad, por ello asignamos random() que inventa un valor entre 1 y el número que está entre paréntesis. Por lo tanto las líneas 14 y 15 harán una suma diferente, afectando la velocidad del personaje en la pantalla. algunas veces más rápido otras más lenta.
Código del Ejercicio
var x=200;
var y=200;
var sumax=8;
var sumay=15;
var ameo;
var fondo;
function setup() {
createCanvas(1000,600);
ameo=loadImage("raven.png");
fondo=loadImage("ciudad.jpg");
}
function draw() {
x=x+sumax
y=y+sumay
if ( x>1000 || x<0 ) { sumax = -sumax }
if ( y>600 || y<0 ) { sumay = -sumay }
background(0)
fill (255,255,0)
rect(mouseX-200, 550 , 400,100)
if ( y>600) {
if ( x>mouseX+200 || x<mouseX-200 ) {
x=0
y=0
sumax=random(10)
sumax=random(15)
}
}
imageMode(CENTER)
image(ameo, x , y ,150 ,150)
}
Agregando imágenes
Para mejorar al juego, podemos reemplazar al rectángulo con una imagen. Como el imageMode() es CENTER, las imágenes se dibujan desde el centro, por lo tanto la posición del fondo no es 0,0 sino 500,300 (centro del canvas), lo mismo ocurre con el rect() que es reemplazado por una imagen ubicado en mouseX no en mouseX-200.
También podemos reemplazar a RAVEN por cualquiera de las imágenes pelota1.png, pelota2.png, pelota3.png o pelota4.png (o cualquier imagen que se bajen de internet como ya lo han hecho en clase).
var x=200;
var y=200;
var sumax=8;
var sumay=15;
var ameo;
var barra;
var fondo;
function setup() {
createCanvas(1000,600);
barra=loadImage("barra.png");
ameo=loadImage("pelota3.png");
fondo=loadImage("lava1.png");
}
function draw() {
x=x+sumax
y=y+sumay
if ( x>1000 || x<0 ) { sumax = -sumax }
if ( y>600 || y<0 ) { sumay = -sumay }
background (0)
image(fondo, 500,300,1000,600)
image(barra, mouseX , 600 ,400 ,120)
if ( y>600) {
if ( x>mouseX+200 || x<mouseX-200 ) {
x=0
y=0
sumax=random(10)
sumay=random(15)
}
}
imageMode(CENTER)
image(ameo, x , y ,150 ,150)
}