domingo, 17 de junio de 2012

Capítulo 4: Volúmenes envolventes

Introducción:

En éste capítulo abordaremos el tema de los volúmenes envolventes, un aspecto muy importante en el desarrollo de videojuegos.


4.1: Volúmenes envolventes

En un videojuego, ya sea 3d o 2d, uno de los problemas más importantes es saber cuando y como colisionan dos objetos, además de reaccionar apropiadamente a dicha colisión. Ésto es lo que se denomina "Gestión de colisiones" , un tema muy estudiado y desarrollado.

La gestión de colisiones normalmente se divide en tres fases: Detección de colisión, cálculo de las características de la colisión, y por último la respuesta a la colisión. Aunque ya desarrollaremos más detenidamente éste tema en capítulos posteriores, la primera fase integra una serie de elementos que nos son de gran utilidad: Los volúmenes envolventes.

Pero, ¿Que es un volumen envolvente?
Un volumen envolvente, también llamados recubrimientos simpliciales, es una representación más simple de un objeto, ya sea un polígono en 2d, o un poliedro en 3d. Su utilidad consiste en reducir la complejidad de la detección de colisión entre diferentes objetos.

Veamos un ejemplo. Imaginemos que tenemos dos pentágonos en el plano, y queremos saber si colisionan o no:


Alguno me dirá: "Pues colisionan, lo estoy viendo". Ya, pero recordad que el ordenador no ve.

El problema es bastante más complejo de lo que parece, pero existen muchas maneras de solucionarlo.
Un método sería intentar calcular los puntos de intersección entre los polígonos. Si existe alguno, significa que hay colisión. Pero el problema es que tendríamos que calcular la intersección (si las hay) de m*n rectas, siendo m y n el número de lados de cada polígono respectivamente. Descartado.
Otro método consistiría en averiguar si algún vértice de uno de los polígonos está contenido en el otro y viceversa. Como en el caso anterior, queda descartado, ya que igualmente tendríamos que hacer m+n tests, además que, como veremos más adelante; el test de inclusión de un punto en un polígono suele ser bastante costoso.

Así que ya se ve la complejidad del asunto. Pensemos en un caso más extremo, una escenario en el que sabemos perfectamente que cada polígono está en una punta del mapa. ¿Para que hacer todos éstos cálculos?

Y aquí es donde entran en juego los volúmenes envolventes. La idea es recubrir la figura por otra mucho más simple (Idealmente con un test de colisión más simple), y efectuar primero el test entre las nuevas figuras. En caso de que se detecte colisión entre los volúmenes envolventes, pasar a test más precisos (y costosos) que involucren a las figuras originales.

Éste tipo de metodología es la que se suele usar en la primera fase de  la gestión de colisiones, dividiendo la fase de detección en dos subfases, denominadas "Fase Ancha" y "Fase Estrecha". En la fase ancha, descartas mediante un algoritmo sencillo todos los casos extremos, y solo los que no la pasen continuarán por la fase estrecha, que constará de un test mucho más preciso que la anterior.


4.2: Clasificación de volúmenes envolventes

En la actualidad, se han desarrollado diferentes tipos de volúmenes envolventes, cada uno con sus ventajas y desventajas. Los dos más importantes son:

 - AABB (Axis Aligned Bounding Box): Como su nombre indica, consiste en una caja rectangular alineada con los ejes de coordenadas. Su principal ventaja es que el test de colisión entre ellos es muy sencillo. El problema es que no suele adaptarse muy bien a las figuras. Ideal para la fase ancha.

AABB


- OBB (Oriented Bounding Box): Es un caso especial de AABB que está alineado con el sistema de coordenadas del objeto. Aunque mucho más fiel que el AABB, obtener los ejes de coordenadas óptimos no es facil. Además, el test de colisión es bastante más costoso que el de los AABB.

OBB


4.3: Implementación  de AABBs

La implementación mas sencilla de AABB consiste en guardar los datos sobre la posición y dimensiones del rectámgulo:


