Colisiones en SDL

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

Colisiones en SDL

Notapor pablo9891 » Sab Ene 15, 2011 12:57 am

Ultimamente estube haciendo un pequeño Pong en SDL y me encuentro ante un importante problema con las colisiones, basicamente el punto es que cada vez que la bola va hacia un lado de la pantalla en la cual del otro lado se encuentra posicionada la otra barra, se genera una colisione (en la imagen lo van a ver perfectamente)

Imagen

Este es el codigo que controla la colision, donde miBarra es la barra de la izquierda, miBarra2 es la de la derecha, y los demas metodos son propios del objeto pelota

Como pueden ver en el codigo lo que estoy haciendo es verificar si la pelota se encuentra dentro del rango de alguna de las barras y si es asi verifico si choco contra alguna

Sirius es el nombre de una clase que cree a modo de game engine

Código: Seleccionar todo
if((miBarra.getY()<=getY() && (miBarra.getY()+miBarra.getAlto())>=getY()+getAlto())//CHOCA CONTRA BARRA
    || (miBarra2.getY()<=getY())&&
    ((miBarra2.getY()+miBarra2.getAlto())>=getY()+getAlto()))
{
  if(getX()-10<miBarra.getX()+miBarra.getAnc())
  {
   Sirius::reproducirSonido(1);
   setVelX((-1)*getVelX());
  }
  else
  {
   if(getX()+getAnc()+getVelX()+10>miBarra2.getX())
   {
    Sirius::reproducirSonido(1);
    setVelX((-1)*getVelX());
   }
  }
}
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am

Re: Colisiones en SDL

Notapor Juanxo » Sab Ene 15, 2011 1:10 am

El tema es que tienes que tratar las 2 colisiones por separado. Te explico la situación de la imagen que has comentado, con respecto a tu código:

primero compruebas si está a la altura de alguno de los dos palos( si, está a la altura del izquierdo)

luego compruebas a ver si está a la izquierda del palo izquierdo, que en este caso es no
Compruebas si está a la derecha del palo derecho, y aquí sale el fallo, ya que si que está a la derecha.

El tema sería separar las condiciones:

- Está a la altura de la barra1? Y está a la izquierda de la barra 1? hay colision
- Si no está a la altura de la barra1, está a la altura de la barra2? Y está a su derecha? hay colision
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Colisiones en SDL

Notapor pablo9891 » Sab Ene 15, 2011 1:57 am

Prefecto! era eso, ahora tengo otro problema y es con respecto a los rebotes de la pelotita cuando se produce la colision, basicamente me fije en internet y en algunos libros y me recomendaban que cuando la pelota chocara contra algunas de las barras la direccion que deberia tomar seria la contraria a la direccion de la que proviene, lo que quiero decir es que si la pelota viene avanzando en sentido positivo de X, yo tengo que cambiar ese sentido cambiandole el signo al X para que vaya en sentido inverso

Código: Seleccionar todo
  if(getX()-10<miBarra.getX()+miBarra.getAnc())
  {
   Sirius::reproducirSonido(1);
   setVelX((-1)*getVelX());
  }


fijense en ese pedazo de codigo, si la pelota colisiona con la barra, simplemente lo que hago es cambiar el sentido de X, y la Y la mantengo igual, lo que hace que nada mas la pelota pueda tomar un rebote en forma de " V ",me fije en internet y algunos utilizan un random para el rebote de la pelotita, como seria eso??
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am

Re: Colisiones en SDL

Notapor carlostex » Sab Ene 15, 2011 6:19 am

Bueno, aleatorio no creo que sea muy bueno, cuando jugaba este juego sabia que movimiento hacer para que la pelota valla por donde yo quiera, así es mas interesante pensar en estrategias para hacer perder al otro.
Lo que podrías hacer es tomar a la barra como un espejo, supón que la barra esa fija y la pela choca en ella con un ángulo de 30°, pues lo que arias es espejar ese ángulo, si pones como origen el punto donde choca solo seria cambiar el cuadrante.
pero si la barra se mueve puedes aumentar unos grados el angulo al espejar, un aumento en el mismo lado.
la facilidad con que hagas eso depende de la forma en la que hagas tu animaciones, también hice un juego que tiene un motor, y manejaba las velocidades como un vector, de esa forma creo que es mas facil , solo cambiar el angulo.
Solo es imaginarse las cosas y pensar un poco en la matemática para que salga.
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico

Re: Colisiones en SDL

Notapor kaiser » Sab Ene 15, 2011 1:22 pm

Hola Pablo, lo primero es que debes tener en cuenta la zona de rebote para aplicar el cambio de signo a las velocidades de la pelota, por ejemplo si la pelota choca con la pared superior o inferior del campo de juego deberás cambiar el signo de la VelY pero no de la VelX, en cambio si la pelota choca con las palas deberás cambiar tanto la VelX como la VelY. El problema es que con éste cambio de signo la trayectoria de la pelota será siempre igual partida tras partida y el jugador no tendrá ninguna influencia sobre la trayectoria. Para solucionar ésto una forma sencilla es aplicar un pequeño incremento/decremento aleatorio en el ángulo de rebote al chocar con las palas, pero ésto sigue sin permitir que el jugador influya en la trayectoria de la pelota, por eso lo mejor que puedes hacer es aplicar el consejo de carlotex y tener en cuenta el movimiento de la pala en el momento del choque para modificar el ángulo de rebote. Otra técnica muy popular es determinar en que punto de la pala se ha producido el choque y en función de eso modificar el ángulo de rebote, por ejemplo si choca justo en el centro el ángulo de rebote será igual que el ángulo de incidencia, pero cuanto más hacia los extremos de la pala se produzca el choque mayor incremento/decremento se aplicará al ángulo de rebote

