Sign up with your email address to be the first to know about new products, VIP offers, blog features & more.

Curso programación de videojuegos con SDL – Colisiones

Una vez ya tenemos los enemigos moviéndose, el doble búfer implementado e incluso si queremos la pantalla completa pasemos a establecer algún objetivo en el juego. Para este ejemplo el objetivo será evitar que nuestro avión se choque con los aviones enemigos. Una vez se choquen terminaremos el juego. Aunque esto en un juego real no pasaría dado que es un ejemplo didáctico, es la opción que tomamos. Podríamos también poner un número de vidas por ejemplo, pero esto ya alargaría demasiado el ejemplo (tened en cuenta que tendríamos entonces que escribir con letras y números en nuestra pantalla de SDL, lo que no es tan fácil). Lo que si haremos será que cada vez que desaparezcan los enemigos posicionarlos de nuevo en el comienzo para que vuelvan a aparecer.

Comprobando si existe colisión

Para comprobar si existe colisión calcularemos la distancia entre el jugador y cada uno de los enemigos. Para calcular la distancia, primero hallaremos el centro de cada uno de los enemigos y del jugador para posteriormente calcular la distancia euclidea entre ambos puntos.

Ya que las dimensiones son:

  • Jugador: 59×42
  • Enemigo: 50×40

El centro de cada uno de ellos debe estar desplazado de la posición en la que están dibujados (teniendo en cuenta que SDL dibuja desde la posición superior izquierda del objeto):

  •  Jugador: (30,21)
  • Enemigo: (25,20)

Veamos cuál es la distancia límite a la que pueden estar el jugador y un enemigo (si la distancia es menor se considerará que ha habido una colisión y por lo tanto el juego se termina):

  • Distancia crítica=(30²+21²)^(1/2)+(25²+20²)^(1/2) aproximadamente 69.

Es decir el punto en el que se tocan los extremos de las superficie enemigo con la superficie jugador. Este modo de calcular la distancia no es el más exacto, pero es bastante orientativo. Si quisiéramos calcular la distancia de manera más exacta deberíamos estudiar mejor la geometría y las dimensiones reales de nuestro dibujo (despreciando la parte con transparencia en los extremos).

La función que hace esta comprobación sería la siguiente:

Una vez tenemos la distancia crítica pasemos a ver como ha quedado la función (devuelve 1 si existe colisión, 0 en caso contrario).

Tened en cuenta la diferencia entre centro y posición. El centro es el centro de la superficie y la posición su extremo superior izquierdo.

Paso por paso:

  1. ¿Qué recibe?
  • int x: entero con coodenada X de la posición del jugador.
  • int y: entero con coordenada Y de la posición del jugador.
  • int numeroEnemigos: número de enemigos.
  • struct posicion* posicionesEnemigos: vector con las posiciones de los enemigos.
  1.  Cálculo del centro (30 y 21, por las dimensiones de la superficie del jugador 59 y 42):
  • int centroJugador[2]={x+30,y+21};
  1. Declaración del vector con las coordenadas del centro de los enemigos. Aprovechamos la estructura de datos posición, ya que nos sirve para almacenar las coordenadas X e Y del centro:
  • struct posicion* centroEnemigos;
  • centroEnemigos=(struct posicion*)malloc(sizeof(struct posicion)*numeroEnemigos);

Para cada enemigo además:

  1. Calculamos las coordenadas de su centro:
  • centroEnemigos[i].x=posicionesEnemigos[i].x+25;
  • centroEnemigos[i].y=posicionesEnemigos[i].y+20;
  1. La distancia euclídea entre el centro del jugador y el centro que acabamos de calcular (la expresión no se ve demasiado bien pero es simplemente aplicar la raíz a la suma de los cuadrados de las diferencias de las coordenadas X e Y).
  • distancia=sqrt(pow((double)centroJugador[0]-centroEnemigos[i].x,2)+pow((double)centroJugador[1]-centroEnemigos[i].y,2));
  1. Vemos si la distancia es menor o igual que la distancia crítica:
  • if(distancia<=68) return 1;

Para que el juego terminase en caso de que existiera colisión haríamos una llamada dentro del bucle

Leer entrada anterior
Libresfera, nueva revista libre en español

Los creadores de Libresfera, nos informan directamente que acaba de publicarse el primer número de esta revista, de libre difusión...

Cerrar