De ésta manera, el espacio del AABB queda definido por:

Siendo:
MinX = Coordenadas.X
MinY = Coordenadas.Y
MaxX = Coordenadas.X + Ancho
MaxY = Coordenadas.Y + Largo

Y las esquinas se definen como:
EsquinaSuperiorIzquierda = (MinX,MinY)*
EsquinaSuperiorDerecha = (MaxX,MinY)
EsquinaInferiorDerecha = (MaxX,MaxY)
EsquinaInferiorIzquierda = (MinX,MaxY)

*Como se observa, la esquina superior izquierda es el origen de coordenadas del AABB. En mis implementaciones suelo tomar éste criterio, ya que la mayoría de los sistemas de gráficos por ordenador tienen el origen de coordenadas en la esquina superior izquierda, además de aumentar la coordenada Y hacia abajo.


4.3.2: Cálculo de AABB dado un conjunto de puntos

Calcular el AABB de un conjunto de puntos es algo bastante sencillo: Basta con calcular los cuatro puntos extremos (Mas arriba, más abajo, más a la derecha, y más a la izquierda) del conjunto de puntos, y utilizar sus coordenadas como base para el AABB. Es decir si tenemos los cuatro puntos extremos, llamados Norte, Sur, Este, Oeste, los datos del AABB serán:
Coordenadas = (Oeste.X , Norte.Y)*
Dimensiones = ( |Este.X - Oeste.X| , |Sur.Y - Norte.Y| )

*Recordad que el origen está en la esquina superior izquierda


4.3.3: Test de pertenencia Punto-AABB

Con éstos datos, el test de pertenencia de un punto a un AABB es muy sencillo. Lo único que hay que hacer es examinar si el punto pertenece al espacio definido por los extremos del AABB, es decir, si el punto está entre MinX y MaxX, además de MinY y MaxY:
Pertenece(P) = P.X >= MinX y P.X <= MaxX y P.Y >= MinY y P.Y <= MaxY


4.3.4: Test de colisión entre AABBs

El test de colisión entre dos AABBs se puede abordar de dos maneras:

 - La primera, basada en el teorema de los ejes separados, consiste en evaluar si los intervalos (MinX,MaxX) y (MinY,MaxY) de ambos AABB se superponen:

Es decir:
SuperposiciónX = No ( MaxX' < MinX o MinX' > MaxX)   
SuperposiciónY = No ( MaxY' < MinY o MinY' > MaxY) 

Aplicando las leyes de Morgan:
SuperposiciónX = MaxX' >= MinX y MinX' <= MaxX 
SuperposiciónY = MaxY' >= MinY y MinY' <= MaxY 

Y finalmente:
Colisión = SuperposiciónX y SuperposiciónY


 - El segundo método consiste en transformar el test de colisión en uno de pertenencia Punto-AABB. ¿Como? Veamos:


Lo que tenemos que hacer es generar un  nuevo AABB que contenga a los AABBs originales, de manera que si la esquina origen del segundo (Las coordenadas del AABB) pertenece al nuevo AABB, los originales colisionan. Las características de éste nuevo AABB son:
Coordenadas = (CoordenadasA.X - AnchoB , CoordenadasA.Y - LargoB)
Dimensiones = (AnchoA + AnchoB , LargoA + LargoB)

De manera que el test de colisión se transforma en:
Colisión = Pertenece (NuevoAABB , CoordenadasB)


4.3.5: Test colisión recta-AABB:

Éste test es muy util para realizar una fase ancha en un algoritmo de raycasting. El método que voy a explicar se me ocurrió en un momento de inspiración, y me parece mucho mas sencillo que calcular las intersecciones de los lados del AABB:


La idea es muy sencilla: Si todas las esquinas del AABB están al mismo lado de la recta, la recta no lo atraviesa, y si lo atraviesa en caso contrario. Y como vimos en el capítulo anterior, saber la posición relativa de un punto respecto de una recta es muy sencillo.
Como recomendación, no calculéis las cuatro posiciones relativas y luego las comparéis, ya que, aunque el cálculo sea sencillo, ahorramos algo si vamos comparando paso a paso:

        Public Function Pertenece(ByRef Recta As Recta2D) As Boolean
            Dim Posicion As Double = Recta.SignoPosicionRelativa(EsquinaSuperiorIzquierda)
            Dim P As Double

            P = Recta.SignoPosicionRelativa(EsquinaSuperiorDerecha)
            If P = Posicion Then
                P = Recta.SignoPosicionRelativa(EsquinaInferiorDerecha)
                If P = Posicion Then
                    P = Recta.SignoPosicionRelativa(EsquinaInferiorIzquierda)
                    If P = Posicion Then
                        Return False
                    Else
                        Return True
                    End If
                Else
                    Return True
                End If
            Else
                Return True
            End If
        End Function


4.4: Implementación de OBBs

La implementación de OBBs es algo más complicada que la de los AABBs. Recordemos que un OBB no es más que un AABB definido en el sistema de coordenadas del objeto. Entonces lo primero que tendremos que hacer es encontrar dicho sistema de coordenadas. Es decir, tenemos que calcular la transformación que nos lleve desde el sistema universal de referencia (SUR) hasta el sistema del objeto.

Para ello, tenemos que encontrar los ejes de coordenadas óptimos para el objeto. La manera correcta de hacerlo es mediante el cálculo de la matriz de covarianza del conjunto de puntos del objeto, y de ésta sacar los ejes de coordenadas. El problema es que ésto implica calcular los autovectores de la matriz, un proceso que suele incluir el cálculo de raices de polinomios (Algo bastante complejo). Para solucionar ésto, existen diversos algoritmos que permiten calcular los autovectores sin utilizar la factorización de polinomios. Pero también son bastante complicados.

Voy a exponer un método bastante sencillo para encontrar unos ejes de coordenadas que, aunque no siempre son óptimos, suelen valer:
 - Primero, necesitamos conocer el baricentro del objeto, algo trivial, es la media de todos sus puntos.
 - Segundo, averiguamos cual es el punto más alejado del centro.
 Y ya está, el eje que nos interesa es la recta que une el centro con el punto más lejano.

Ahora solo nos falta calcular la transformación desde el mundo al objeto.En 2d es facil: Ésta será una rotación que convierta una recta en dirección del ejeX en el eje que hemos calculado, seguido de una traslación desde el origen hasta el centro del objeto.
En 3d es algo más complicado, ya que implica la rotación mediante cuaterniones, que veremos en temas posteriores.

Una vez hecho ésto, solo falta calcular el AABB en el nuevo sistema de coordenadas, con los métodos que vimos en el apartado anterior.

Aquí podéis ver mi implementación en acción: OBBs VB.NET

4.4.2: Test de pertenencia Punto-OBB:

Como hemos definido el OBB como un AABB con su propio sistema de coordenadas, solo tenemos que transformar el punto para que esté definido en dicho sistema de coordenadas (Mediante la matriz de transformación que calculamos antes). Una vez hecho ésto, ejecutamos el test de pertenencia Punto-AABB.


4.4.3: Test de colisión entre OBBs

La mayoría de la gente implementa éste test mediante el teorema de los ejes separados, o SAT, por sus siglas en inglés Separating Axis Theorem. En este teorema se define el eje de separación entre dos objetos convexos como aquella recta tal que las proyecciones ortogonales de los objetos sobre ella no se solapan. Nuestras OBBs no colisionarán entre sí, si nuestro algoritmo consigue encontrar un eje de separación entre ellas. En el siguiente dibujo se puede ver la representación gráfica de lo que acabamos de comentar en un ejemplo en dos dimensiones:


El problema que tienen los algoritmos basados en éste teorema es que para asegurar la fiabilidad de los cálculos, hay que probar muchos rectas de proyección.

