Saltar al contenido principal

Dibujar y mover

Aquí tu programa usa la pantalla: abre una ventana (o la pantalla de la placa), dibuja, anima una pelota y mueve un cuadrado con las teclas o con los botones. Es el bucle de cualquier juego, escrito a mano, y el paso previo a Tu primer juego con salas, donde el editor de escenas lo escribe por ti.

Como en las páginas anteriores, cada programa va en el fichero principal de tu proyecto, en lugar de lo que tenga.

Una pelota que rebota​

use Display

Display.open(320, 240)
Display.fps = 30 // 30 fotogramas por segundo

var draw = Display.draw
draw.colorBG = 0x102040 // el color con el que update() borra la pantalla

var x = 160.0
var y = 120.0
var vx = 90.0 // píxeles por segundo
var vy = 60.0
while (true)
draw.color = 0xFFCC00
draw.circle(x, y, 10, true)
draw.text(8, 8, "Hola, JARU", 0xFFFFFF)
Display.update() // enseña el fotograma y espera al siguiente

x = x + vx * Display.dt
y = y + vy * Display.dt
if (x < 10 or x > Display.viewWidth - 10) then
vx = -vx
end
if (y < 10 or y > Display.viewHeight - 10) then
vy = -vy
end
end

Pulsa Run: se abre una ventana de 320 × 240 con una pelota amarilla que rebota en los bordes. Para acabar, pulsa Stop.

La ventana del programa: una pelota amarilla que rebota en los bordes sobre un fondo azul oscuro, con el texto Hola, JARU arriba a la izquierda
  • Display.open(320, 240) abre la ventana en Windows. En la placa, el programa usa su pantalla (ver Display).
  • Display.draw es el módulo de dibujo, Draw: draw.color es el color de lo que pintas, en 0xRRGGBB, draw.circle pinta un círculo (relleno, con true) y draw.text escribe un texto.
  • Cada vuelta del bucle es un fotograma: pinta, y Display.update() lo enseña, borra la pantalla con colorBG para el siguiente y espera lo justo para que haya 30 por segundo, los de Display.fps.
  • Display.dt son los segundos que ha durado el fotograma anterior. Multiplicar la velocidad por dt hace que la pelota recorra 90 píxeles por segundo, vaya rápido o despacio el aparato.
  • Display.viewWidth y Display.viewHeight son el ancho y el alto de la zona de dibujo: la pelota rebota en ellos.

Moverlo con las teclas y los botones​

Ahora, algo que manejas tú: un cuadrado que va a la izquierda y a la derecha, y que cambia de color.

use Display
use Input

const IZQUIERDA = 0
const DERECHA = 1
const COLOR = 2

if (platform() == HW_WIN32) then
Input.map(IZQUIERDA, "LEFT")
Input.map(DERECHA, "RIGHT")
Input.map(COLOR, "SPACE")
elsif (platform() == HW_ESP32) then
// Los tres botones de la LILYGO T4; en otra placa, los pines de los tuyos
Input.map(IZQUIERDA, 39)
Input.map(DERECHA, 38)
Input.map(COLOR, 37)
end

Display.open(320, 240)
Display.fps = 30
var draw = Display.draw
draw.colorBG = 0x102040

var colores = [0xFFCC00, 0x40E0D0, 0xFF6080]
var c = 0
var x = 150.0
var velocidad = 120.0 // píxeles por segundo
var colorAntes = false
while (true)
if (Input.pressed(IZQUIERDA) and x > 0) then
x = x - velocidad * Display.dt
end
if (Input.pressed(DERECHA) and x < Display.viewWidth - 20) then
x = x + velocidad * Display.dt
end
var colorAhora = Input.pressed(COLOR)
if (colorAhora and not(colorAntes)) then // se acaba de pulsar
c = (c + 1) % 3
end
colorAntes = colorAhora
draw.color = colores[c]
draw.rect(x, Display.viewHeight - 40, 20, 20, true)
Display.update()
end

Pulsa Run y, con la ventana del programa delante, usa las flechas: el cuadrado se mueve mientras tienes una pulsada. Cada pulsación de la barra espaciadora le cambia el color.

La ventana del programa: un cuadrado abajo va a la derecha hasta el borde, cambia de amarillo a turquesa, va a la izquierda hasta el otro borde, pasa a rosa, vuelve al centro y se pone amarillo otra vez
  • Input reparte la entrada en acciones, números del 0 al 15. Input.map asocia cada acción a una tecla en Windows o al pin de un botón en la placa, y el resto del programa pregunta solo por las acciones: es el mismo en las dos.
  • platform() dice dónde corre el programa: HW_WIN32 en Windows y HW_ESP32 en una placa con ESP32. Cada placa tiene sus pines, por eso cada una lleva su mapeo.
  • Input.pressed dice si la acción está pulsada en este fotograma. Para el color, el programa compara con el fotograma anterior, como con el botón de Un LED y un botón: así cambia una vez por pulsación, aunque la tengas pulsada.
  • colores es una lista, y colores[c] su elemento c, contando desde 0. % es el resto de la división: c va de 0 a 2 y vuelve a 0.

Esto es lo que hacen todos los juegos: leer la entrada, mover las cosas y pintarlas, fotograma a fotograma.

justPressed en la 0.9.7

Input tiene justPressed(), que dice si una acción se acaba de pulsar, pero en la 0.9.7 puede perder pulsaciones si en un mismo fotograma consultas varias acciones, como aquí. Por eso el programa compara a mano. Ver justPressed.

En la placa​

  1. Los botones. Si tu placa es la LILYGO T4, ya llevas sus tres botones. Si es otra, añade al if una rama para su chip, como elsif (platform() == HW_ESP32S3) then, con los pines de sus botones, conectados entre el pin y GND. Qué pines valen, y las constantes de cada chip, en Botones, pines y mando.
  2. Con tu placa en Target, pulsa Run, como en Tu programa en una placa.

La pelota y el cuadrado salen en la pantalla de la placa. Su tamaño lo pone la placa, no los números de Display.open:

WindowsESP32 / ESP32-S3ESP32-P4ESP32-S31
Lo que abre Display.open(320, 240)Una ventana de 320 × 240Toda la pantalla de la placa: los números no se usanUna zona de 320 × 240 en el centro de la pantallaIgual que el ESP32-P4

Como los dos programas usan Display.viewWidth y Display.viewHeight, la pelota rebota en los bordes y el cuadrado no se sale, en cualquier pantalla.

En el ESP32-S3, el pin 37 no vale para un botón

En el ESP32-S3, los pines del 33 al 37 son de su memoria PSRAM: con Input.map en el 37, la placa se cuelga y se reinicia una y otra vez. Por eso el mapeo de la LILYGO T4 va solo para el ESP32 (HW_ESP32). Ver Pines que no valen para un botón.

Siguientes pasos​