Un Saludo!
De la API al IDE y del IDE a la API.
Avatar de Usuario
kaiser
 
Mensajes: 121
Registrado: Mié Nov 24, 2010 7:47 pm
Ubicación: Madrid (España)

Re: Colisiones en SDL

Notapor Juanxo » Sab Ene 15, 2011 1:29 pm

ya solo por hacer hincapié en lo que te han comentado.. usa el efecto de espejo que te ha comentado Carlos, o algo que se le asemeje, como por ejemplo calcular cual es el vector del centro de la bola al centro de la pala, inviertes ese vector y ya tienes la velocidad de salida
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Colisiones en SDL

Notapor pablo9891 » Sab Ene 15, 2011 8:33 pm

y que me dicen de los cambios en la velocidad de le pelota?, se podria realizar algun calculo ahi?
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am

Re: Colisiones en SDL

Notapor carlostex » Sab Ene 15, 2011 8:50 pm

Pues que yo recuerde pocos de estos juegos he visto que aumenten de velocidad, en mi opinión prefiero que se mantenga, pero la puedes aumentar cuando choca, o por el tiempo que ha estado corriendo el juego, no se te olvide aumentar también la velocidad de las barras, no tan rápido como la pelota pero que si permita poder alcanzar la bola.
El conocimiento de unos es conocimiento de todos.
Avatar de Usuario
carlostex
 
Mensajes: 249
Registrado: Mar Jul 14, 2009 4:13 am
Ubicación: mexico

Re: Colisiones en SDL

Notapor pablo9891 » Mar Ene 18, 2011 7:12 pm

Vuelvo a un problema antiguo respecto de las colisiones, basicamente lo que me gustaria es si pueden ver el codigo de colision que estoy aplicando, ya que encuentro algunos errores que no puedo resolver

el codigo es el siguiente:

Código: Seleccionar todo
   if((miBarra.getY()<(getY()+getAlto())) && (miBarra.getY()+miBarra.getAlto()>getY()+getAlto()))
   {
    if(!(getX()<miBarra.getX()))
    {
     if(getX()+getVelX()<miBarra.getX()+miBarra.getAnc())
     {
      Sirius::reproducirSonido(1);
      setVelX((-1)*getVelX());
     }
    }
   }

   if ((miBarra2.getY()<=getY()+getAlto()+getVelY())&&((miBarra2.getY()+miBarra2.getAlto())>=getY()+getAlto()+getVelY()))//CHOCA CONTRA BARRA DER
   {
    if(!(getX()+getAnc()>miBarra2.getX()+miBarra2.getAnc()))
    {
     if(getX()+getAnc()+getVelX()>miBarra2.getX())
     {
      Sirius::reproducirSonido(1);
      setVelX((-1)*getVelX());
     }
    }
   }


Un ejemplo de los problemas que estoy sufriendo es el siguiente:

Imagen

Fijense que si engancho la pelotita por la parte superior la pelota queda picando dentro de la barrita, cuando deberia picar, ese es uno de los problemas que estoy teniendo, asi que bueno estaria bueno si se pueden fijar el codigo para hacerme algun comentario de que les aprece y si quieren realizar algun cambio pueden hacerlo con total libertad
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am

Re: Colisiones en SDL

Notapor Juanxo » Mar Ene 18, 2011 8:37 pm

el problema es que no manejas bien los casos de colisiones. Creo que lo mejor es que limpies un poco el código, porque con tanto getY, getAlto etc te lías:

Código: Seleccionar todo
int barra1_arriba = miBarra.getY();
int barra1_abajo = miBarra.getY() + miBarra.getAlto();
int barra1_izq = miBarra.getX();
int barra1_der = miBarra.getX() + miBarra.getAncho();

... igual para la otra barra ...


tienes que ser consistente: no puedes tener en cuenta la velocidad en algunos casos y en otros no

- haz diagramas para aclararte: yo veo 5 situaciones posibles a tener en cuenta
Imagen

cada vez que veas que el código no funciona, comprueba estos 5 casos, y mira que tu ejemplo los maneje bien
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Re: Colisiones en SDL

Notapor pablo9891 » Lun Ene 24, 2011 1:10 am

He logrado mejorar els istema de colisiones, hasta el punto en que casi ya no tengo problemas con eso, ahora me estoy enfocando en la parte del rebote, mi idea basicamente es que si la pelota choca contra la parte superior o inferior de la barra teoricamente deberia tomar un angulo mucho mas abierto y al mismo tomar algo mas de velocidad, mientras que si choca contra la parte central reduce un poco la velocidad y hace un angulo algo mas cerrado, pero me preocupa que como decian por ahi, quien juega no tiene el control del angulo que va a tomar la pelota, como puedo hacer para que eso pase?
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am

Re: Colisiones en SDL

Notapor pablo9891 » Mié Ene 26, 2011 5:46 am

Reviviendo el thread, mas o menos he logrado armar una pequeña funcion que dependiendo de donde toque la pelotita la pelota irar para determinada posicion con determinada fuerza, lo que me interesa saber es para lograr rebotes mas reales y aleatorios como puedo implementar desde un punto de vista matematico el tema de los angulos???, es decir que calculo deberia hacer y utilizando que valores??
pablo9891
 
Mensajes: 32
Registrado: Lun Dic 28, 2009 2:48 am


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron