Notxor tiene un blog
  • Inicio
  • Categorías
  • Tags
  • Archivo

Löve-2D un Game Engine en Lua

Una de las cosas que llevo tiempo siguiendo –y persiguiendo– al meterme en los temas de programación y de la informática que tanto tiempo me ocupan, es la capacidad que tiene la tecnología para hacer juegos, crear mundos virtuales y la posibilidad que eso da de utilizar ese tipo de aplicaciones para mejorar el aprendizaje.

Quizá el haber tenido que aprender la lista de los reyes Godos cuando era joven, las tediosas tardes recitando nombre tras nombre, para olvidarlos nada más hacer el examen, me predisponga a perseguir el sueño de un aprendizaje más lúdico, más interesante. El aprenderme esa lista no me hizo más inteligente ni el haberla olvidado me hace más torpe (eso sí, sé quienes son las estatuas de la plaza de Oriente en Madrid, ciudad en la que residí durante veinticuatro años de mi vida).

El caso es que mientras cambiaba ayer mi móvil a android estuve mirando las aplicaciones que instalar y muchas más cosas. Empleando casi todo el día procrastinando entre unas y otras apps y viendo qué instalar y que desinstalar (si me dejaba) o dejaba inhabilitado, tropecé con la versión para android de Löve-2D. Hace un tiempo, cuando corría por la versión 0.8 ó 0.9 ya hice unas pruebas con él, pero sólo para PC (GNU/linux y güindón).

El código

Pego aquí el código en Lua para hacer ese ejercicio. No es mi objetivo explicar todo lo que hace. De todas formas, creo que puse suficientes comentarios, lo suelo hacer porque soy muy torpe y al cabo del tiempo después de haber escrito el código muchas veces no tengo claro qué hace. Por eso uso los comentarios como un guiaburros de lo que pienso cuando lo escribo.

function love.load()
  love.physics.setMeter(50)     --el largo de un metro en nuestro mundo será de 50px
  world = love.physics.newWorld(0, 9.81*50, true) --creamos un mundo para los cuerpos con una gravedad horizontal de 0 y de 9.81 en vertical

  objects = {} -- tabla donde guardar los objetos físicos

  --creamos un clavo
  objects.clavo = {}
  objects.clavo.body = love.physics.newBody(world, 425, 200)
  objects.clavo.shape = love.physics.newRectangleShape(10, 10)
  objects.clavo.fixture = love.physics.newFixture(objects.clavo.body, objects.clavo.shape)

  --creamos un par de bolas que harán de pesos de los péndulos
  objects.bola1 = {}
  objects.bola1.body = love.physics.newBody(world, 525, 200, "dynamic") --pone el cuerpo en el mundo y lo hace dinámico, por eso puede moverse
  objects.bola1.shape = love.physics.newCircleShape(20) --la forma de la bola tiene un radio de 20
  objects.bola1.fixture = love.physics.newFixture(objects.bola1.body, objects.bola1.shape, 2) --fija la forma al cuerpo y le da una densidad de 2.
  objects.bola1.fixture:setRestitution(0.8) --deja que la pelota rebote

  objects.bola2 = {}
  objects.bola2.body = love.physics.newBody(world, 625, 200, "dynamic") --pone el cuerpo en el mundo y lo hace dinámico, por eso puede moverse
  objects.bola2.shape = love.physics.newCircleShape(20) --la forma de la bola tiene un radio de 20
  objects.bola2.fixture = love.physics.newFixture(objects.bola2.body, objects.bola2.shape, 2) --fija la forma al cuerpo y le da una densidad de 2.
  objects.bola2.fixture:setRestitution(0.8) --deja que la pelota rebote

  --crear dos bloques que harán de brazos de los péndulos
  objects.barra1 = {}
  objects.barra1.body = love.physics.newBody(world, 475, 200, "dynamic")
  objects.barra1.shape = love.physics.newRectangleShape(0, 0, 100, 10)
  objects.barra1.fixture = love.physics.newFixture(objects.barra1.body, objects.barra1.shape, 1) -- Una densidad mayor proporciona más masa.
  objects.barra1.fixture:setRestitution(0.7)

  objects.barra2 = {}
  objects.barra2.body = love.physics.newBody(world, 595, 200, "dynamic")
  objects.barra2.shape = love.physics.newRectangleShape(0, 0, 100, 10)
  objects.barra2.fixture = love.physics.newFixture(objects.barra2.body, objects.barra2.shape, 1)
  objects.barra2.fixture:setRestitution(0.7)

  --poner el fondo
  love.graphics.setBackgroundColor(111, 143, 255) --el color de fondo es un azul marica-ilusión

  --uniones entre objetos
  love.physics.newRevoluteJoint(objects.clavo.body, objects.barra1.body, 425, 200, false) --unión rotativa entre el clavo y una barra
  love.physics.newWeldJoint(objects.barra1.body, objects.bola1.body, 520, 200) --unión fija entre una barra y su bola
  love.physics.newRevoluteJoint(objects.bola1.body, objects.barra2.body, 530, 200, false) --unión rotativa entre la bola anterior y la barra
  love.physics.newWeldJoint(objects.barra2.body, objects.bola2.body, 635, 200) --unión fija entre una barra y su bola
