Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Colisiones 2d eficientes (en que parte golpeó?)

Iniciado por pylorca, 06 de Febrero de 2007, 03:09:55 AM

« anterior - próximo »

pylorca

Bueno, estoy aca de nuevo...

tengo 2 sprites, uno mas grande en forma rectangular y otro mas pequeño.

tengo que detectar la colision entre los 2 sprites, pero no seria una comprobacion comun ya que tengo que detectar en que cara del rectangulo golpeó

a mi se me ocurrió crear 4 rectangulos de colision para el cuadrado (uno por cara) y asi hacer las 4 comprobaciones, pero calculo que no es la forma correcta de hacerlo

alguna sugerencia? (si tienen libros, tutos, etc sobre maths que me ayuden a resolver problemas de esta indole tambien ser'an bienvenidas)


Gracias

[EX3]

Con una sola caja de colision te deberia bastar. El resto seria simplemente detectar en que direccion ha colsionado el sprite, si A venia de la derecha ya sabes que colisiono con el lado izquierdo de B, no se si me explico.

Exactamente que estas intentando implementar? por que otro metodo interesante complementario a las cajas de colision son los puntos de control. Defines unas posiciones X e Y en el sprite que una vez detectada la colision de la caja de A pasarias a evaluar que punto de control de A se encuentra dentro del area de la caja de colision del sprite B.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

sés

Soy indeciso... ¿o no?

pylorca

muchas gracias sés, lo estoy mirando.

[EX3], lo que me decis en el 1er parrafo es una de las soluciones que mas me convence, pero... yo buscaba una forma mas matematica, en vez de ir poniendo ifs, no se si me explico

Lo que realmentre quiero hacer es ver donde cololisiona una pelota sobre un cuadrado para que esta tome la direccion correcta.

a mi se me ocurrieron otras cosas, unas de ellas tambien hacerla a ojito (sacando las coordenadas y viendo donde colisiono, y con 4 ifs lo detecto (muy cabeza))


seguro parezco un salamin preguntando estas cosas, pero bueno, soy nuevo y trato de hacer las cosas lo mas elegante y correctamtne posible, quiza no exista un metodo como el q quiero.

Gracias.


[EX3]

Cita de: "pylorca"[EX3], lo que me decis en el 1er parrafo es una de las soluciones que mas me convence, pero... yo buscaba una forma mas matematica, en vez de ir poniendo ifs, no se si me explico

Lo que realmentre quiero hacer es ver donde cololisiona una pelota sobre un cuadrado para que esta tome la direccion correcta.
El metodo de los puntos de control, depende para que, puede ser un metodo de los mas rapido que puedas encontrar y complementar otros mas. Suponte el sprite de un personaje de un juego donde quiere detectar  colisiones con distintas partes del sprite, puedes usar los puntos de control para detectar colsiones o para ubicar el centro de circunferencias para detectar colisiones con zonas concretas, pero para no andar calculando todas las colisiones posibles en cada paso calculas primero la colision con la caja principal que envolveria a todo el sprite, asi solo calculas una colision muy basica que no requiere apenas calculos. Ahora, si solo buscas detectar colision sobre una caja como tal, pues con que averigues el avance de A sobre B te sobra para saber en que direccion impacto A sobre B. Esto es mas facil y consume menos que calcular 4 cajas de colision o calculando a ojo como decias.

Citaryo buscaba una forma mas matematica, en vez de ir poniendo ifs, no se si me explico
(...)
a mi se me ocurrieron otras cosas, unas de ellas tambien hacerla a ojito (sacando las coordenadas y viendo donde colisiono, y con 4 ifs lo detecto (muy cabeza))
Aqui te contradices un poco, no? :P Teniendo predefinidos puntos de control fijos te resulta mas optimo que calcular a ojo la coordenada de colision. En cualquiera de los casos, siempre tendras que usar condiciones if dado que la programacion se basa en eso, en condiciones ;)

Cita de: "pylorca"seguro parezco un salamin preguntando estas cosas, pero bueno, soy nuevo y trato de hacer las cosas lo mas elegante y correctamtne posible, quiza no exista un metodo como el q quiero.
No te preocupes, todos al principio nos rebanamos la cabeza buscando la forma de hacer cosas como estas, y la cosa se complica cuando quieres comprobar cosas mas complejas que una caja :)

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

