jueves, 17 de noviembre de 2016

Scrolling Shooter en Love2D (I)

Bieeeen bien, parece que aún tengo algunas ganas de escribir. No sé cuánto durarán esta vez (creo que he tenido como seis o siete blogs diferentes en los últimos diez años, algunos con una sóla entrada), pero procuraré usarlas correctamente.

Voy a empezar por explicar, en castellano, algo del código que se puede ver si se sigue el tutorial de OSMStudios para iniciarse al desarrollo de juegos con LUA y Love2D. Como yo mismo soy un recién iniciado, además esto me vendrá bien para repasar y afianzar ¡todo ventajas!. No voy a dar una descripción explícita de cada parte del código, si no sólo de aquellas que me resultan más interesantes, mejorables o complicadas. Espero no liarme con las explicaciones más de la cuenta.

Movimiento

if love.keyboard.isDown('left','a') then
    if player.x > 0 then -- binds us to the map
        player.x = player.x - (player.speed*dt)
    end
elseif love.keyboard.isDown('right','d') then
    if player.x < (love.graphics.getWidth() - player.img:getWidth()) then
        player.x = player.x + (player.speed*dt)
    end
end

Este es el código original que figura en el tutorial de OSMStudios. Son un par de sencillas comprobaciones para saber si se han pulsado las teclas flecha izquierda, a, flecha derecha o d. Si es alguna de las dos primeras, moverá el objeto jugador a la izquierda, y se moverá en sentido contrario si se ha pulsado alguna de las otras dos teclas. Incluye, además, comprobaciones de posición para asegurarse de que nuestro avión no se sale del área de juego.

Me paro un momento en esto último. Player.x y player.y representan la posición x e y de la imagen de player. Hasta donde he entendido, hay que tener muy en cuenta las dimensiones de la misma para situar al objeto, dado que los valores x=0 e y=0 corresponden a la esquina superior izquierda de la imagen y son los que se usan como referencia para evitar que salgamos de la zona útil. Se recoge el valor del ancho del área de juego con love.graphics.getWidth() y se le resta el ancho de la imagen de player, así se evita que nos salgamos por la parte derecha, dado que nuestro (x,y) de la imagen no podrá pasar de ahí. Recordar de nuevo que dicho (x,y) corresponde a la esquina superior izquierda, de ahí que restemos el tamaño de la imagen para no abandonar la zona por el lado derecho. Por el lado contrario será más sencillo: mientras la posición x de la imagen sea superior a 0, podremos movernos.

Una de las propuestas finales del tutorial consiste en añadir movimiento vertical, lo cual no es difícil, pero tras implementar eso me pregunté como realizar movimiento libre, es decir, que también pudiera mover al avioncete en diagonal. Hice varias pruebas fallidas hasta darme cuenta de algo obvio (y me costó un buen rato caer en ello) que es que el código original es excluyente. Mi primera implementación de movimiento vertical era muy similar a la horizontal, por lo que no podía moverme en dos direcciones a la vez (izquierda + arriba por ejemplo). Esto es debido a la estructura excluyente, dado que si se pulsa una tecla no va a capturar otra a la vez. Finalmente mi estructura fue la siguiente:
  -- movimiento
  if love.keyboard.isDown('left', 'a') then
    if player.x > 0 then
      player.x = player.x - (player.speed*dt)
    end
  end
  if love.keyboard.isDown('right','d') then
    if player.x < (love.graphics.getWidth() - player.img:getWidth()) then
      player.x =  player.x + (player.speed*dt)
    end
  end
  if love.keyboard.isDown('up','w') then
    if player.y > (love.graphics.getHeight()/2) then
      player.y = player.y - (player.speed*dt/2)
    end
  end
  if love.keyboard.isDown('down','s') then
    if player.y < (love.graphics.getHeight() - player.img:getHeight()) then
      player.y = player.y + (player.speed*dt/2)
    end
  end

De esta forma si se pulsan dos teclas a la vez, estas serán recogidas sin problema dado que las sentencias condicionales no son excluyentes entre sí, habilitando el movimiento libre.

Hay otro aspecto interesante en este código que es la parte del cálculo de la velocidad de movimiento (player.speed*dt), pero esto lo voy a dejar para la próxima vez.

Espero que esto le sirva a alguien que se quiera iniciar al mundillo de Love2D.

No hay comentarios :

Publicar un comentario