¿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.
Pues en esta entrada
paso a explicar tres nuevas funciones a incluir en nuestro archivo
ControlDeColisiones.lua. Esta
vez las funciones nos valdrán para detectar colisiones entre
rectángulos y si es así generar el rectángulo de intersección que
se crea mediante la colisión.
Las
funciones a crear serán:
- crear_rectangulo(xr,yr,wr,hr): Recibe la estructura de un rectángulo y la retorna convertida en una tabla donde; x,y serán las coordenadas del rectángulo y w,h, serán el ancho y el alto
- colision_entre_rectangulos(rA,rB): Recibe la estructura de dos rectángulos y retorna true si estos están en colisión.
- rectangulo_interseccion(rA,rB):Recibe la estructura de dos rectángulos y retorna el rectángulo de intersección que se genera entre ambos
La
primera función que vamos a incluir en el archivo
ControlDeColisiones.lua, será
la función que usaremos para generar la estructura de los
rectángulos
--[[Esta función retorna la estructura de un
rectángulo contenidos en una tabla.
Los datos contenidos en la tabla retornada
seran
x=posición horizontal
y=posición vertical
w=ancho del rectángulo
h=como alto del rectángulo]]--
function ControlDeColisiones.crear_rectangulo(xr,yr,wr,hr)
rect={x=xr,y=yr,w=wr,h=hr}
return rect
end
La siguiente función a crear será
colision_entre_rectangulos(rA,rB) y como dijimos se le pasa
como argumentos la estructura de dos rectángulos creados por la
anterior función.
--[[Recibe la estructura de dos rectángulos y
retorna true si estos dos se están tocando]]--
function ControlDeColisiones.colision_entre_rectangulos(rA,rB)
--[[Comprobamos si la
posición orizontal de rA es menor que la suma de la posición
horizontal
de rB más su ancho y
si la posición horizontal de rB es menor
que la posición horizontal de rA más su ancho. Si es así
ignifica
que los dos rectángulos
se chocan en horizontal]]--
if
(rA.x<rB.x+rB.w and rB.x<rA.x+rA.w) then
--[[Comprobamos si
la posición vertical de rA es menor que la posición vertical de rB
más su alto
y si la posición vertical de rB
es menor que la posición vertical de rA
más su alto.
Si esta comprobación retorna true
significa que los rectángulos chocan en vertical]]--
if
(rA.y<rB.y+rB.h and rB.y<rA.y+rA.h) then
--[[Si las dos
comprobaciones son correctas la función retornará true]]--
return
true
end
end
return
false
end
uY por último implementamos la función
encargada de generar el rectángulo de intersección
rectangulo_interseccion(rA,rB)
--[[Retorna el rectangulo de intersección
generado por la colisión entre dos rectángulos]]--
function ControlDeColisiones:rectangulo_interseccion(rA,rB)
--Usamos la función max
de la biblioteca math para saber cual de las dos coordenadas x de
los rectángulos es mayor
--Guardamos el resultado en una nueva variable
nX
nX=math.max(rA.x,rB.x)
--Usamos la función max de la biblioteca
math para saber cual de las dos coordenadas y de los rectángulos es
mayor
--Guardamos el resultado en una nueva
variable nY
nY=math.max(rA.y,rB.y)
--[[Sumamos el ancho de rA + su coordenada
x y sumamos el ancho de rB mas su coordenada x,
Usamos la función min de la biblioteca
math para adivinar el menor de los dos resultados
anteriores y le
restamos nX
y guardamos el valor en una nueva
variable]]--
nW=math.min(rA.x+rA.w,rB.x+rB.w)-nX
--[[Sumamos el alto
de rA mas su coordenada y y sumamos el alto de rB más su coordenada
y,
Usamos la función min de la biblioteca
math y adivinamos el menor de los anteriores
resultados, al resultado
le restamos nY
y guardamos el valor en una nueva
variable]]--
nH=math.min(rA.y+rA.h,rB.y+rB.h)-nY
--Usamos las nuevas
variables para generar un nuevo rectángulo con la funcion
crear_rectangulo y lo retornamos
nR=self.crear_rectangulo(nX,nY,nW,nH)
return
nR
end
Con esto nuestro archivo
ControlDeColisiones.lua estará listo para detectar colisiones
entre rectángulos. Para comprobarlo escribiremos el siguiente
ejemplo. Dibujaremos dos rectángulos en pantalla y a uno de
ello le haremos que se mueva junto con el cursor del ratón. Si los
dos rectángulos colisionan avisaremos con un mensaje y dibujaremos
el rectángulo de intersección generado por la colisión.
Para generar la estructura del ejemplo haremos
lo mismo que en los anteriores post.
En la función love.load de nuestro archivo
main.lua incluimos el archivo ControlDeColisiones.lua, creamos
la estructura de dos rectángulos, el mensaje de control y la variable
que contendrá el rectángulo de intersección si los dos primeros
están en contacto.
function love.load()
--Incluimos
nuestro controlador de colisiones
controlChoques=require("ControlDeColisiones")
rA=controlChoques.crear_rectangulo(100,100,40,40)
rB=controlChoques.crear_rectangulo(300,300,40,40)
texto="no
están en colisión"
rInterseccion=nil
end
En love.update(dt) actualizamos el movimiento del primer rectángulo,
comprobamos si existe colisión y generamos el rectángulo de
intersección.
function love.update(dt)
--Recogemos
las posiciones del cursor
mX=love.mouse.getX()
mY=love.mouse.getY()
--Asignamos
las posiciones del cursor al rectángulo a para que se desplace con
el movimiento del cursor
rA.x=mX
rA.y=mY
--Llamamos
a la función para comprobar la colisión
if
(controlChoques.colision_entre_rectangulos(rA,rB)) then
texto="Están
en colisión"
--[[Si
los rectángulos se tocan generamos el rectangulo de
interseccion]]--
rInterseccion=controlChoques:rectangulo_interseccion(rA,rB)
else
rInterseccion=nil
texto="no
están en colisión"
end
end
Dibujamos el resultado en pantalla
function love.draw()
--dibujamos
los rectángulos
love.graphics.rectangle("fill",
rA.x,rA.y,rA.w,rA.h)
love.graphics.rectangle("fill",
rB.x,rB.y,rB.w,rB.h)
--dibujamos
el texto de control en pantalla
love.graphics.print(texto,10,10)
--Etiqueta
para indicar donde mostramos el rectángulo de intersección
love.graphics.print("Intersección:",10,40)
--Si
los rectángulos se tocan dibujamos el rectángulo de intersección.
--Lo
hacemos usando el operador ~= que significa distinto de.
--Quiere
decir: si rIntersección es distinto del valor nil
if
(rInterseccion~=nil) then
--Dibjamos
el rectangulo en 10 y 70 porque de usar las posiciones propias de la
tabla rIntersección
--el
rectángulo se dibujaría sobre los otros dos.
love.graphics.rectangle("fill",
10,70,rInterseccion.w,rInterseccion.h)
end
end
El resultado de todo esto en pantalla sería el
siguiente
Y hasta aquí todo lo que sé, sobre como detectar
colisiones entre rectángulos.
No hay comentarios:
Publicar un comentario