pregunta acerca de colisiones

Started by DCelso, March 08, 2010, 08:38:13 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

DCelso

Esto es un problema con dos soluciones y unas cuantas preguntas relaccionadas con el asunto :D.

A ver, tengo dos procesos en los que tengo separada la lógica de actuación en caso de colisión para que cada proceso se auto realize su movimiento o destrucción.

process enemigo()
begin
// Inicializaciones de gráficos y/o animaciones
...
while(!key(_esc))
if (collision (type jugador))
x-=100;
end
frame;
end
// Liberaciones de gráficos y/o animaciones
end

process jugador()
begin
// Inicializaciones de gráficos y/o animaciones
...
while(!key(_esc))
if (collision (type enemigo))
break;
end
frame;
end
// Liberaciones de gráficos y/o animaciones
end

process main()
begin
jugador();
enemigo();
while(!key(_esc))
frame;
end
end


Esto en teoría es mas lento que hacerlo en el mismo proceso (ya que implica hacer dos veces un collision)
¿Estoy en lo cierto? Porque, claro, sabemos que es la misma colisión con mismo resultado pero en distintos puntos de vista y creo que podría ser "cacheable"

La otra opción sería hacer esto.

process enemigo()
private
jugador id_colision;
begin
// Inicializaciones de gráficos y/o animaciones
...
while(!key(_esc))
id_colision = collision (type jugador);
if (id_colision)
x-=100;
id_colision.destruir = 1;
end
frame;
end
// Liberaciones de gráficos y/o animaciones
end

process jugador()
private
destruir;
begin
// Inicializaciones de gráficos y/o animaciones
...
destruir = 0;
while(!key(_esc))
if (destruir == 1)
break;
end
frame;
end
// Liberaciones de gráficos y/o animaciones
end

process main()
begin
jugador();
enemigo();
while(!key(_esc))
frame;
end
end


Quisiera saber ventajas e inconvenientes de ambas opciones y de si se os ocurre otra opción para realizar esto.
Yo había pensado en otro proceso que sea el que compruebe colisiones y actúe en consecuencia con ambos procesos pero no veo funcion para comprobar si hay colisión en dos procesos dados de entrada.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Drumpi

No, es una de las carencias de collision, que sólo comprueba choques entre el proceso que lo invoca y el que tiene la ID que se le pasa por parámetro.

Pero en este caso en concreto, tu segunda solución es la más indicada... a decir verdad, para todos los casos es la más indicada, porque si al hacer la colisión uno de los procesos se mueve, es posible que el otro proceso, en el mismo frame, al comprobar colisión, ya no se de (porque el otro proceso acaba de alejarse). Lo normal es que uno de los procesos compruebe colisión y mande una "señal" al otro para que actúe en consecuencia... aunque según el orden de ejecución actuará en el mismo frame o en el siguiente, pero vamos, si un frame no es crítico, te vale.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Hokutoy

Imagino que el codigo que has puesto de ejemplo es teórico pero por si no lo fuera:

   id_colision.destruir = 1;

Te va a dar error ya que no puedes modificar el parametro destruir del proceso jugador desde el proceso enemigo ya que se trata de una variable PRIVADA del proceso jugador.
Deverías declarar destruir como una variable Pública.

Saludos!

BoMbErLiNk

Puedes hacer la colisión en una sola via y que mande la información a un proceso independiente que se ejecute el último y mande los resultados en el siguiente frame.

La colisión debería hacerse después de mover X para más precisión.

FRAME 1
* Soy bala
* Soy persona (prioridad distinta, se ejecuta después de bala para entrar en este mismo FRAME y no saltar al siguiente)
= colisionamos, solo 1 de los procesos hace la colisión y envia la información (El proceso que menos se repita, si van a haber 20 balas obviamente es mejor poner la colisión en el personaje que solo habrá 1)
= Notificamos al proceso externo, el prepara la info para el siguiente frame

FRAME 2
= Reciben la información
Soy bala y desaparezco
Soy persona y me como un balazo

Windgate

Yo no usuaría la detección mutua de colisiones, en primer lugar por problemas de rendimiento, pero también porque si uno de los procesos es destruido inmediatamente después de la colisión puede suceder que el otro no lo detecte dependiendo del orden en que se ejecutan. Problema típico disparo/enemigo o protagonista/enemigo la primera vez que haces tu matamarcianos en Bennu xD

La solución 2 que propones está bien, aunque eso sí, o bien usas signal para matar al proceso que ha chocado, o bien usas una LOCAL/PUBLIC para indicarle que debe morir.

Es un problema al que me he enfrentado varias veces, y yo soy amigo de usar signal y poner una claúsula ONEXIT al final para que haga sus últimas acciones antes de morir definitivamente, aunque también depende mucho de qué es lo que quieras hacer.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

el problema no es de collision, sino de como lo uses...

el 2do ejemplo esta bien, pero esta mal el sentido de la comprobacion... procesos disparo pueden existir muchos con lo que ejecutarias muchos collision, en cambio, jugador es 1 solo, deberias hacer el chequeo en jugador... y si colisiona contra algun disparo morir...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

DCelso

#6
Gracias por las aclaraciones.
Bueno, en verdad esto es un ejemplo, no está implementado en ningún lado.

Así que sí, "destruir" debería de ser public en vez de private :D.
En cuanto a dónde debería de ir, pues estaba pensando en un enemigo final de fase que suele ser único :D.

Por cierto, este ejemplo podría valer para enseñar la técnica de colisión en algún tutorial.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Windgate

... y también está el tema de que se puede hacer WHILE ( collision ( type ... ) ) y así interpretar los múltiples disparos que puedan colisionar, ya que no necesariamente tiene por qué interpretar un sólo impacto por FRAME... Es peludo el tema de collision, depende mucho de lo que quieras hacer.

Por cierto, este hilo me ha dado una idea para mejorar la collision3D ( ) que tengo implementada en 3Dit, ya que ahora mismo detectaba colisiones y soportaba tipos de proceso con type, pero no chequeaba que fuese uno distinto cada vez, y eso puedo hacerlo con exists :D

No tengas reparo en sacar este tipo de temas DCelso, nos interesan a muchos xD
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es