Tutorial: un juego paso a paso
Vamos a hacer "Caza de monedas": un @ se mueve por un tablero recogiendo monedas $ antes de que se acabe el tiempo. Cada paso añade una idea nueva; al final tendrás un juego completo de unas 60 líneas.
Crea una carpeta, abre en ella VS Code y crea caza.hz. Pulsa Ctrl+Alt+F5 para que el programa se vuelva a ejecutar cada vez que guardes.
Paso 1: el tablero
Empezamos dibujando un tablero vacío con un borde:
const ANCHO = 20
const ALTO = 8
function dibujar() {
print("#" * ANCHO)
repeat ALTO - 2 { print("#" + " " * (ANCHO - 2) + "#") }
print("#" * ANCHO)
}
dibujar()▶ Probar en el editor
"#" * 20 repite el texto 20 veces.
Paso 2: el jugador y las monedas
Guardamos las posiciones con Vec2 y dibujamos cada casilla según lo que haya en ella:
const ANCHO = 20
const ALTO = 8
randomSeed(1)
var jugador = Vec2(1, 1)
var monedas = []
repeat 5 { monedas.add(Vec2(randomInt(1, ANCHO - 2), randomInt(1, ALTO - 2))) }
function casilla(x: number, y: number): text {
if x == 0 or y == 0 or x == ANCHO - 1 or y == ALTO - 1 { return "#" }
if jugador == Vec2(x, y) { return "@" }
if monedas.contains(Vec2(x, y)) { return "$" }
return " "
}
function dibujar() {
for y in 0..ALTO {
var linea = ""
for x in 0..ANCHO { linea += casilla(x, y) }
print(linea)
}
}
dibujar()▶ Probar en el editor
Paso 3: moverse
Console.readKey() espera a que se pulse una tecla y devuelve su nombre. Movemos al jugador con las flechas, sin dejarle salir del tablero (clamp):
function mover(tecla: text) {
var d = match tecla {
"up", "w" => Vec2(0, -1)
"down", "s" => Vec2(0, 1)
"left", "a" => Vec2(-1, 0)
"right", "d" => Vec2(1, 0)
else => Vec2(0, 0)
}
jugador = Vec2(clamp(jugador.x + d.x, 1, ANCHO - 2), clamp(jugador.y + d.y, 1, ALTO - 2))
}
while true {
Console.clear()
dibujar()
mover(Console.readKey())
}
Paso 4: recoger monedas y ganar
Al pisar una moneda la quitamos de la lista y sumamos puntos. Cuando no quedan, se acaba:
var puntos = 0
function recoger() {
var i = monedas.indexOf(jugador)
if i >= 0 {
monedas.removeAt(i)
puntos += 10
}
}
Paso 5: el juego completo
Con un límite de movimientos, colores y la posibilidad de que el juego se juegue solo cuando no hay teclado (así se puede probar con hyper test):
const ANCHO = 20
const ALTO = 8
const MOVIMIENTOS = 60
randomSeed(7)
var jugador = Vec2(1, 1)
var monedas = []
repeat 5 { monedas.add(Vec2(randomInt(2, ANCHO - 2), randomInt(1, ALTO - 2))) }
var puntos = 0
var quedan = MOVIMIENTOS
function casilla(x: number, y: number): text {
if x == 0 or y == 0 or x == ANCHO - 1 or y == ALTO - 1 { return "#" }
if jugador == Vec2(x, y) { return "@" }
if monedas.contains(Vec2(x, y)) { return "$" }
return " "
}
function dibujar() {
for y in 0..ALTO {
var linea = ""
for x in 0..ANCHO { linea += casilla(x, y) }
print(linea)
}
print("Puntos: ${puntos} Movimientos: ${quedan} Monedas: ${monedas.length}")
}
function mover(tecla: text) {
var d = match tecla {
"up", "w" => Vec2(0, -1)
"down", "s" => Vec2(0, 1)
"left", "a" => Vec2(-1, 0)
"right", "d" => Vec2(1, 0)
else => Vec2(0, 0)
}
jugador = Vec2(clamp(jugador.x + d.x, 1, ANCHO - 2), clamp(jugador.y + d.y, 1, ALTO - 2))
quedan -= 1
var i = monedas.indexOf(jugador)
if i >= 0 {
monedas.removeAt(i)
puntos += 10
}
}
/// Sin teclado: va hacia la moneda más cercana.
function teclaAutomatica(): text {
var objetivo = monedas.minBy(m => abs(m.x - jugador.x) + abs(m.y - jugador.y))
if objetivo.x > jugador.x { return "right" }
if objetivo.x < jugador.x { return "left" }
return objetivo.y > jugador.y ? "down" : "up"
}
while monedas.length > 0 and quedan > 0 {
if Console.interactive {
Console.clear()
dibujar()
mover(Console.readKey())
} else {
mover(teclaAutomatica())
}
}
dibujar()
Console.print(monedas.isEmpty() ? "¡Has ganado!" : "Se acabaron los movimientos", monedas.isEmpty() ? "green" : "red")▶ Probar en el editor
Para seguir
- Añade enemigos que se muevan solos (otra lista de
Vec2que cambia en cada turno). - Separa la lógica en
src/tablero.hezy escribe pruebas entests/(pruebas). - Para un juego en tiempo real, cambia
readKey()porpollKey()y añadeSystem.sleep(0.1)al bucle. - Mira los juegos completos de examples/juegos.
HyperEZ