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...
Comentarios
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.
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.
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.
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.
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!