Otra forma de hacerlo es utilizando el test de colisión entre AABBs. Dados dos OBBs, se calcula el AABB de uno de ellos en el sistema de coordenadas del otro y viceversa. Si ambos test detectan colisión, significa que hay colisión:



4.4.4: Test de colisión recta-OBB

Al igual que el test de inclusión de un punto, basta transformar la recta al sistema de coordenadas del OBB, y utilizar el test del AABB. Para aplicar una transformación a una recta, solo hay que aplicar la transformación a dos puntos de la recta y volverla a generar con los nuevos puntos.


Conclusión

En éste capítulo hemos desarrollado la implementación de los volúmenes envolventes más utilizados en el desarrollo de videojuegos. En el próximo capítulo mostraremos un ejemplo práctico de todo lo que hemos aprendido hasta ahora: La implementación de un Arcanoid


Consideraciones sobre implementación:

Todos los algoritmos explicados en éste capítulo son válidos tanto para 2d como para 3d, con la diferencia de utilizar una dimensión más o menos. Como expliqué en el apartado 4.4, el cálculo de OBBs en 3d la veremos más adelante, cuando veamos rotaciones en 3d.

sábado, 16 de junio de 2012

Capitulo 3: Geometría básica. Algebra

Introducción:

En éste capítulo, abordaremos los aspectos básicos de geometría necesarios para entender los capítulos posteriores. Nótese que no estoy dando todas las explicaciones necesarias, solo es un repaso por encima, ya que mi objetivo no es dar una clase de geometría y álgebra, sino exponer sus utilidades y uso en ciertos aspectos.


3.1: Rectas y planos:

Los elementos geométricos más básicos, además del punto y el vector, son la recta y el plano.
La recta es un elemento muy importante en los vidojuegos, ya sea para seleccionar un objeto en un entorno 3d mediante algún algoritmo de raycasting, o en el algoritmo de raytracing (Aunque ésto hoy en día solo se utilice en películas, ya queda poco para que veamos raytracing en nuestras consolas; o eso parece vistas las nuevas pruebas de NVIDIA). Pero no nos vallamos por las ramas. 
Una recta en 2d está definida por una ecuación general del tipo:
Ax + By + C = 0

Es decir, la reta está formada por todos los puntos que satisfacen dicha ecuación.
Pero además, una propiedad a tener en cuenta es que para aquellos puntos que no pertenezcan a la recta, el signo del resultado de la ecuación depende de en que lado de la recta se sitúen. Ésto nos permite clasificar los puntos del plano fácilmente (Muy util para algoritmos de recorte de polígonos, como veremos más adelante)

El plano, tiene una ecuación general muy similar:
Ax + By + Cz + D = 0

Y al igual que pasaba con la recta en 2d, el signo de los puntos no pertenecientes al plano dependerá de su posición respecto al plano.


3.2: Intersecciones

Utilizando éstas ecuaciones, el cálculo de intersecciones es muy simple. Por ejemplo, en el caso de una recta 2d, la intersección de dos rectas r, s definidas como:
r: Ax + By + C = 0
s: A'x + B'y + C' = 0

No es más que la solución al sistema formado por las dos ecuaciones.
Con dos planos, exactamente igual:
alfa: Ax + By + Cz + D = 0
beta: A'x + B'y + C'z + D = 0

Y la intersección de los dos planos alfa y beta será una recta en 3d. Por ese motivo, las rectas en 3d se definen de manera general como el corte de dos planos. Así, por ejemplo, si quieres calcular el punto de intersección entre una recta y un plano, no tienes más que calcular el sistema formado por los tres planos.


3.3: Posiciones relativas:

Además de la posición relativa entre una recta/plano y un punto,a veces es necesario conocer la posición relativa entre dos rectas, dos planos, o una recta y un plano. Por ejemplo, antes de calcular las intersecciones, ya que en determinados casos puede que no haya intersección. Las posiciones relativas entre éstos elementos se obtiene discutiendo el sistema de ecuaciones de la intersección. 

