sábado, 19 de marzo de 2016

Lo que sé sobre: Como detectar colisiones en Love2d (punto en segmento 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 unas coordenadas x,y se encuentran dentro de un segmento de recta dibujado en pantalla.


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

Colisión entre círculos

Para esta ocasión vaos a editar de nuevo nuestro archivo ControlDeColisiones.lua incluyendo en el tres nuevas funciones:

  • crear_segmento_de_recta(rxI,ryI,rxF,ryF):Recibe un par de coordenadas 
    x,y. Las primeras coordenadas indican el punto inicial del segmento y las segundas coordenadas indican el punto final
  • round(n): Función que hace uso de la función floor de la biblioteca math para redondear el valor recibido en la misma
  • punto_en_recta(s,x,y): Recibe la estructura de un segmento de recta y unas coordenadas x,y. La función retorna true si las coordenadas están dentro del segmento de recta


La primera función queda de la siguiente manera:

--[[

Recibe la estructura de un segmento de recta y la retorna dentro de una tabla donde:

xI:Es la posición horizontal inicial

yI:Es la posición vertical inicial

xF:Es la posición horizontal Final

yF:Es la posición vertical Final

]]--

function ControlDeColisiones.crear_segmento_de_recta(rxI,ryI,rxF,ryF)

     segmento={xI=rxI,yI=ryI,xF=rxF,yF=ryF}

     return segmento

end

La siguiente función será la función round:


--[[Redondea un número dado usando la función floor de la biblioteca math, que retorna el mayor entero o igual al número recibido en la función

Existen muchas formas de redondear un número, pero esta para el caso

da buenos resultados]]--

function ControlDeColisiones.round(n)

     return math.floor((math.floor(n*2) + 1)/2)

end

Y por último incluiremos la función encargada de detectar la colisión etre las coordenadas y el segmento de recta

--[[Función que recibe la estructura de un segmento de recta

y una coordenadas x,y, la función retorna true si las coordenadas recibidas se

encuentran dentro del segmento de recta]]--

function ControlDeColisiones:punto_en_recta(s,x,y)

     --[[primero medimos la distancia restante entre las coordenadas iniciales de la recta

     y las coordenadas a comprobar, el resultado lo guardamos en distanciaA]]--

     distanciaA=self.medir_distancia(s.xI,s.yI,x,y)

     --[[Medimos la distancia restante desde las coordenadas finales de la recta

     y las coordenadas a comprobar, el resultado lo guardamos en distanciaB]]--

     distanciaB=self.medir_distancia(s.xF,s.yF,x,y)

     --[[Obtenemos la distancia restante entre los puntos iniciales y finales de la propia recta

     guardamos el resultado en distanciaC]]--

     distanciaC=self.medir_distancia(s.xI,s.yI,s.xF,s.yF)


     --[[Si el resultado de redondear la suma entre distanciaA y distanciaB es igual al resultado de 
     redondear distanciaC

    la función retornará true, indicando que las coordenadas se encuentran dentro del segmento de
     recta]]--

    if self.round(distanciaA+distanciaB)==self.round(distanciaC)then

        return true

    else

        return false

    end

end

Para poner estas funciones a prueba, vamos a crear un nuevo ejemplo. Este comprobará la colisión entre las coordenadas del cursor y un segmento de recta.

Generamos como la anterior vez, una carpeta con un archivo main.lua y diseñamos la estructura básica.

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 realizara todo el proceso de dibujar la pantalla

end

Esta vez usaremos la función love.load para incluir nuestro archivo ControlDeColisiones.lua, crear nuestro segmento y nuestra variable de control


function love.load()

     --Incluimos nuestro controlador de colisiones

     controlChoques=require("ControlDeColisiones")


     --Generamos el segmento de recta

     segmento=controlChoques.crear_segmento_de_recta(400,100,400,300)


     texto="no están en colisión"

end

como en los casos anteriores en love.update(dt) comprobaremos la colisión y actualizaremos la variable de control.

function love.update(dt)

     --Recogemos las posiciones del cursor

     mX=love.mouse.getX()

     mY=love.mouse.getY()


     --Llamamos a lafunción para comprobar la colisión

     if (controlChoques:punto_en_recta(segmento,mX,mY)) then

         texto="Están en colisión"

     else

         texto="No están en colisión"

     end

end

y ya sólo nos queda usar la función love.draw para dibujarlo todo en pantalla.

function love.draw()

     --dibujamos el segmento de recta

     love.graphics.line(segmento.xI,segmento.yI,segmento.xF,segmento.yF)

     --dibujamos el texto de control en pantalla

     love.graphics.print(texto,10,10)

end

El resultado del ejemplo:


Y hasta aquí todo lo que sé, sobre como crear una colisión punto en segmento de recta.

Hasta la próxima.

No hay comentarios:

Publicar un comentario