lunes, 7 de marzo de 2016

Lo que sé sobre: Como detectar colisiones en Love2d (punto en círculo)




¿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 círculo dibujado en pantalla.


Para hacerlo, vamos a recuperar nuestro archivo ControlDeColisiones.lua. En este archivo vamos a escribir dos nuevas funciones que nos van a permitir detectar este tipo de colisiones.

medir_distancia(x1,y1,x2,y2): Esta recibe dos coordenadas en pantalla dadas por x1,y1 y x2, y2. La función retorna la distancia restante entre ellas.

colision_punto_con_circulo(x,y,cX,cY,radio): Esta recibe la coordenada a comprobar x,y y la estructura del círculo dada por, cX,cY como sus coordenadas en pantalla y su radio. La función retorna true si la comprobación de colisión es correcta.

Estas dos funciones las vamos a incluir en nuestro archivo ControlDeColisiones.lua de la siguiente manera. Primero escribimos la función medir_distancia:

--[[Haciendo uso de la biblioteca math la función retorna la distancia en píxeles restante

entre dos coordenadas dadas]]--

function ControlDeColisiones.medir_distancia(x1,y1,x2,y2)

     distancia=math.sqrt(math.pow(math.abs(x2-x1),2)+math.pow(math.abs(y2-y1),2))

     return distancia

end

Está función se usará muy a menudo para comprobar otro tipo de colisiones, la verdad es que es una función muy útil.

Despues de escribir esta función, pasaremos a escribir la siguiente, colision_punto_con_circulo. Esta será la encargada de comprobar nuestra colisión y hará uso de la función medir_distancia para realizar su cálculo correspondiente.

--[[Recibe unas coordenadas "x,y" y la estructura de un círculo

dado por sus coordenadas cX,cY y su radio]]--

function ControlDeColisiones:colision_punto_con_circulo(x,y,cX,cY,radio)

     --[[LLamamos a la función medir_distancia del archivo útiles,

     esto nos retornará la distancia restante entre la coordenada inicial (x,y) y la final(cX,cY)]]--

     distanciaAlCentro=self.medir_distancia(x,y,cX,cY)


     --[[Con la distancia restante obtenida ya sólo nos queda

     preguntar si esta es menor al radio del círculo,

     si es así la función retornará true, en caso contrario

     retornará false]]--

    if (distanciaAlCentro<=radio) then

        return true

    end

    return false

end

Esta vez declararemos la función separando el nombre de nuestra tabla del de la función usando “:” en vez de un “.”. Esto lo haremos para poder recibir en la función, de manera automática y en el primer parámetro, el valor “self”

self hace referencia a la propia tabla en si, y nos va a servir para llamar a las funciones que están escritas dentro de la misma. En este caso no va a servir para llamar a la función medir distancia desde la función colision_punto_con_circulo.

Para poner estas funciones a prueba, vamos a crear un nuevo ejemplo, que al igual que el anterior, comprobará la colisión con las coordenadas del cursor, pero esta vez lo hará contra un círculo.

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 crear la estructura de nuestro círculo, además de incluir nuestro archivo ControlDeColisiones


function love.load()

     --Incluimos nuestro controlador de colisiones

     controlChoques=require("ControlDeColisiones")

     --Posición x del círculo

     cX=300

     --Posición y del círculo

     cY=200

     --Radio del círculo

     radio=40

    --Texto de control

    texto="Fuera del rectángulo"

end

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()


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

     if (controlChoques:colision_punto_con_circulo(mX,mY,cX,cY,radio)) then

         texto="Detro del Círculo"

     else

     texto="Fuera del Círculo"

     end

end

Recordad que al declarar una funcion dentro de una tabla usando el operador ":" deberá ser llamada del mismo modo al momento de su ejecución. 
como el caso de:

if (controlChoques:colision_punto_con_circulo(mX,mY,cX,cY,radio)) then 


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

function love.draw()

     --dibujamos el círculo en pantalla

     love.graphics.circle("fill", cX,cY,radio, 100)

     --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 con círculo.

No hay comentarios:

Publicar un comentario