En el caso recta-recta: Si sale compatible determinado, las rectas se cortan, y la solución es el punto de intersección.
En el caso plano-plano: Si el sistema sale compatible indeterminado, el sistema tiene infinitas soluciones, y por tanto, esos dos planos definen una recta.
El caso plano-recta: Si el sistema es compatible determinado, como en el caso de recta-recta, la solución es el punto de intersección. Pero si es compatible indeterminado, significa que hay infinitas soluciones, es decir, que la recta está contenida en el plano.


Conclusión:

En éste capítulo hemos resumido los aspectos básicos necesarios para desarrollar algoritmos más avanzados que desarrollaremos en el siguiente capítulo, como son la implementación de segmentos, polígonos, o diferentes tipos de volúmenes envolventes.


Consideraciones sobre implementación:

Muchas veces, se define la recta mediante su ecuación paramétrica, ya que el cálculo de intersecciones es mas sencillo (es una ecuación de una única variable). Éste tema lo dejo a elección de cada uno. En mi caso, en los algoritmos geométricos que he implementado suelo utilizar muchas veces la posición relativa de los puntos, así que me conviene usar la ecuación general.

Como se ha visto, el cálculo de intersecciones se basa fundamentalmente en la resolución de sistemas de ecuaciones.

Existen diversos métodos para el cálculo y discusión de sistemas de ecuaciones. Pero si se examinan éstos a fondo. los más fáciles de implementar son aquellos que están basados en el teorema de Rouché-Frobenius, ya que éstos se reducen básicamente al cálculo de rango de matrices.
Normalmente, en los institutos se enseña a realizar éste cálculo buscando la dimensión del mayor menor no nulo, pero implementar éste tipo de algoritmo es complicado, ya que es el tipo de cálculo en el que una persona se basa en la intuición. (Y como cualquiera que se haya metido en programación de IA sabrá, generar una heurística que simule intuición es algo prácticamente imposible).

Así que mi recomendación es calcular el rango mediante el método de Gauss (muy fácil de implementar), y calcular la solución mediante la regla de Cramer (También fácil)

Breve paréntesis


A través de éste blog me gustaría compartir todo mi conocimiento sobre la teoría y desarrollo de videojuegos con cualquiera que desee leerlo, ya sea por mera curiosidad o por necesidad de documentación.

Expondré temas que van desde los fundamentos básicos de los gráficos de videojuegos, la matemática necesaria para la programación de éstos, pasando por algoritmos más específicos. Para su comprensión no se necesita ningún conocimiento especial, pero ayudaría mucho tener alguna experiencia en programación, además de conocimientos de geometría y álgebra a nivel del instituto.

Procuraré mostrar ejemplos de implementación de los temas tratados. Suelo trabajar con Microsoft .NET Framework, así que normalmente los ejemplos ejemplos estarán desarrollados sobre ésta plataforma. Todo dependerá de las circunstancias.

No me atrevo a concretar sobre la frecuencia con la que añadiré nuevos temas, ya que éste blog lo mantengo únicamente en mi tiempo libre. Como en el caso anterior, dependerá de las circunstancias.

Capítulo 2: Transformaciones

Introducción:

En ésta entrada comenzaremos a desarrollar la teoría necesaria para el desarrollo de videojuegos. Empezaremos con una de las cosas más básicas: Como transformar los objetos

En geometría, normalmente se trabaja sobre tres tipos de transformaciones: Traslación, escalado, y rotación.


 - 2.1: Traslación

Imaginemos que tenemos un polígono formado por 5 vértices, con centro en el punto C(1,1), y queremos mover el polígono de manera que su centro acabe en el punto C'(4,2): 



Pues bien, lo único que tenemos que hacer es calcular cuanto se tiene que desplazar el centro, y en que dirección. Es decir, calcular el vector CC'. Una vez que tenemos éste vector, basta sumárselo a todos los vértices para que nos den sus nuevas posiciones.


 - 2.2: Escalado

