Como hacer un Snake en Love2D

Archivos

Comenzamos creando los archivos main.lua y conf.lua, en el conf.lua solo añadimos lo siguiente:

function love.conf(t)
  t.window.title = "Snake - made in Love2D by Deybis Melendez"
  t.window.width = 400
  t.window.height = 400
end


function love.load()

Vamos a comenzar declarando las variables que utilizaremos, cada linea de código tendrá un comentario con su explicación:

  t = 20 -- tamaño de cada celda
  timer = 0 -- Controlaremos el tiempo de ejecución con esta variable
  perder = false -- Para controlar cuando pierde el juego
  ganar = false -- Para controlar cuando gana el juego
  love.graphics.setBackgroundColor(0.6039, 0.7725, 0.0117) -- Colocaos un fondo verde
  area = {} -- Nos ayudará a definir un area de juego
  area.x = t -- La posición del area en la parte superior izquierda
  area.y = t * 2 --La posición del area en la parte inferior izquierda
  area.w = love.graphics.getWidth() - t * 2 -- (Width o Ancho) La posición del area en la parte superior derecha
  area.h = love.graphics.getHeight() - t * 3 -- (Height o Alto) La posición del area en la parte inferior derecha
  snake = {} -- Los datos de la serpiente
  snake.velX = 20 -- Velocidad inicial en X de la serpiente
  snake.velY = 0 -- Velocidad inicial en Y de la serpiente
  snake.cola = {} -- contiene todos los puntos x , y de cada parte de la serpiente
  snake.cola[0] = {x = area.x , y = area.y} -- Cabeza de la serpiente
  comida = {} -- Los datos de la comida
  comida.radio = 8 -- La comida será representada por un circulo, por lo que necesitamos un radio
  comida.offset = t/2 -- Ajuste de la posición del circulo en la celda.
  comida.x = (math.random((area.w - area.x)/t)) * t + area.x --Posición inicial random en el eje X
  comida.y = (math.random((area.h - area.y)/t)) * t + area.y -- Posición inicial random en el eje Y


function love.draw()

