FizzX: Librería de colisiones para Love2D

Love2D tiene un motor de físicas, en realidad es un port de la librería Box2D. A mi parecer es un como complicado de aplicar y en ocasiones cuando quiero hacer algo mas sencillo ni siquiera lo ocupo, en cambio uso una función simple para detectar colisiones:
local function checkCollision (a, b)
    local dx = math.abs(a.x - b.x) -- x distance
    local dy = math.abs(a.y - b.y) -- y distance
    local mx = a.halfwidth + b.halfwidth -- minimum x distance
    local my = a.halfheight + b.halfheight -- minimum y distance

    return dx < mx and dy < my
end
Pero en ocasiones puede suceder que necesito una física mínima, no solo saber si dos cajas colisionan y toca implementar la física porteada de Box2D que viene en Love2D.

Por suerte, en la web se pueden encontrar muchas librerías de físicas además de la que viene con Love2D, algunas mas complejas y otras mas específicas, y en esta ocasión quiero exponer un poco sobre FizzX.

FizzX es una librería ligera de física al muy estilo de la vieja escuela, esto significa que tenemos lo básico para simular la física de un plataformero clásico.

Lo primero que debemos hacer es descargar la librería y colocarla en el proyecto, la importamos de esta manera en el main.lua:
local fizz = require("fizzx.fizz")
Fizz tiene 3 formas (shape) disponibles, rectangulo ("rect"), circulo ("circ") y línea ("line"), no acepta polígonos ni soporta rotaciones.

Al mismo tiempo soporta 3 tipos de cuerpos, static (cuerpo inamovible), kinematic (cuerpo que no colisiona), dynamic (cuerpo que si colisiona).

Por ejemplo:
local shape = fizz.addDynamic("rect", 50, 50, 20, 20) --forma, x, y, mitad ancho, mitad alto
local shape2 = fizz.addStatic("rect", 200, 200, 30, 100)
Luego para eliminar una forma de colisión solo hace falta poner fizz.removeShape(shape).

Cada forma tiene un callback para las colisiones, es decir, si añadimos la función onCollide() del shape esta será llamada cuando colisione:
function shape.onCollide(a,b,nx,ny,pen) -- self, shape, dirX, dirY,
    print(a,b,nx,ny,pen)
end
a es el shape en sí mismo, b es el shape con el que colisionó, nx y ny es la dirección de la colisión, puede ser 0 o 1, es decir, si nx == 0 y ny == 1 entonces la colisión viene desde abajo.

A continuación un ejemplo que puedes probar con 2 shapes:
local fizz = require("fizzx.fizz")

local shape = fizz.addDynamic("rect", 50, 50, 20, 20)
local shape2 = fizz.addStatic("rect", 200, 200, 30, 100)

function shape.onCollide(a,b,nx,ny,pen) -- self, shape, dirX, dirY,
    print(a,b,nx,ny,pen)
end

function love.update(dt)
    fizz.update(dt)
    if love.keyboard.isDown("right") then
        shape.xv = 100
    elseif love.keyboard.isDown("left") then
        shape.xv = -100
    else
        shape.xv = 0
    end
    if love.keyboard.isDown("up") then
        shape.yv = -100
    elseif love.keyboard.isDown("down") then
        shape.yv = 100
    else
        shape.yv = 0
    end
end

function love.draw()
    love.graphics.rectangle("fill", shape.x - shape.hw, shape.y - shape.hh, shape.hw*2, shape.hh*2)
    love.graphics.rectangle("fill", shape2.x - shape2.hw, shape2.y - shape2.hh, shape2.hw*2, shape2.hh*2)
end
Fizz requiere que actualices en cada frame, por eso necesitas poner fizz.update(dt).

shape.xv y shape.xy son las variables de velocity, shape.x, shape.y son las variables de posición, shape.hw, shape.hh son las variables del tamaño del shape, sin embargo estas son las mitades, ya que las formas se dibujan desde el centro, es decir, hw significa half-width y hh half-height.

Personalmente me gusta esta librería ya que es muy sencilla aunque con muchas limitaciones, sirve para proyectos sencillos, si quieres saber mas de esta librería revisa el proyecto aquí.

Comentarios

  1. Chalé entendí pero tengo unos problemas al tratar de crear un cuerpo en un archivo que no es main.lua :c

    ResponderEliminar

Publicar un comentario