miércoles, 16 de marzo de 2016

Lo que sé sobre: Como detectar colisiones en Love2d (Colisión entre círculos)


¿Acaso no sabes como hacer que el héroe de tu juego sea capaz de golpear a ese maldito enemigo?

¿Como demonios hago para que mi ratón pulse es bonito botón?


Pues poco a poco voy a explicar lo que yo descubrí sobre como detectar varios tipos de colisiones.

En este caso amos a crear un nuevo par de funciones para el archivo ControlDeColisiones.lua que nos servirán junto con la función medir_distancia, escrita en un post anterior, para detectar colisiones entre círculos.

El resto de capítulos, sobre estos ejemplos, pueden visitarse desde los siguientes enlaces.

Colisión punto en rectángulo

Colisión punto en círculo

Colisión entre Rectángulos

Las funciones a incluir serán las siguientes:

  • crear_circulo(rX,rY,rR): Recibe la estructura de un círculo y la retorna dentro de una tabla.
  • colision_entre_circulos(cA,cB):Recibe la estructura de dos círculos y retorna true si estos están en colisión.

La primera es muy sencilla y al igual que la función crear_rectangulo, ya vista en otra entrada anterior, nos servirá para mantener el código más ordenado.

--[[Esta función recibe la estructura de un círculo yla retorna en una tabla donde:
x=posición horizontal
y=posición vertical
r:el radio del círculo
]]--
function ControlDeColisiones.crear_circulo(rX,rY,rR)
     circulo={x=rX,y=rY,r=rR}
     return circulo
end

Ahora vamos a implementar la función encargada de detectar la colisión.

--[[Recibe la estructura de dos círculos y retorna true sis estos están en colisión]]--
function ControlDeColisiones:colision_entre_circulos(cA,cB)
     --[[Primero medimos la distancia restante entre los dos círculos usando
     las función medir_distancia]]--
     distanciaEntreEntes=self.medir_distancia(cA.x,cA.y,cB.x,cB.y)
     --Luego sumamos los radios de los dos círculos
     radioColision=cA.r+cB.r
     --[[finalmente preguntamos si la distancia es menor a la suma de los radios,
     si es así retornamos true pues la colisión será correcta]]--
     if (distanciaEntreEntes<radioColision) then
         return true
     else
         return false
     end
end


Pues ya conlas funciones implementadas, vamos a pasar a generar un nuevo ejemplo para poder ponerlas a prueba.

Creamos una carpeta y incluimos en ella nuestro archivo ControlDeColisiones.lua, creamos un archivo en blanco llamado main.lua y en el creamos la estructura básica de un programa en love2d

function love.load()
--Aquí crearemos las variables y cargaremos los recursos
end

function love.load()
--Aquí crearemos las variables y cargaremos los recursos
end

function love.draw()
--Aqui se realizara todo el proceso de dibujar la pantalla
end

en love.load incluimos nuestro archivo ControlDeColisiones.lua, y creamos la estructura de nuestros círculos más el mensaje de control.

function love.load()
     --Incluimos nuestro controlador de colisiones
     controlChoques=require("ControlDeColisiones")
     cA=controlChoques.crear_circulo(100,100,20)
     cB=controlChoques.crear_circulo(300,300,20)
     texto="no están en colisión"
end


function love.update(dt)
     --Recogemos las posiciones del cursor
     mX=love.mouse.getX()
     mY=love.mouse.getY()
     --Asignamos las posiciones del cursor al círculo cA para que se desplace con 
     el movimiento del cursor
     cA.x=mX
     cA.y=mY
     --Llamamos a lafunción para comprobar la colisión
     if (controlChoques:colision_entre_circulos(cA,cB)) then
         texto="Están en colisión"
     else
         texto="no están en colisión"
     end
end


function love.draw()
     --dibujamos los rectángulos
     love.graphics.circle("fill", cA.x,cA.y,cA.r,100)
     love.graphics.circle("fill", cB.x,cB.y,cB.r,100)
     --dibujamos el texto de control en pantalla
     love.graphics.print(texto,10,10)
end

Si probamos el ejemplo veríamos lo siguiente:




y hasta aquí, todo lo que sé sobre colisiones en love2d: Colisiones entre círculos.

No hay comentarios:

Publicar un comentario