Anuncios Google

Ultima entrega de LUA

Tutoriales Avanzados Homebrewes

Ahora vamos a escribir un juego simple en 2d, puedes editar mapas para distintos niveles. En C64 habia conjuntos de 254 caracteres de 8x8 pixeles que heran los bloques constructores del mapa. Podemos salvar este "bloque constructor" en una imagen, tambien conocido como tile set, o azulejo. Aqui hay un ejemplo para un juego de tuneles, tipo Pac-man:

Las baldosas:

Vamos a numerarlas de la 'a' a la 'p':

abcd
efgh
ijkl
mnop

Ahora podemos dibujar un mapa con ellas y mostrarlo con un poco de codigo Lua:

System.usbDiskModeActivate()
 
tiles = Image.load("tiles.png")
 
map = {
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm",
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm",
    "mmeaaaaaaaaaaaaaaaaaaaaaaaafmm",
    "mmdpnnnnnnnnnnnnnnnnnnnnnnpbmm",
    "mmdokcccccclnkccccccccccclnbmm",
    "mmdojaaaaafdnbmmmmmmmmmmmdnbmm",
    "mmdooooooobdnbmmmmmmmmmmmdnbmm",
    "mmdokccclobdnbmmmmmmmmmmmdnbmm",
    "mmdobmmmdobdnbmmmmmmmmmmmdnbmm",
    "mmdobmmmdobdnjaaaaaaaaaafdnbmm",
    "mmdobmmmdpbdnnnnnnnnnnnnbdnbmm",
    "mmdobmmmhcghcccccccccclnbdnbmm",
    "mmdojaaaaaaaaaaaaaaaaainjinbmm",
    "mmdpnnnnnnnnnnnnnnnnnnnnnnpbmm",
    "mmhccccccccccccccccccccccccgmm",
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm",
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"
}
 
function drawTile(tile, x, y)
    local tileX = math.mod(tile, 4)
    local tileY = math.floor(tile / 4)
    screen:blit(16 * x, 16 * y, tiles, 17 * tileX + 1, 17 * tileY + 1, 16, 16, false)
end    
 
while true do
    pad = Controls.read()
    if pad:start() then break end
    screen:clear()
    for y = 1, 17 do
        line = map[y]
        for x = 1, 30 do
            tile = string.byte(line, x) - string.byte("a")
            drawTile(tile, x - 1, y - 1)
        end
    end
    screen.waitVblankStart()
    screen:flip()
end

Este es el resultado:

El modo USB hace mas facil editar el mapa, porque te permite abrir tu editor salvar y recargarlo pulsando "start"

Ahora necesitamos alguna animacion:

El programa que muestra el jugador y le permite moverse, comiendo puntos y añadiendo puntuacion:

-- cargar imagenes
tiles = Image.load("tiles.png")
figure = Image.load("figure.png")
 
-- el mapa
mapSource = {
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm",
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm",
    "mmeaaaaaaaaaaaaaaaaaaaaaaaafmm",
    "mmdpnnnnnnnnnnnnnnnnnnnnnnpbmm",
    "mmdokcccccclnkccccccccccclnbmm",
    "mmdojaaaaafdnbmmmmmmmmmmmdnbmm",
    "mmdooooooobdnbmmmmmmmmmmmdnbmm",
    "mmdokccclobdnbmmmmmmmmmmmdnbmm",
    "mmdobmmmdobdnbmmmmmmmmmmmdnbmm",
    "mmdobmmmdobdnjaaaaaaaaaafdnbmm",
    "mmdobmmmdpbdnnnnnnnnnnnnbdnbmm",
    "mmdobmmmhcghcccccccccclnbdnbmm",
    "mmdojaaaaaaaaaaaaaaaaainjinbmm",
    "mmdpnnnnnnnnnnnnnnnnnnnnnnpbmm",
    "mmhccccccccccccccccccccccccgmm",
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm",
    "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm"
}
 
-- imagen en el offsreen, donde dibujamos el mapa
board = Image.createEmpty(480, 272)
 
-- dibuja una baldosa en el mapa:
function drawTile(tile, x, y)
    tile = string.byte(tile, 1) - string.byte("a")
    local tileX = math.mod(tile, 4)
    local tileY = math.floor(tile / 4)
    board:blit(16 * x, 16 * y, tiles, 17 * tileX + 1, 17 * tileY + 1, 16, 16, false)
end    
 
-- copia el mapa fuente a un vector para facilitar el acceso y dibujarlo en el offscreen
map = {}
for y = 1, 17 do
    line = mapSource[y]
    map[y] = {}
    for x = 1, 30 do
        tile = string.sub(line, x, x)
        map[y][x] = tile
        drawTile(tile, x - 1, y - 1)
    end
end
 
-- posicion actual del jugador
playerX = 6
playerY = 14
 
-- imagen actual de animacion del jugador
animation = 0
 
-- 1 = incremento en la animacion, -1: decremento
animationDirection = 1
 
-- contador de freno de la animacion
animationSlowDown = 0
 
-- control de la velocidad de movimiento. a speedStep == 0, el
-- ultimo movimiento sera evaluado, los otros movimientos solamente seran
-- salvados
speedStep = 0
 
-- ultima direccion del pad
dx = 0
dy = 0
 
-- puntuacion actual
score = 0
 
