Programación de videojuegos - Físicas

Una de las partes básicas de los juegos es la interacción de los personajes con el mundo creado y entre los diferentes elementos del juego. Estas interaciones tienen que estar reguladas por algunos principios. En la vida real se aplican las leyes de la física a los objetos, lo que hace que una piedra caiga atraída por la fuerza de la gravedad, un objeto pierda velocidad cuando entra en el agua o simplemente un objeto no pueda atravesar una superficie rígida, como una pared o a otro objeto.

Para dotar al juego de cierto realismo necesitamos que se apliquen ciertos principios que simulen las leyes que se aplican a la vida real.

Cuando se utilizan físicas para producir simulaciones estas suelen incluir multitud de parámetros y factores que recrean con precisión una situación real, algunos de los cuales pueden llevar mucho tiempo de proceso. En el mundo de los videojuegos el tiempo para aplicar los cálculos de la física al juego es de unos milisegundos (como vimos en la entrada dedicada al Game Loop), por tanto requieren de una simplificación de los cálculos que se van a aplicar.

Aunque no todos los juegos necesitan de un motor de físicas, lo cierto es que hay dos facetas que la gran mayoría de juegos necesitan de una manera u otra: 

  • Físicas para el movimiento: Tienen en cuenta fuerzas, aceleración, masa, y otras propiedades inherentes a la mecánica clásica para determinar dónde van los objetos de un frame a otro
  • Detección de colisiones: Determinar cuando dos objetos del juegos se cruzan o no

En los juegos que requieren movimiento en un mundo (que no necesariamente tiene que seguir las mismas leyes que nuestro mundo), se tiene que aplicar alguna forma de física para simular el movimiento. La mayoría de juegos se basan en la física neutoniana (o mecánica clásica), principalmente utilizando la mecánica lineal. En este modelo el bloque de construcción más básico para programar el movimiento es el vector (concretamente el vector geométrico).

Vector

Por otro lado, para la detección de colisiones se utilizan figuras geométricas sencillas como líneas, esferas o rectángulos. Existen formulas que nos permiten calcular si estas figuras geométricas se intersecan con otras.

Colisiones en figuras 2D

Como todo esto se repite siempre para los diferentes juegos, he desarrollado una librería en Vala que nos permite trabajar con vectores (incluye una clase vector2D y los métodos para aplicar las operaciones con vectores) y por otro permite la detección de colisiones, en la que se utilizan, como hemos comentado, figuras geométricas sencillas, puntos, líneas, círculos, rectángulos y rectángulos orientados, e incluye los métodos para comprobar las colisiones.

Aunque la librería esta todavía en desarrollo, ya es funcional la parte relativa a los vectores y las colisiones para los siguientes objetos 2D:

  • Point2D
  • Line2D
  • Circle2D
  • Rectangle2D
  • OrientedRectanble2D
  • GroupShapes2D

Para instalar la librería desde el repositorio git:

$ git clone https://git.clibre.io/sgp/sgp.git

Para construir e instalar:

$ cd sgp
$ meson build
$ cd build
$ ninja
$ ninja install

Uso de la librería

Vamos a ir viendo algunos ejemplos de su uso en diferentes entradas. Hoy vamos a mostrar un ejemplo básico de colisiones usando las figuras geométricas básicas. En nuestros juegos utilizaremos estas figuras básicas, en ocasiones combinándolas para formar figuras más complejas.

El código es similar al que hemos visto en entradas anteriores.

En la clase GameLoop hacemos uso de la librería para dibujar la figuras y comprobar las colisiones.

En create_shapes () creamos cuatro formas geométricas para el cursor y otras cuatro para poner en pantalla:

line_c = new Line2D (new Point2D (150, 300), new Point2D (250, 350)); 
circle_c = new Circle2D (new Point2D (400, 400), 40); 
rectangle_c = new Rectangle2D (new Point2D (100, 100), 
                                new Point2D (150, 150)); 
oriented_rect_c = new OrientedRectangle2D (new Point2D (100, 100), 
                                            new Vector2D (25, 50), 00.0f); 
shape_c = line_c; 
 
line1 = new Line2D (new Point2D (100, 400), new Point2D (300, 400)); 
circle1 = new Circle2D (new Point2D (400, 400), 40); 
rectangle1 = new Rectangle2D (new Point2D (600, 350), 
                                new Point2D (750, 450)); 
oriented_rectangle1 = new OrientedRectangle2D (new Point2D (1050, 400), 
                                            new Vector2D (100, 50), 00.0f); 

Lo más interesante lo tenemos en la función update () donde comprobamos si se realiza la colisión de la figura que se mueve con el cursor, con las que tenemos en pantalla. La comprobación es muy sencilla ya que solo hay que llamar al método collision () de cada figura y pasarle como parámetro la figura contra la que queremos hacer la comprobación. Si existen colisión pintamos el borde de un color y si no hay colisión de otro color:

if (shape_c.collision (line1)) { 
    line1.set_rgba_color (80, 22, 10, 255); 
} else { 
    line1.set_rgba_color (255, 255, 255, 255); 
} 
if (shape_c.collision (circle1)) { 
    circle1.set_rgba_color (80, 22, 10, 255); 
} else { 
    circle1.set_rgba_color (255, 255, 255, 255); 
} 
if (shape_c.collision (rectangle1)) { 
    rectangle1.set_rgba_color (80, 22, 10, 255); 
} else { 
    rectangle1.set_rgba_color (255, 255, 255, 255); 
} 
if (shape_c.collision (oriented_rectangle1)) { 
    oriented_rectangle1.set_rgba_color (80, 22, 10, 255); 
} else { 
    oriented_rectangle1.set_rgba_color (255, 255, 255, 255); 
} 

Tenemos el ejemplo completo en el repositorio git:

$ git clone https://git.clibre.io/sgp/shapecollision.git

Para construir e instalar:

$ cd shapecollision
$ meson build
$ cd build
$ ninja
$ ninja install

Shape Collision Demo 

Lógicamente en nuestros juegos normalmente no usaremos estas figuras básicas, la idea es que cuando creamos nuestros personajes en el juego (que como hemos visto en entradas anteriores son texturas), le asociamos una o varias figuras geométricas que nos van a permitir de forma sencilla calcular las colisiones. Lo iremos viendo en posteriores entradas.

Modificado por última vez enSábado, 02 Octubre 2021 18:33
(4 votos)
Etiquetado como :

Deja un comentario

Asegúrese de introducir toda la información requerida, indicada por un asterisco (*). No se permite código HTML.