martes, 29 de marzo de 2016

Lo que sé sobre: Como detectar colisiones en Love2d (Cruce entre segmentos de recta)




¿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.

Esta vez, vamos a comprobar si dos segmentos de recta están en contacto.

Para hacerlo, vamos a recuperar nuestro archivo ControlDeColisiones.lua y en el vamos a incluir una nueva función

  • se_cruzan_los_segmentos(rA,rB): Recibe la estructura de dos segmentos de recta y retorna true si estos están en contacto

La función hace uso exhaustivo de las funciones max y min de la biblioteca math, para realizar varias comprobaciones entre las posiciones de los segmentos de recta. A mi gusto esta ya es un tanto liosa de explicar, mucho más que escribirla o aprenderla.

--[[Función que recibe dos sementos de recta y retorna true si estos se cruzan en algún punto]]--
function ControlDeColisiones.se_cruzan_los_segmentos(rA,rB)
     --[[Usamos las funciónes max y min de la biblioteca math
      para realizar varias comprobaciones entre las posiciones de la recta A]]--
     --retornamos el mayor valor entre xI y XF de la rA
      maxXA=math.max(rA.xI,rA.xF)
     --retornamos el menor valor entre xI y XF de la rA
     minXA=math.min(rA.xI,rA.xF)
    --retornamos el mayor valor entre yI y yF de la rA
     maxYA=math.max(rA.yI,rA.yF)
    --retornamos el menor valor entre yI y yF de la rA
     minYA=math.min(rA.yI,rA.yF)
    --retornamos el mayor valor entre xI y XF de la rB
     maxXB=math.max(rB.xI,rB.xF)
    --retornamos el menor valor entre xI y XF de la rB
     minXB=math.min(rB.xI,rB.xF)
    --retornamos el mayor valor entre yI y yF de la rB
     maxYB=math.max(rB.yI,rB.yF)
    --retornamos el menor valor entre yI y yF de la rB
    minYB=math.min(rB.yI,rB.yF)
   --Usamos los valores arrojados de las funciones anteriores para la siguiente comprobación
   --Si la misma retorna true sera que los dos segmentos de recta se cruzan en algún punto
   if (maxXA>=minXB) and (maxXB>=minXA) and (maxYA>=minYB) and (maxYB>=minYA) then
       return true
  end
  return false
end

Vamos ahora a comprobar el uso de esta función. Vamos a generar un ejemplo en el que un segmento de recta controlado por el cursor del ratón va a cruzarse con otro segmento fijo en pantalla.

Como siempre generamos un nuevo proyecto creando la carpeta el main.lua y incluyendo dentro de la carpeta nuestro archivo ControlDeColisiones.lua. Escribimos la estructura básica del ejemplo.

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

function love.update(dt)
     --Aquí realizaremos la actualización lógica de la aplicación
end

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

Incluimos nuestro archivo, creamos los segmentos y la variable de control dentro de la función love.load

function love.load()
     --Incluimos nuestro controlador de colisiones
     controlChoques=require("ControlDeColisiones")
     --Generamos nuestro segmento de recta
     segmentoA=controlChoques.crear_segmento_de_recta(40,40,100,40)
     segmentoB=controlChoques.crear_segmento_de_recta(400,100,400,300)
     texto="no están en colisión"
end

Como siempre en love.update(dt) vamos a comprobar la colisión y a cambiar el texto de control según sea necesario.

function love.update(dt)
     --Recogemos las posiciones del cursor
     mX=love.mouse.getX()
     mY=love.mouse.getY()
     --actualizamos las posiciones del segmento de recta A
     segmentoA.xI=mX
     segmentoA.yI=mY
     segmentoA.xF=mX+60
     segmentoA.yF=mY

     --Llamamos a lafunción para comprobar la colisión
    if (controlChoques.se_cruzan_los_segmentos(segmentoA,segmentoB)) then
         texto="Están en colisión"
   else
         texto="no están en colisión"
   end
end

Dibujamols todo en pantalla usando love.draw

function love.draw()
     --dibujamos los segmentos de recta
     love.graphics.line(segmentoA.xI,segmentoA.yI,segmentoA.xF,segmentoA.yF)
     love.graphics.line(segmentoB.xI,segmentoB.yI,segmentoB.xF,segmentoB.yF)
     --dibujamos el texto de control en pantalla
     love.graphics.print(texto,10,10)
end

El resultado del ejemplo (no sale la primera recta en la captura, pero no se por qué, el caso es por estar aseguro que está):


Y hasta aquí todo lo que sé, sobre como detectar colisiones entre segmentos.

No hay comentarios:

Publicar un comentario