marcode

No puedes saber de dónde procede la pelota por la posición de su marco. Cuando vaya a toda leche se introducirá en el ladrillo, (incluso a una velocidad excesiva podría atravesarlo).

En imagen de la izquierda puedes ver cómo es imposible saberlo.



La forma correcta en mi opinión sería retroceder el cuadrado siguiendo la dirección inversa, hasta que quede justo en el borde (imagen derecha), de este modo podemos saber donde está el lado sobre el que rebota, en este caso hay que invertir la dirección X.

Además te asegura que la próxima vez el rebote se produce en el lugar donde debe, no en el interior, ya que podría confundirse al permanecer en colisión.

No sé si me expliqué bien.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

[EX3]

Cita de: "marcode"La forma correcta en mi opinión sería retroceder el cuadrado siguiendo la dirección inversa, hasta que quede justo en el borde (imagen derecha), de este modo podemos saber donde está el lado sobre el que rebota, en este caso hay que invertir la dirección X.
Totalmente deacuerdo. Tantos pixeles avanzas tantos compruebas, desde origen hasta destino, la primera colision detectada es la valida :)

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt


pylorca

[/quote]La forma correcta en mi opinión sería retroceder el cuadrado siguiendo la dirección inversa, hasta que quede justo en el borde (imagen derecha), de este modo podemos saber donde está el lado sobre el que rebota, en este caso hay que invertir la dirección X.[/quote]

en este caso como sabria cuanto retroceder de Y y cuanto de X?

seria un calculo en punto flotante, no?

pylorca

Acabo de implementar eso (aclaro que es la clase SpritePelota:Sprite


if (this->colision(&brick->at(i))) {

if (this->posAnteriorX - this->posx > this->posAnteriorY - this->posy)

this->velocidadX = -this->velocidadX;

else if (this->posAnteriorX - this->posx < this->posAnteriorY - this->posy)

this->velocidadY = -this->velocidadY;

else {

this->velocidadY = -this->velocidadY;

this->velocidadX = -this->velocidadX;

}
     
        ........
    }


anda bastante bien, pero no del todo, ya que a veces tiene comportamientos extraños cuando hay muchos bricks juntos (o quiza es mi imaginacion)

marcode

Yo hice un arkanoid en su día, y seguro que nos hemos encontrado todos con el mismo problema, la bola rebota donde le da la gana, atraviesa ladrillos, o golpea al que está detras, se queda atascada, se vuelve loca, etc. etc. Sobre todo cuando va a mucha velocidad.

Puedes hacer lo que ha dicho EX3, si en el siguiente desplazamiento se prevee colisión,  la avanzas en unidades hasta que entre en contacto, paras ahí la bola y determinas su nueva dirección, la sabrás dependiendo de la dirección actual y del lado (de los cuatro) en el que está el ladrillo con respecto a la bola.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]

pylorca



En el 1er ejemplo de la imagen, si la bola viene a toda leche (por ej: 10px/iteracion) nunca detectaria una colision

en el 2do ejemplo, tambien la bola viene a toda leche, se "saltea" a la caja 2 e impacta con la caja 1, cuando rebote golpear'a a la caja 2.

mmm estoy medio perdido...

marcode

Pues lo que dijo antes EX3, en cada iteración compruebas el recorrido pixel a pixel en un bucle, si detecta colisión lo rompe y ahí se queda la bola.

Como dijiste antes tendrás que usar floats y reducirlos a la unidad dividiendo los dos incrementos de posición por el mayor de ellos.

Entonces si DesplazaX = 8 y DesplazaY = 11.
el incremento de las X será 8/11 = 0.72f
y el de las Y 11/11 = 1.0f

Esto un total de 11 veces, si hay colisión detienes la bola en la posición (o incluso podrías continuar avanzando hasta finalizar el bucle en la dirección que tome después del rebote para más perfección)

Si no hubo colisión ignoras esos incrementos y la desplazas como siempre.

Yo creo que debe funcionar esta teoría.
size=9]afortunadamente siempre ha habido alguien dispuesto a reinventar la rueda, de lo contrario seguiríamos usando un disco de piedra con un agujero.[/size]






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.