end

function love.quit()
    print("La demostración ha finalizado.")
    return false
end

function love.update(dt)
  world:update(dt) --esto pone el mundo en movimiento

  --controlar algunos eventos del teclado
  if love.keyboard.isDown("right") then --pulsar la flecha derecha empuja la bola central a la derecha
    objects.bola1.body:applyForce(800, 0)
  elseif love.keyboard.isDown("left") then --pulsar la flecha izquierda empuja la bola central a la izquierda
    objects.bola1.body:applyForce(-800, 0)
  elseif love.keyboard.isDown("up") then --pulsar la flecha arriba pone la bola central en su posición de inicio, aunque con la inercia que lleve
    objects.bola1.body:setPosition(525, 200)
  elseif love.keyboard.isDown("escape") then
    love.event.push("quit")
  end
end

function love.draw()
  love.graphics.setColor(50, 50, 50) --pone el color gris para los bloques
  love.graphics.polygon("fill", objects.barra1.body:getWorldPoints(objects.barra1.shape:getPoints()))
  love.graphics.polygon("fill", objects.barra2.body:getWorldPoints(objects.barra2.shape:getPoints()))

  love.graphics.setColor(193, 47, 14) --pone un color rojo para la bola y el clavo
  love.graphics.circle("fill", objects.bola1.body:getX(), objects.bola1.body:getY(), objects.bola1.shape:getRadius())
  love.graphics.circle("fill", objects.bola2.body:getX(), objects.bola2.body:getY(), objects.bola2.shape:getRadius())
  love.graphics.polygon("fill", objects.clavo.body:getWorldPoints(objects.clavo.shape:getPoints()))

  love.graphics.setColor(250, 200, 0)
  love.graphics.print('[esc] sale de la demo', 40, 15)
  love.graphics.print('[-->] empuja la bola a la derecha.', 40, 30)
  love.graphics.print('[<--] empuja la bola a la izquierda.', 40, 45)
  love.graphics.print('[ ^ ] pone la bola en la posición de partida, aunque con la inercia que tenga en ese momento.', 40, 60)
  love.graphics.print('Prueba de distribución cruzada -- Notxor', 40, 560)
end

Hay que destacar que las funciones love.load(), love.draw() y love.update() son centrales en el game engine para establecer y controlar todos los parámetros que afectan al juego. Digamos que son los mínimos que debe cumplir una demo en Löve 2D.

El funcionamiento

El funcionamiento es muy suave, tanto en el ordenador como en la tablet. Siendo una demo tan simple tampoco sobrecarga el sistema demasiado, supongo que en juegos complejos la cosa pueda cambiar.

Löve en el ordenador

En la imagen anterior se puede ver cómo se ve en mi portátil el ejemplo funcionando. En la siguiente se puede ver funcionando en la tablet bq M10 que tengo también con android.

Löve en la tablet

Sin hacer esfuerzos estéticos, evidentemente, la adaptación a la pantalla de la tablet android queda un desplazada hacia arriba y a la izquierda. Pero supongo que con un poco más de código se podría capturar la resolución de la pantalla y centrar la demo.

La interacción también es complicada, no aparece el teclado virtual y he tenido que conectar uno bluetooth para poder controlar la demo. No sé si sería posible el acceder con Lua a los acelerómetros y demás sensores del aparato, eso lo tendré que investigar en adelante. Si continúo con estas investigaciones ya habrá noticias por aquí. Otro de los puntos sería si se puede hacer una compilación del fichero .love con el .apk de android para distribuir el juego o la demo directamente.

De momento, lo dejo aquí, que no deja de ser una pequeña demo funcionando en android... pero hay temas que investigar.


  • « Adiós a Ubuntu Touch
  • Compilando un juego de Löve 2D »

Publicado

El domingo 2017-04-30 10:00

Categoría

Programación

Etiquetas

  • cajón desastre 71
  • juegos 1
  • lua 1

Enlaces

rss feed Diaspora GNUsocial Creative Commons License

  • «Notxor tiene un blog» por Notxor se licencia como Attribution-NonCommercial-ShareAlike 4.0 International.
  • Powered by Pelican. Tema retocado, basado en: Elegant by Talha Mansoor