El escalado no es mucho más complicado. Lo que queremos hacer es que nuestro polígono aumente de tamaño de manera uniforme. Pues bien, para cualquier punto, si multiplicamos sus coordenadas por un factor k, conseguimos que el punto esté k veces mas lejos del origen de coordenadas. Así, si queremos hacer nuestro polígono el doble de grande, solo tendremos que multiplicar las coordenadas de sus vértices por dos.

¿Cual es el problema? Que si el centro del polígono no está en el origen de coordenadas, si lo escalamos, también lo trasladamos. Para solucionar ésto, solo tenemos que mover el polígono para que su centro esté en el origen, escalarlo, y devolver el centro a su posición original. De manera que lo que tenemos es:
Transformación= Traslación -> Escalado -> Traslación inversa


 - 2.3: Rotación

El método de traslación y escalado es exactamente el mismo para 2d y 3d, pero con la rotación no ocurre lo mismo, ya que el método "tradicional" de rotación produce algunos problemas. Pero para hacer las cosas más sencillas, por ahora solo lo explicaré en 2d.

Por ejemplo, queremos rotar el punto A(1,1) +90º (El sentido positivo es el antihorario) alrededor del origen: 

Dados dos ángulos a y b, tenemos que:
sin(a+b) = sin(a) * cos(b) + sin(b) * cos(b)
cos(a+b) = cos(a) * cos(b) - sin(a) * sin(b)

De manera que:
Ax = r * cos(a)
Ay= r * sin(a)
Siendo r el modulo del vector que va desde el origen a A, y a el angulo entre dicho vector y la horizontal (45º)

Si b es el ángulo de rotación (90º) tenemos:
A'x= r * cos(a+b) = r * ( cos(a) * cos(b) - (sin(a) * sin(b) ) = r * cos(a) * cos(b) - r* sin(a) * sin(b)
A'y= r * sin(a+b) = r * ( sin(a) * cos(b) - (cos(a) * sin(b) ) = r * sin(a) * cos(b) - r* cos(a) * sin(b)

Sustituyendo Ax y Ay:
A'x = x * cos(b) - y * sin(b)
A'y = x * sin(b) + y * cos(b) 

Efectivamente, si sustituimos los datos de nuestro ejemplo en las dos fórmulas obtenidas, nos sale A'(-1,1)


 - 2.4: Concatenación de transformaciones. Matrices

Como se ha visto, los cálculos de los tres tipos de transformaciones son muy diferentes entre sí. Pero para que la aplicación de transformaciones sea eficiente, es necesario un método que permita encadenar diferentes tipos de transformaciones de manera sencilla. Ésto se consigue mediante el producto de matrices.

El método consiste en representar cada tipo de transformación mediante una matriz característica, de manera que para encadenar varias transformaciones únicamente hay que premultiplicar las matrices de las transformaciones. 
Además, para poder aplicar la transformación a un punto cualquiera, basta representar las coordenadas del punto mediante una matriz (fila o columna), y premultiplicarla por la matriz de la transformación.

Así, a la traslación definida por el vector V(x,y), le corresponde la matriz:¡
1 0 x
0 1 y
0 0 1

Y a un escalado K le corresponde:
k 0 0
0 k 0
0 0 1

Por último, la rotación de un ángulo a alrededor del origen es:
cos(a) sin(a)  0
-sin(a) cos(a) 0
0          0       1


De ésta manera, la matriz de transformación T que genera un escalado k desde un punto P(x,y), caso que veíamos al final del escalado, será:
T = Traslación(-x,-y) -> Escalado(k) -> Traslación(x,y)

Es decir:
      1 0 x      k 0 0      1 0 -x      k 0 x - kx
T = 0 1 y  *  0 k 0  *  0 1 -y =  0 k y - ky
      0 0 1      0 0 1      0 0  1      0 0   1

          x           x'
Si P = y , P' = y' entonces:
          1           1

P'= T * P

NOTA: Las matrices que he mostrado se corresponden con la representación de coordenadas en matrices columna.

Conclusión:

Como hemos visto, el álgebra necesaria para la transformación de objetos es muy sencilla. De hecho, la gran calidad gráfica de los videojuegos actuales se debe a que éstos y otros algoritmos son ejecutados por la GPU, la cual cuenta con hardware específicamente diseñado para ello. Una GPU de gama media actual es capaz de procesar escenas con más de un billón de vértices. ¿Como lo consigue? Como el cálculo de transformaciones es muy sencillo, lo que hace es ejecutar dicho cálculo paralelamente, lanzando miles de hilos de ejecución, cada uno con la tarea de ejecutar la transformación a un vértice.

Consideraciones sobre implementación:

A la hora de implementar éstos cálculos, mi recomendación es no implementar un punto como una estructura/clase con un campo de coma flotante por coordenada, ya que tendrás que calcular la matriz columna una y otra vez. Mejor implementarlo con un único campo que se corresponda con la matriz columna, y modificar los elementos apropiados de dicha matriz si se desea modificar las coordenadas directamente.

Y recordad: Al aplicar las transformaciones, siempre se premultiplica. Así si tenemos la cadena de transformaciones Transformación = Transformación1 -> Transformación2 -> ... -> TransformaciónN 
la matriz T resultante es: TN * TN-1 * TN-2 *...* T1

Capítulo 1: ¿Por donde empezar?

La industria de los videojuegos ha experimentado un enorme crecimiento en los últimos años, convirtiéndose en uno de los frentes más importantes en lo que a entretenimiento se refiere. Mientras que hace unos años eran las televisiones las que mayor influencia tenían, desde hace unos años ésto está empezando a cambiar. Pero, ¿Que es lo que hace a los videojuegos tan entretenidos?

Es muy difícil contestar a ésta pregunta. Algunos dirán que la evasión de la realidad. Otros que el reto que supone su resolución. Pero está claro que al jugar captan toda nuestra atención. 

Pero hay una cosa que no mucha gente te sabría contestar: ¿Que es realmente un videojuego?
Un programa informático. Vale, que listo, eso ya lo sabíamos todos. Lo que importa es que es un tipo de programa que interactúa con el usuario en tiempo real. Ya, pero nosotros interactuamos con algo. Dos no conversan si uno no habla, se suele decir. Y aquí está la clave: El programa simula algo, con lo que nosotros interactuamos. Ya sea una aventura gráfica, un shooter, un juego de carreras. Solo estamos interactuando con una simulación. 

Lo que quiero hacer entender con ésto es que la programación de un videojuego consiste en crear una simulación de algo, de manera que el usuario crea que lo que está viendo es real. Pero eso no significa que la simulación sea completamente fiel a la realidad. Un videojuego es como las sombras chinas: Tu ves un conejo o un zorro, pero en realidad es la sombra de la mano de alguien proyectada en una pared.
Un videojuego no es más que un conjunto de imágenes y sonidos que se muestran y modifican de una determinada manera para que a tí te parezca algo real.

Y lo que tiene que saber un programador de videojuegos, es como modificar dichas imágenes para que simulen la realidad. Pongamos un ejemplo: Angry Birds.

Nosotros jugamos a matar a unos cerditos lanzando unos pájaros haciendo que las cosas del escenario se derrumben. Pero no es más que un conjunto de imágenes moviéndose en la pantalla. El truco está en hacer que dichos movimientos parezcan reales, Y efectivamente lo parece. Parece que el pajarito a chocado con la caja, que a caído encima del cerdito. En realidad, la escena del juego está compuesta por una serie de polígonos, y el programa se encarga de calcular cuando unos colisionan con otros, y en caso de que ésto ocurra, modificar su trayectoria para que parezca que han "chocado".
Si os pica la curiosidad, el motor de física utilizado en Angry Birds se llama Box2D, y es totalmente gratuito. Lo podéis descargar desde http://box2d.org/

Pues ésto precisamente es lo que trataré en éste blog: Como hacer para que nuestra simulación parezca "real"