-- color del texto
white = Color.new(255, 255, 255)
 
while true do
    -- lectura del pad
    pad = Controls.read()
 
    if pad:start() then
        -- salirse al lowser / reiniciar aplicacion dependiendo de como se cargara este
        break
    end
    if speedStep == 0 then
        -- salva la posicion anterior del jugador
        oldPlayerX = playerX
        oldPlayerY = playerY
 
        -- añadir ultimo movimiento
        playerX = playerX + dx
        playerY = playerY + dy
 
        -- comprobar el nuevo valdosin
        newTile = map[playerY][playerX]
 
        -- si la posicion no esta permitida, reestablece la posicion anterior
        if newTile ~= "n" and newTile ~= "p" and newTile ~= "o" then
            playerX = oldPlayerX
            playerY = oldPlayerY
        end
 
        -- Sí esta en una baldosa que puede ser comida,la come:
        if newTile == "p" then score = score + 5 end
        if newTile == "o" then score = score + 1 end
        if newTile == "p" or newTile == "o" then
            -- pone el fondo
            map[playerY][playerX] = "n"
 
            -- dibuja el fondo
            drawTile("n", playerX - 1, playerY - 1)
        end
 
        -- reestablece la ultima posicion
        dx = 0
        dy = 0
    else
        -- comprobar el pad
        if pad:up() then
            dy = -1
        elseif pad:down() then
            dy = 1
        elseif pad:left() then
            dx = -1
        elseif pad:right() then
            dx = 1
        end
    end
 
    -- incrementar el contador de velocidad de pasos
    speedStep = speedStep + 1
    if speedStep == 5 then
        speedStep = -1
    end
 
    -- dibuja en el offscreen
    screen:blit(0, 0, board, 0, 0, board:width(), board:height(), false)
 
    -- dibuja la animacion actual del jugador
    screen:blit((playerX - 1) * 16 - 4, (playerY - 1) * 16 - 4, figure, 1 + 25 * animation, 1, 24, 24)
 
    -- calcula la proxima imagen de animacion
    animationSlowDown = animationSlowDown + 1
    if animationSlowDown == 3 then
        animationSlowDown = 0
        animation = animation + animationDirection
        if animation == 4 then
            animationDirection = -1
        elseif animation == 0 then
            animationDirection = 1
        end
    end
 
    -- imprime puntuacion
    screen:print(10, 260, "Score: " .. score, white)
 
    -- espera el proximo refresco de pantalla para dibujar el offscreen
    screen.waitVblankStart()
    screen:flip()
end

Notar que las baldosas son dibujadas en el offscreen, debido a que dibujar multiples baldosas es mas lento que dibujar una imagen del mismo tamaño que todas las baldosas. Con este truco podemos alcanzar los 60fps.

Algunas modificaciones posibles son algunos oponentes, usar un fondo transparente para los azulejos y dibujar estos sobre un fondo predefinido, o usar multiples mascaras con multiples fondos o mapas que coordinen la posicion y las partes con diferentes tamaños etc...

4.5
Tu voto: Ninguno Votos totales: 4.5 (30 votos)

Anuncios Google

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

eso,eso, todos a programar

eso,eso, todos a programar en lua, que os puedo decir que no es tan dificil como parece.

si hasta yo me he atrevido con el lua y parece que algo va saliendo, jajaja.

Muy bueno el tuto, seguid asi.
un saludo
Spirax

que no sea el ultimo

espero que este tutorial no sea el ultimo ya que me los e mirado todos i estan todos muy bien i este es una pasada i ahora empiza haber muchas posibilidades, i queria ponerme a provar cosas.

Imagen de Unicorn

Vamos a actualizar la new del LUA Player

ya que en el nuevo Loader de Fanjita el Lua 0.16 es funcional en 2.01+ con el GTA (no en 2.00...). A ver si asi mas gente se anima a programar...son muchiiiiiisimos los usuarios que disfrutarian el juego!!!


Para recibir ayuda más rápidamente, recomendamos que pongas títulos descriptivos y no utilices abreviaturas (estilo MSN) en tus post de los foros. Recuerda revisar el Manual del perfecto forero y las Normas de la Comunidad.

Imagen de CLARK

Espero mas

Tambien espero k no sea el ultimo tutorial de lau k se hace ya k creo k como a mi ahi muchos usuarios k les facina este tema debido ala satisfaccion o emocion de correr en tu propio psp algo programado y hecho por ti mismo aunque solo es algo muy sencillo pero por algo se empiesa no creen.

Imagen de Miquel Carol

Esperemos que no

Llamame Kchondo, yo espero que no sea TU ultima entrega relacionada con LUA, ejejeje. >8)

Por cierto, felicidades Mordi, en serio el tuto completo es un Loox.


Imagen de mordi

Sigo currando

Bueno tras un finde sabatico, voy a seguir currando un poco el lua, entre examen y examen, (parece que las fechas cuanto mas agobiantes, mas productivas) voy a ver si saco una guia de las funciones implementadas en lua, de manera que sirva como "guia de referencia" para todo aquel que quiera acercarse a la programacion, permitiendo muchas msa acciones que las expuestas en estos tutoriales.

 

--flotaré, como patitos de goma en el agua estancada de la vida--


¡Un verdadero guerrero Klingon nunca utiliza comentarios en su código!

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.