Ahora daremos las instrucciones para dibujar el juego:

  love.graphics.setColor(0,0.1,0) -- El color que utilizaremos para dibujar el juego
  if not perder  and not ganar then -- Si no ha perdido o no ha ganado entonces...
    love.graphics.print("Puntuación: " .. #snake.cola, 16, 16) -- Imprimimos la Puntuación en la posición 16,16
  elseif not perder and ganar then -- Si no ha perdido pero ha ganado entonces...
    love.graphics.print("Ganaste! presiona R para reiniciar :D" , 16 , 16) -- Imprimimos que ganamos en la posición 16,16
  else -- Si no se cumplen las condiciones entonces
    love.graphics.print("Perdiste! Tu Puntuación es: " .. #snake.cola .. ", presiona R para reiniciar", 16 , 16) -- Imprimimos que perdiste en la posición 16,16
  end
  for i = 0, #snake.cola do -- Obtenemos cada contenido de snake.cola, es decir, cada x,y (cada parte de la serpiente)
    -- A continuación por cada Posición en x , y que tiene snake.cola, dibujaremos 4 cuadrados para simular el estilo retro del Nokia.
    love.graphics.rectangle("fill", snake.cola[i].x, snake.cola[i].y,t/2 - 1 , t/2 - 1)
    love.graphics.rectangle("fill", snake.cola[i].x + t/2, snake.cola[i].y, t/2 - 1, t/2 - 1)
    love.graphics.rectangle("fill", snake.cola[i].x, snake.cola[i].y + t/2, t/2 - 1, t/2 - 1)
    love.graphics.rectangle("fill", snake.cola[i].x + t/2, snake.cola[i].y + t/2, t/2 - 1, t/2 - 1)
  end
  love.graphics.rectangle("line", area.x, area.y, area.w , area.h ) --Dibujamos la linea que representará el area del juego
  love.graphics.circle("line", comida.x + comida.offset, comida.y + comida.offset, comida.radio) -- Dibujamos el circulo que representa la comida
end



function love.update(dt)

Primero, para ordenar un poco el código y se entienda, vamos a crear unas funciones, esto fuera del love.update:

function comer()

if snake.cola[0].x == comida.x and snake.cola[0].y == comida.y then -- Si la serpiente está encima de la comida entonces...
    snake.cola[#snake.cola + 1] = {x = snake.cola[#snake.cola].x - snake.velX , y  = snake.cola[#snake.cola].y - snake.velY} -- Añadimos una cola a la serpiente.
    if #snake.cola < 361 then -- Si la serpiente no tiene ocupado todo el area del juego, area es 19x19
      while contains(snake.cola , comida, 0) do -- Repetimos el siguiente codigo si la comida aparece encima de la serpiente
        -- damos una nueva posición random hasta que la comida esté fuera de la serpiente.
        comida.x = (math.random((area.w - area.x)/t)) * t + area.x
        comida.y = (math.random((area.h - area.y)/t)) * t + area.y
      end
    else -- Si la serpiente ocupa todo el area entonces...
      ganar = true -- Has ganado.
    end
  end
end



function mover()

  -- El sguiente for significa: Para i = cantidad de partes de la serpiente , repetimos el codigo hasta llegar que i = 0, restando -1 a i en cada repetición.
  for i = #snake.cola , 0 , -1 do -- Obtenemos cada parte de la serpiente, comenzando desde la cola hasta la cabeza, (en orden descendente, ej: 5,4,3,2,1,0)
    if i == 0 then -- snake.cola[0] es la cabeza de la serpiente, por lo que con ella controlamos el movimiento.
      snake.cola[0].x = snake.cola[0].x + snake.velX
      snake.cola[0].y = snake.cola[0].y + snake.velY
    else -- Para las demás hacemos que cada parte de la cola sea igual a la vecina anterior (i-1)
      snake.cola[i].x = snake.cola[i-1].x
      snake.cola[i].y = snake.cola[i-1].y
    end
  end
end



function contains(tabla,val,num)

-- Debido a que en Lua no existe un has() para saber si alguna variable existe en una tabla,
-- He conseguido esta función en internet que hace lo mismo, con la diferencia que he añadido una variable num
-- Que utilizaremos en 2 variantes en nuestro juego.
function contains(tabla, val, num)
   for i=num,#tabla do
      if tabla[i].x == val.x and tabla[i].y == val.y then
         return true
      end
   end
   return false
end





Ahora sí, añadimos el love.update(dt):

function love.update(dt)

  if timer < 0.1 then -- Con esto controlaremos cada actualización de pantalla a 0.1 segundos
    timer = timer + dt
  elseif not perder and not ganar then -- El juego no continuará si has perdido o ganado
    timer = 0 -- Indica que el contador del tiempo de cada frame comienza
    comer()
    mover()
    if contains(snake.cola , snake.cola[0] , 1) then -- Revisamos si snake.cola tiene un valor igual a la cabeza(snake.cola[0]), añadimos 1 para que no cuente la cabeza.
      perder = true -- Si ha colisionado entonces ha perdido
    end
    -- Aqui controlamos que la serpiente se mantenga dentro del area, reapareciendo en el lado opuesto.
    if snake.cola[0].x > area.w then
      snake.cola[0].x = area.x
    elseif snake.cola[0].x < area.x then
      snake.cola[0].x = area.w
    elseif snake.cola[0].y > area.h + t then
      snake.cola[0].y = area.y
    elseif snake.cola[0].y < area.y then
      snake.cola[0].y = area.h + t
    end
  end
end



function love.keypressed()

Por último, añadimos la función del teclado y como manipulamos el juego:

function love.keypressed(key, scancode, isrepeat)
  if key == "up" and snake.velY ~= t then
    snake.velX = 0
    snake.velY = - t
  elseif key == "down" and snake.velY ~= -t then
    snake.velX = 0
    snake.velY = t
  elseif key == "left" and snake.velX ~= t then
    snake.velX = - t
    snake.velY = 0
  elseif key == "right" and snake.velX ~= -t then
    snake.velX = t
    snake.velY = 0
  elseif key == "r" and (perder or ganar) then -- Solo ejecuta si ha perdido o ganado.
    snake.cola[0] = {x = area.x , y = area.y} -- Colocamos la cabeza de la serpiente en el lugar inicial
    for i = 1 , #snake.cola do -- Borramos todo el contenido de snake.cola menos la cabeza (snake.cola[0])
      snake.cola[i] = nil
    end
    -- Reiniciamos las variables del juego a su valor inicial...
    snake.velX = t
    snake.velY = 0
    comida.x = (math.random((area.w - area.x)/t)) * t + area.x
    comida.y = (math.random((area.h - area.y)/t)) * t + area.y
    perder = false
    ganar = false
  end
end





Y listo, ya tenemos un juego básico de snake al puro estilo de los antiguos celulares Nokias,  a continuación un pequeño gameplay del juego:

 

Tutorial como hacer un Pong en Love2D


Assets:

Primero descargaremos los siguientes assets para este proyecto

https://opengameart.org/content/pong-programmer-art

https://opengameart.org/content/pong-sfx

https://www.dafont.com/es/squarefont.font

Creamos una carpeta que nombraremos "pong" y unas sub-carpetas llamadas "sprites" , "sonidos" , "fuentes" y añadimos cada archivo en su respectiva carpeta.

conf.lua

Crearemos un archivo y lo llamaremos conf.lua, en él añadiremos el siguiente código para configurar el proyecto:

function love.conf(t)
  t.window.title = "Pong - made in Love2D by Deybis Melendez"
  t.window.width = 800
  t.window.height = 600
end

main.lua

love.load()

En el love.load vamos a declarar las variables para la bola, la barra izquierda y barra derecha, la imagen de background y los sonidos que utilizaremos:

function love.load()
  bola = {}
  bola.velocidad = 300
  bola.movX, bola.movY = -bola.velocidad , bola.velocidad
  bola.sprite = love.graphics.newImage("sprites/fancy-ball.png") -- El sprite mide 32x32
  bola.x , bola.y = love.graphics.getWidth()/2 - 16 , love.graphics.getHeight()/2 - 16

  barra1 = {}
  barra1.sprite = love.graphics.newImage("sprites/fancy-paddle-blue.png")
  barra1.x , barra1.y = 32, love.graphics.getHeight()/2 - 64 -- La barra mide 32x128

  barra2 = {}
  barra2.sprite = love.graphics.newImage("sprites/fancy-paddle-green.png")
  barra2.x , barra2.y = love.graphics.getWidth() - 64 , love.graphics.getHeight()/2 - 64

  background = love.graphics.newImage("sprites/fancy-court.png")

  fuente = love.graphics.newFont("fuentes/Square.ttf", 32)

  pop = love.audio.newSource("sonidos/Pop.ogg", "static")
  score = love.audio.newSource("sonidos/Score.ogg", "static")
  velocidadBarra = 300
  puntaje1 , puntaje2 = 0 , 0
end

love.draw()

Ahora dibujaremos todo el juego en pantalla:

function love.draw()
  love.graphics.draw(background, 0, 0)
  love.graphics.draw(bola.sprite, bola.x, bola.y)
  love.graphics.draw(barra1.sprite, barra1.x, barra1.y)
  love.graphics.draw(barra2.sprite, barra2.x, barra2.y)
  love.graphics.setFont(fuente)
  love.graphics.print(puntaje1, love.graphics.getWidth() * 1/3 , 32)
  love.graphics.print(puntaje2, love.graphics.getWidth() * 2/3 , 32)
end


Funciones


Vamos a añadir 2 funciones para no repetir el código:

function clamp(min, val, max) -- Nos retorna un rango de valor, desde un mínimo a un máximo
  return math.max(min, math.min(val, max))
end


function reiniciar()  -- Reiniciamos la partida si la bola sale de pantalla
  bola.x , bola. y = love.graphics.getWidth()/2 - 16 , love.graphics.getHeight()/2 - 16
  bola.movX = - bola.movX
  bola.movY = - bola.movY
  play(score)
end

function play(sonido)  -- Un simple control de sonido.
  if sonido:isPlaying() then
    love.audio.stop()
    love.audio.play(sonido)
  else
    love.audio.play(sonido)
  end


love.update(dt)

En el update, añadiremos el movimiento de la bola:

  --Movimiento de la bola
  bola.x = bola.x + bola.movX * dt
  bola.y = bola.y + bola.movY * dt


Luego añadimos el código para el rebote desde arriba y abajo:

  -- Rebote de la bola desde arriba hacia abajo
  if bola.y < 0 then
    bola.movY = bola.velocidad
    play(pop)
  elseif bola.y > love.graphics.getHeight() - 32 then
    bola.movY = - bola.velocidad
    play(pop)
  end


Ahora el en caso de que la bola salga de la pantalla por los lados:

  -- Si la bola sale de pantalla reinicia su posición y da puntajes
  if bola.x < -16 then
    reiniciar()
    puntaje2 = puntaje2 + 1
  elseif bola.x > love.graphics.getWidth() then
    reiniciar()
    puntaje1 = puntaje1 + 1
  end


Ahora añadimos el movimiento de las barras, el control del juego:

  -- Control del juego
  if love.keyboard.isDown("a") then
    barra1.y = barra1.y - velocidadBarra * dt
  elseif love.keyboard.isDown("z") then
    barra1.y = barra1.y + velocidadBarra * dt
  end
  if love.keyboard.isDown("up") then
    barra2.y = barra2.y - velocidadBarra * dt
  elseif love.keyboard.isDown("down") then
    barra2.y = barra2.y + velocidadBarra * dt
  end


Ahora limitamos el movimiento de las barras para que no salga de la pantalla:

  barra1.y = clamp(0, barra1.y, love.graphics.getHeight() - 128) -- 128 píxeles mide el alto de la barra
  barra2.y = clamp(0, barra2.y, love.graphics.getHeight() - 128)


Ahora añadimos el código que controla el rebote de la bola en las barras:

  --Rebote de la bola cuando golpea las barras
  if bola.x <= barra1.x + 32 and bola.x >= barra1.x and bola.y >= barra1.y and bola.y + 32 <= barra1.y + 128 then
    bola.movX = bola.velocidad
    play(pop)
  elseif bola.x + 32 >= barra2.x and bola.x <= barra2.x and bola.y >= barra2.y and bola.y + 32 <= barra2.y + 128 then
    bola.movX = - bola.velocidad
    play(pop)
  end



Ahora ya puedes jugar.

Puedes encontrar el proyecto en mi Github: https://github.com/DeybisMelendez/Love2DBlog/tree/master/pong
Tambien puedes jugar el juego en Itch.io:  https://damv.itch.io/pong

Exportar para Web

Vamos a exportar nuestro proyecto Flappy Bird para la web usando Emscripten.

Requisitos:

Tener instalado Care, para ellos solo usaremos sudo apt install care

Tener instalado Python 2.7 La mayoría de distribuciones lo traen instalado.

Los pasos son los siguientes:

Nos ubicamos en la terminal en una carpeta donde podamos tener a mano el "programa" que utilizaremos para exportar a web, y utilizaremos el comando:

git clone https://github.com/TannerRogalsky/love.js.git

Luego nos ubicamos en la carpeta love.js y utilizamos el siguiente comando:

git submodule update --init --recursive



Una vez que haya terminado, nos ubicamos en la carpeta release-compatibility y utilizaremos el siguiente comando:

python ../emscripten/tools/file_packager.py game.data --preload [ubicacion/de/tu/juego]@/ --js-output=game.js



Vamos a sustituir [ubicacion/de/tu/juego] por la dirección donde tenemos el proyecto, importante dejar el @/ y no usar caracteres especiales en la dirección.

El conjunto de archivos que nos queda es el juego exportado, para probarlo nos iremos al navegador y escribiremos la ubicacion del archivo index.html, por ejemplo:

/home/damv/Documentos/love.js/release-compatibility/index.html

Ahora nos debería ejecutar el juego:


Nota: He modificado el index.html para ponerle un título, con un poco de conocimiento html5 puedes acomodar a tu gusto la forma como se muestra el juego.

He publicado el juego en Itch puedes probarlo aquí:

https://damv.itch.io/ejemplo-de-juego-flappy-bird-en-love2d

Tutorial como hacer un Flappy Bird en Love2D - Parte 1

Empezaremos creando un proyecto nuevo en Atom, haremos una carpeta llama "flappyBird" y en Atom iremos a File - Add Project Folder. Seleccionamos la carpeta de nuestro proyecto.

Ahora crearemos el archivo conf.lua y le añadiremos lo siguiente:

function love.conf(t)
  t.window.title = "Flappy Bird - made in Love2D by Deybis Melendez"
  t.window.width = 512
  t.window.height = 288
end




Guardamos el archivo con Ctrl +S, y ahora creamos un archivo nuevo llamado main.lua.

El main.lua:

function love.load():

Comenzaremos con la funcion love.load y añadiremos las variables que utilizaremos para manipular el pajaro, en este caso, el pajaro será representado por un circulo rojo, no utilizaremos imágenes.

Primero añadimos una tabla pajaro = {} esto nos servirá para mantener toda la información del pajaro en un solo lugar, como la posicion, radio del circulo, color, etc.

Luego añadiremos las variables a continuación:

pajaro.radio = 10
pajaro.x = love.graphics.getWidth() / 2 - pajaro.radio
pajaro.y = love.graphics.getHeight() / 2 - pajaro.radio
pajaro.r , pajaro.g , pajaro.b = 255 , 0 , 0 -- Indicamos los colores RGB
pajaro.grav = 20

pajaro.mov = 0
pajaro.salto = 5
pajaro.maxY = love.graphics.getHeight() - pajaro.radio

pajaro.minY = pajaro.radio
end --Indica que la funcion love.load termina ahí.

Explicación:
radio: indicamos el radio del circulo, 10 pixeles de radio.
x,y: calculamos el centro de la pantalla, restando la mitad del ancho y alto respectivamente de la pantalla y lo restamos con el radio.
r, g, b: representa el numero RGB que coloreará el circulo.
grav: el valor de la gravedad que aplicaremos al pajaro.
mov: representa el movimiento en frames del pajaro.
salto: Fuerza que aplicaremos para que el pajaro vuele.
maxY, minY: con esto limitamos a que el pajaro no salga de la pantalla, aplicando una altura maxima (maxY) y una minima (minY)

Nos debe quedar así:


function love.update(dt):

Ahora aplicaremos la lógica del pajaro escribiendo lo siguiente:

  -- Movimiento del pajaro
  pajaro.y = pajaro.y + pajaro.mov -- Indicamos el movimiento en la posicion
  pajaro.mov = pajaro.mov + pajaro.grav * dt -- Aplicamos gravedad al movimiento
  -- Aplicamos limite para que el pajaro no salga de pantalla
  if pajaro.y > pajaro.maxY then -- Si la posicion del pajaro es mayor al limite maximo entonces...
    pajaro.y = pajaro.maxY -- Coloca el pajaro en el limite maximo
    pajaro.mov = 0 -- Su movimiento es 0
  elseif pajaro.y < pajaro.minY then -- además si la posicion del pajaro es menor que el limite minimo entonces...
    pajaro.y = pajaro.minY -- Coloca el pajaro en el limite minimo
    pajaro.mov = 0
  end -- Siempre hay que indicar que el if termina con end.
end


La multiplicación de pajaro.grav por dt es para que el el movimiento se regule en base a la media del fps del juego, y que no dependa de la velocidad de los frames por segundos, que puede variar según la caracteristica del PC.

Nos debe quedar así:


function love.draw():

Ahora que ya tenemos la lógica básica del pajaro, nos hace falta dibujarlo en pantalla, para ello, vamos a escribir:

  -- Dibujamos el pajaro
  love.graphics.setColor(pajaro.r, pajaro.g, pajaro.b)
  love.graphics.circle("fill", pajaro.x, pajaro.y, pajaro.radio)
end


Primero seleccionamos el color que utilizaremos para dibujar el circulo con  love.graphics.setColor() esta función acepta 4 valores, el codigo RGB y un canal alfa. Es decir, Le podemos indicar por separado cuanto R (rojo), G(verde), B (azul), alfa (transparencia) va a tener lo que vamos a dibujar, el canal alfa puede ser omitido ya que por default vale 1. Los codigos RGB los podemos conseguir facilmente en internet.

Segundo indicamos que dibujaremos un circulo con love.graphics.circle() acepta 4 valores, el modo, que puede ser "fill" (rellenar) o "line" (linea), la posicion x, la posicion y, y el radio del circulo.

Nos debe quedar así:


function keypressed(key):

Esta función se ejecuta cuando una tecla es presionada, escribiremos lo siguiente:

-- Controles
function love.keypressed(key)
  if key == "w" then -- Si "key" es igual a "w" entonces...
    pajaro.mov = - pajaro.salto -- Al movimiento del pajaro le restamos el salto.
  end
end


En total el código nos debe quedar así:


Ahora guardamos todo, y si ejecutamos el proyecto, por ahora deberiamos ver el pajaro (circulo rojo) con gravedad y al presionar W pueda hacer saltos en el aire.


Tutorial como hacer un Flappy Bird en Love2D - Parte 2

Continuamos con el tutorial de Flappy Bird, ahora en el love.load() añadiremos el siguiente código:

tubo = {}
tubo.ancho = 20
tubo.alto = love.graphics.getHeight()
tubo.x = love.graphics.getWidth() - 10
tubo.y = love.math.random(- 100 , - tubo.alto) --Nos dará un valor random de -tubo.alto hasta -100
tubo.r , tubo.g , tubo.b = 0 , 255 , 0 -- equivalente al color verde
tubo.limite = - tubo.ancho
tubo.mov = 200 -- Movimiento del tubo en el eje X


Esto nos debe quedar así:



Si nosotros colocaramos tubo.y = 0 se dibujaría un rectangulo verde en vertical que cubriría toda la pantalla, nosotros queremos dejar un margen de 100 pixeles para que el pajaro pueda pasar en medio, es por eso que obtenemos un valor random desde -100 en el eje y, entonces, a partir de esa posición, podemos subir el tubo hasta que la parte baja del tubo quede en el limite, por eso ponemos que nos dé un valor random desde -tubo.alto.

Aquí una gráfica muy mal hecha posiblemente por falta de presupuesto:

Es por eso que es necesario que la altura maxima en el eje y sea -100, para dejar un espacio minimo. Sin embargo, en el juego original hay dos tubos y no uno, bien, vamos ahorrar un poco de código porque utilizaremos el mismo tubo para dibujar dos, unicamente aumentando 100 pixeles al eje Y.

Nos dirigimos directamente a love.draw() y escribiremos lo siguiente:

  -- Dibujamos los tubos
  love.graphics.setColor(tubo.r, tubo.g, tubo.b) -- Seleccionamos el color
  -- Primer tubo
  love.graphics.rectangle("fill", tubo.x, tubo.y, tubo.ancho, tubo.alto)
  -- Segundo tubo
  love.graphics.rectangle("fill", tubo.x, tubo.y + tubo.alto + 100, tubo.ancho, tubo.alto)


Esto nos debe quedar así:



Como podrás ver, usamos la misma tabla tubo para dibujar dos tubos, la diferencia es que al segundo tubo le sumamos el alto del tubo mas 100, esto es para porque el punto de origen del dibujado del rectangulo es en la esquina superior izquierda.

Por último, hay que darle movimiento al tubo, sí, al tubo, no es buena idea hacer que se mueva el pajaro, lo que haremos será simular que el pajaro está volando y en movimiento. Ahora escribiremos lo siguiente en el love.load():

  --Movimiento de los tubos
  tubo.x = tubo.x - tubo.mov * dt
  if tubo.x < tubo.limite then
    tubo.x = love.graphics.getWidth()
    tubo.y = love.math.random(- 100 , - tubo.alto)
  end


Esto nos debería quedar así:


En la primera línea, aplicamos el movimiento, siempre multiplicando por dt para equilibrar el movimiento, luego en la siguiente línea revisamos si el tubo es menor al limite del tubo, una vez cumplida esa condición, colocamos los tubos en la parte derecha de la pantalla, y luego randomizamos una vez mas la posición en Y, para que no reaparezca en la misma posición.

Bien ahora, el juego debería aparecer los tubos.


Tutorial como hacer un Flappy Bird en Love2D - Parte 3

Para finalizar este tutorial, vamos a detectar que el pajaro "choca" con los rectangulos, y añadiremos la puntuación.

En el love.load() añadiremos lo siguiente:

puntuacion = 0
puntoSumado = false


puntoSumado lo utilizaremos para controlar que puntuación no se suma varias veces...

Ahora en el love.update() añadimos lo siguiente:

  if (pajaro.x > tubo.x) and (pajaro.x < tubo.x + tubo.ancho) then
    if ((pajaro.y - pajaro.radio) < (tubo.y + tubo.alto)) or ((pajaro.y + pajaro.radio) > (tubo.y + tubo.alto + 100)) then
      tubo.r , tubo.g , tubo.b = 0 , 0 , 255 -- Color azul
    elseif not puntoSumado then
      puntuacion = puntuacion + 1
      puntoSumado = true
    end
  else
    tubo.r , tubo.g , tubo.b = 0 , 255 , 0
    puntoSumado = false
  end


En la primera linea detectamos si el pajaro está entre los tubos (chocando o no), significa, si la posición del pajaro es mayor a la del tubo y la posicion del pajaro es menor a la del tubo mas su ancho.

En la segunda linea detectamos si el pajaro está en el area del primer rectangulo o en el area del segundo rectangulo, significa, si la posicion del pajaro menos su radio es menor a la posicion del tubo mas su alto o si la posicion del pajaro mas su radio es mayor a la del tubo mas su alto mas 100 pixeles...

Si estas condiciones se cumplen, cambiaremos el color del tubo a azul.

Ahora analizaremos la línea del elseif:

Esta línea en adelante lo que significa es, además si puntoSumado no es verdadero (not invierte el booleano) entonces sumamos puntuacion mas 1 y cambiamos puntoSumado a verdadero,

En el else:
En else colocamos el codigo que se ejecuta si no se cumple ninguna condición, una vez que el pajaro sale de la zona del tubo (la primera condición) pasaremos el color del tubo a verde otra vez, y puntoSumado a false.

Es importante mantener la identación correcta en el proyecto, ese espacio que dejamos con Tab para indicar a qué pertenece cada linea de código. Te dejo el link de Wikipedia sobre Identación: Identación

Por ultimo en love.draw() colocamos el código para imprimir nuestra puntuación:

  -- Imprimimos en pantalla la puntuacion
  love.graphics.setColor(255 , 255 , 0) -- Color amarillo.
  love.graphics.print("Puntuación: " .. puntuacion, 32 , 32)


Y ya tenemos listo nuestro juego básico de Flappy Bird.

Te dejaré el link del proyecto para que puedas descargarlo y verlo en tu PC.

https://github.com/DeybisMelendez/Love2DBlog/tree/master/flappyBird


Como instalar Lua y Love2D en Linux

Instalando Lua

Instalar Lua es fácil, podemos utilizar un comando: sudo apt install lua5.3

Tu primer Hola Mundo en Lua:


Crea con un editor de texto un archivo con nombre main.lua
Escribe print("Hola mundo!")


Guarda el archivo, abrimos la terminal y nos ubicamos en la carpeta donde guardamos el archivo.



Escribimos el comando lua5.3 main.lua


Instalando Love2D

Para instalar Love2D utilizaremos el siguiente comando: 

sudo add-apt-repository ppa:bartbes/love-stable
sudo apt-get update
sudo apt-get install love

Tu primer Hola mundo con Love2D:

Borra lo que escribimos en main.lua o crea un nuevo archivo.
Escribe el siguiente codigo, recuerda que la identación (el espacio vacío al inicio de love.graphics..) se escribe con Tab:

function love.draw()
    love.graphics.print("Hello World", 400, 300)
end



Ahora ejecutamos con el comando:  love /ubicacion/del/archivo
Nota: no debes incluir el main.lua en la dirección ya que love busca el archivo con ese nombre.

Como hacer un Snake en Love2D

Archivos Comenzamos creando los archivos main.lua y conf.lua, en el conf.lua solo añadimos lo siguiente: function love.conf(t)   t.win...