Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

Ejemplo: Juego Completo

Esta lección construye un pequeño juego de recolección. El jugador se mueve por una escena, se choca con paredes, recoge monedas e imprime una puntuación final cuando el juego termina.

En lugar de pegar todo el script a la vez, el ejemplo está dividido en las mismas partes que usarás en la mayoría de los proyectos de Tiniest2D:

  • variables de activos y estado
  • start()
  • onUpdate(dt)
  • onCollision(objA, objB)
  • end()

1. Activos y Estado del Juego

La primera sección crea los activos y variables que el resto del script usará. Los sprites son imágenes, la escena es el nivel, el jugador es un objeto colocado en esa escena, y las variables de puntuación/velocidad almacenan un estado simple del juego.

// Crear activos
var playerImg = Sprite(16, 16)
var wallImg = Sprite(16, 16)
var coinImg = Sprite(8, 8)
var level = Scene()

// Crear objeto jugador
var player = Object("Player")

// Estado del juego
var score = 0
var speed = 100

En este punto, las variables existen, pero el juego aún no ha colocado nada en la escena. Esa configuración ocurre en start().

2. La Función start()

start() se ejecuta una vez cuando el juego comienza. Úsala para configurar objetos, establecer la primera escena, posicionar la cámara y preparar cualquier valor inicial.

func start() {
    // Configurar jugador
    setSprite(player, playerImg)
    setCollisionType(player, COLLISION_DYNAMIC())
    setX(player, 50)
    setY(player, 50)
    addObject(level, player)

    // Establecer escena inicial
    setScene(level)

    // Centrar la cámara en el jugador
    setCameraX(level, getX(player))
    setCameraY(level, getY(player))
    setCameraZoom(level, 3)

    print("¡Recoge las monedas!")
}

El jugador usa COLLISION_DYNAMIC() porque debe chocar y ser empujado fuera de las paredes. La cámara comienza centrada en el jugador, por lo que la vista del nivel comienza en el lugar correcto.

3. La Función onUpdate(dt)

onUpdate(dt) se ejecuta cada fotograma. Aquí es donde el jugador lee la entrada, se mueve, actualiza la cámara y verifica las teclas de reinicio.

dt significa "tiempo delta": la cantidad de tiempo desde el fotograma anterior. Multiplicar el movimiento por dt hace que la velocidad de movimiento sea más consistente en diferentes tasas de fotogramas.

func onUpdate(dt) {
    // Movimiento del jugador
    var moveX = 0
    var moveY = 0

    if (isKeyHeld(KEY_LEFT()) || isKeyHeld(KEY_A())) {
        moveX = -1
    }
    if (isKeyHeld(KEY_RIGHT()) || isKeyHeld(KEY_D())) {
        moveX = 1
    }
    if (isKeyHeld(KEY_UP()) || isKeyHeld(KEY_W())) {
        moveY = -1
    }
    if (isKeyHeld(KEY_DOWN()) || isKeyHeld(KEY_S())) {
        moveY = 1
    }

    // Aplicar movimiento
    setX(player, getX(player) + moveX * speed * dt)
    setY(player, getY(player) + moveY * speed * dt)

    // La cámara sigue al jugador
    setCameraX(level, getX(player))
    setCameraY(level, getY(player))

    // Reiniciar nivel con la tecla R
    if (isKeyPressed(KEY_R())) {
        resetScene(level)
        setX(player, 50)
        setY(player, 50)
        score = 0
        print("¡Nivel reiniciado!")
    }
}

El código de movimiento construye una dirección a partir de la entrada del teclado. Luego, agrega esa dirección a la posición actual del jugador. La cámara se actualiza después del movimiento para que siga la nueva posición.

4. La Función onCollision(objA, objB)

onCollision(objA, objB) se ejecuta cuando dos objetos colisionan. En este ejemplo, las monedas deberían usar COLLISION_TRIGGER(). Los objetos de activación informan solapamientos, pero no bloquean el movimiento.

func onCollision(objA, objB) {
    var nameB = getName(objB)
    var typeB = getCollisionType(objB)

    // Colección de monedas (las monedas deberían ser de tipo TRIGGER en el editor de escenas)
    if (typeB == COLLISION_TRIGGER()) {
        removeObject(level, objB)
        score = score + 1
        print("Puntuación: " + score)
    }
}

Cuando el jugador toca un activador, el script elimina ese objeto de la escena y aumenta la puntuación. Este es el patrón básico para recoger objetos, llaves, potenciadores y puntos de control.

5. La Función end()

end() se ejecuta cuando el juego se detiene. Este ejemplo solo imprime la puntuación final, pero los juegos más grandes pueden usar esta función para limpieza o mensajes de depuración finales.

func end() {
    print("Puntuación final: " + score)
}

Configurando el Ejemplo

  1. Crear los sprites:
  2. Ctrl+Click en playerImg, dibuja un personaje (por ejemplo, una figura de palo simple)
  3. Ctrl+Click en wallImg, dibuja un bloque sólido
  4. Ctrl+Click en coinImg, dibuja un pequeño círculo o diamante

  5. Diseñar la escena:

  6. Ctrl+Click en level
  7. Selecciona wallImg en el panel izquierdo, establece la colisión en "Estática"
  8. Pinta las paredes alrededor de los bordes y crea un laberinto
  9. Selecciona coinImg, establece la colisión en "Ninguna" para los azulejos decorativos de monedas
  10. Coloca monedas alrededor del nivel como guías visuales

  11. Crear objetos de moneda de activación:

Los sprites estampados en la escena son útiles para azulejos y decoración, pero las monedas coleccionables deben ser objetos para que los callbacks de colisión puedan eliminarlas. Agrega objetos de monedas de la siguiente manera:

var coin1 = Object("Coin1")
var coin2 = Object("Coin2")

func start() {
    // ... configuración del jugador ...

    // Configurar monedas como activadores
    setSprite(coin1, coinImg)
    setCollisionType(coin1, COLLISION_TRIGGER())
    setX(coin1, 100)
    setY(coin1, 80)
    addObject(level, coin1)

    setSprite(coin2, coinImg)
    setCollisionType(coin2, COLLISION_TRIGGER())
    setX(coin2, 150)
    setY(coin2, 120)
    addObject(level, coin2)

    // ... resto de start ...
}

Este mismo patrón se puede expandir para más monedas, enemigos, puertas o cualquier objeto que necesite comportamiento de script.