En todo proceso de desarrollo de videojuegos se requiere verificar si algún punto o coordenada está dentro de una área especifica de la pantalla y así reaccionar a ese caso, como puede ser que el puntero del ratón este dentro del área de un botón y que al hacer clic se ejecute alguna acción, o que el disparo del enemigo este dentro del rectángulo que limita a nuestro jugador. A este proceso comúnmente se le llama detección de colisiones y existen distintos algoritmos que nos facilitan esta tarea, hoy te mostraré como verificar las colisiones entre rectángulos, círculos y triángulos.
Detección de un punto dentro de un rectángulo.
Verificar si un punto está dentro de un rectángulo es bastante sencillo, basta con comparar las coordenadas de nuestro punto con las coordenadas mínimas y máximas de nuestro rectángulo y verificar que está dentro de esos valores. Veamos la imagen.
En la imagen podemos observar las 4 coordenadas del rectángulo que necesitaremos, los valores de "x1" e "y1" ya lo conocemos debido a que es el valor que pasamos a Love2D para que dibuje en la pantalla, si queremos dibujar una imagen usamos love.graphics.draw(imagen,x,y), "x" e "y" son justamente los valores de "x1" y "y1" en el caso de la imagen. Bien para obtener el valor de las coordenadas "x2" e "y2" solo sumamos a las coordenadas de origen el ancho y alto del rectángulo, quedando entonces los valores de esta manera.
x2 = x1 + ancho
y2 = y1 + alto
Ya teniendo estos valores mínimos y máximos del rectángulo, solo nos queda comparar el valor de las coordenadas del punto con los valores de las coordenadas del rectángulo. La comparación en simples palabras sería así, si la coordenada "x" del punto está dentro de "x1" y "x2" (es decir que el valor "x" del punto es mayor que "x1" y menor que "x2"). Y si la coordenada "y" del punto está dentro de "y1" e "y2" entonces podemos afirmar que ha habido una colisión. La comparación en nuestro código quedaría así.
if x1 <= x and x <= x2 and y1 <= y and y <= y2 then
-- hay una colisión!
end
Segundo método de detección de colisiones en rectángulos.
También es posible detectar la colisión calculando la distancia entre el punto y el centro del rectángulo. Si tomamos la coordenada "x" del punto y la coordenada "x" del centro del rectángulo y restamos ambos valores obtenemos la distancia entre ellos, y si ese valor es menor o igual a la mitad del ancho en el caso de las coordenadas "x" podemos decir que también hay una colisión, obviamente si también se cumple en la coordenada "y". Veamos como hacer este cálculo.
Las coordenadas del centro del rectángulo se calculan de esta manera, dividimos el ancho entre dos y la sumamos al origen.
rcx = x1 + ancho * 0.5
rcy = y1 + alto * 0.5
Luego restamos los valores de las coordenadas del punto con las coordenadas del centro del rectángulo, aplicamos la función de Lua abs() para obtener el valor absoluto de la resta, y esto se hace para no obtener valores negativos del cálculo.
distx = math.abs(rcx - x)
disty = math.abs(rcy - y)
Teniendo la distancia entre las coordenadas solo nos queda comparar estos valores con la mitad del ancho y la mitad del alto del rectángulo, y si las distancias son menores que el ancho y alto tenemos la colisión.if distx <= ancho * 0.5 and disty <= alto * 0.5 then
--tenemos colisión
end
Detección de un punto dentro de un círculo.
Detección de un punto dentro de un triángulo.
Aplicando este mismo método a los triángulos formados por los vértices del triángulo y el punto a verificar, nos quedan las siguientes ecuaciones.
a1 = math.abs( (x1 - px)*(y3 - py) - (x2 - px)*(y1 - py) )
a2 = math.abs( (x2 - px)*(y2 - py) - (x3 - px)*(y2 - py) )
a3 = math.abs( (x3 - px)*(y1 - py) - (x1 - px)*(y3 - py) )
"px" y "py" son las coordenadas del punto. Y solo nos queda sumar y comparar.
if (a1+a2+a3) == A then
--hay colisión
end
En el siguiente video se pueden ver los tres métodos de colisión en funcionamiento.
Para dibujar un triángulo o cualquier polígono con Love2D usamos la función love.graphics.polygon("fill o line",x1,y1,x2,y2,x3,y3,....), puedes agregar cuantos puntos necesites siguiendo esa regla, también puedes pasarle como parámetro de coordenadas una tabla, polygon("fill o line", {x1,y1,x2,y2,x3,y3}).
Si deseas el código de esta práctica lo tienes aquí.
Eso es todo por los momentos espero lo hayas comprendido y puedas aplicarlo en tus prácticas.
Si te pareció útil me ayudarías mucho compartiéndolo.
Hasta la próxima.
¡Increibe!, No conocía el algoritmo de colisión del triangulo, normalmente cuando se habla de colisiones simples solo se limitan a hablar del circulo y el cuadrado, posteriormente sobre como llenar tu personaje de cuadros y circulos.
ResponderEliminar¡Gracias por compartir!