10 tips de programación de videojuegos

10 tips de programación de videojuegos
Sin comentarios Facebook Twitter Flipboard E-mail

Son muchas las cosas que debemos tener en cuenta los programadores para hacer buen código y aplicaciones eficientes, los programadores de videojuegos y aplicaciones en tiempo real debemos hacer todas ellas y alguna más ya que siempre debemos pensar en optimizar lo máximo posible. Aquí os traigo una lista de 10 tipis de programación de videojuegos que considero importante tener en cuenta.

1. Programa limpio

Es la regla de oro de todo programador, y es la más importante, también para el programador de videojuegos. Usar nombres de variables descriptivos siempre. Evitar cosas como:

int pxj1;
int pxj2;
int pye1;

y usar en su lugar variables más claras:

int jugador1_pos_x;
int jugador2_pos_x
int enemigo1_pos_y;

Cuando lleves más de diez mil líneas de código o lleves unas semanas sin tocar esa parte del código agradecerás haber sido claro.

2. No optimices hasta el final

Espera, ¿Este artículo no trataba de reglas para optimizar? Sí, pero optimiza solo cuando funcione y este terminado, si empiezas a optimizar antes de acabar tendrás un código criptográfico que será muy difícil de corregir o modificar. Así que solo optimiza cuando ya esté todo listo y probado.

3. Ten en cuenta la arquitectura RISC

Lo más probable es que el procesador de tu ordenador esté hecho con arquitectura RISC (Reduced Instruction Set Computer). Esto es que a tu ordenador le gustas las instrucciones simples y no las complejas. Así que por escribir algo como esto:

if( mapa[ jugador.x >> 5 + 4 ][ jugador.y >> 2 + 6 ] == '0' ){ ... }

significa que el procesador vaya a ejecutarlo en un solo ciclo al contrario como el procesador solo recibe instrucciones cortas y simples al compilador le costará más trabajo simplificarlo para dárselo listo al procesador, produciendo un código binario más lento.

4. Usa algoritmos eficientes

Si usas un algoritmo lento tu programa será lento, ya puedes implementarlo entero en lenguaje ensamblador que si tienes un algoritmo de orden O(n2) tu programa irá lento. Así que más importante que el lenguaje es que uses el algoritmo correcto siempre. Hay muy buenos libros de análisis algoritmos ¡úsalos!.

5. Cuidado con C++ y el Polimorfismo

C++ es un gran lenguaje para programar videojuegos te da toda la potencia del bajo nivel de C para optimizar y la programación orientada a objetos que encaja a la perfección con los videojuegos, pero si estas usando C++ y empiezas a usar herencia y polimorfismo con funciones virtuales de forma indiscriminada la velocidad puede caer en picado ya que son procesos que se realizan en tiempo de ejecución, el polimorfismo es un gran invento, pero úsalo adecuadamente. A veces problemas polimórficos se resuelven con uso de templates (plantillas) mejorando mucho la velocidad.

6. Usa funciones inline con cuidado

Cuando usas funciones inline lo que estás haciendo es decirle al compilador que analice dicha función y si es posible sustituya el contenido en donde se hizo la llamada evitando el salto a la función, pero una cosa es que tú lo digas y otra que el compilador lo haga aunque declares todas las funciones de esta manera el compilador analizará cual son las idóneas para ello. Así que no te fíes de que la funciones inline lo serán.

7. Funciones trigonométricas

A menudo en los juegos tendrás que usar cálculos trigonométricos para muchas cosas, pero esto consume una cantidad ingente de tiempo que nos es muy preciado. Es muy ineficiente calcular algo como esto:

x = cos(m)*fuerza;

Así que una solución es al iniciar precalcular los valores trigonométricos que vayas a usar durante el mismo o al menos los más usados y guardarlos en un array y luego simplemente usar esos valores cuando sea necesario:

x = coseno[m]*fuerza;

8. Usa los operadores de bits

Operar con los operadores de multiplicación y división (*, /) consume muchos ciclos de procesador, aunque en los procesadores modernos ya no tanto, pero en las operaciones muy críticas es conveniente evitarlas así que usa solución es usar los operadores de bits de recorrido que mueven a la derecha o a la izquierda (>>, <<) los cuales dividen y multiplican por potencias de 2, es decir:

y = ( y << 3 ); // es lo mismo que y = y*2^3 o en otras palabras y=y*8
y = ( y >> 3 ); // es lo mismo que y = y/2^3 o en otras palabras y=y/8

Si necesitas hacer una división o multiplicación por un número que no es una potencia de 2 puedes dividirlo en dos partes y sumarlos, por ejemplo, si quieres multiplicar por 74:

y = (y << 6) + (y << 3); // osea y = y*26 + y*23 -> y = y*64 + y*8 -> y = y*72

Sí, esto sigue siendo más eficiente que poner directamente y *= 64 ¿mola no?.

9. Evita hacer casts entre int y float

Convertir entre números enteros y de como flotante es una práctica muy habitual, pero para representar el punto flotante en binario se interpreta como una descripción de la forma -25×10^-2 que en binario se ve:

1-1111110-001000000000000000000000000000000000000000000000000000000

donde el primer bit es el signo, los 7 siguientes el exponente y los 56 bits restantes es la mantisa que es el número en sí. ¿Cuántos ciclos crees que le llevará a tu procesador convertir eso en un entero? pues sí, muchos. Así que trata de evitar las conversiones de tipo entre int y float siempre que sea posible.

10. Recorre los arrays grandes con punteros

Muchas veces dentro del desarrollo de videojuegos se tienen que recorrer grandes arrays de datos para procesarlos. Una forma de optimizar esto es usando punteros en lugar de índices, por ejemplo, en un sistema de partículas si tuviéramos:

Particula mi_array[ 21000 ];
for(int i = 0; i < 21000; i++){
mi_array[i].x = .... //cualquier cosa
mi_array[i].y = ....// cualquier cosa
...
}

Se estarían haciendo muchos cálculos para acceder a posiciones específicas dentro del array. Una forma más eficiente sería usando aritmética de punteros:

Particula mi_array[ 21000 ];
Partícula *particula_actual = mi_array;
Particula *fin = &mi_array[ 21000 ];
while(particula_actual++ < fin ){
particula_actual->x = ....// cualquier cosa
particula_actual->y = ....// cualquier cosa
....
}
Comentarios cerrados
Inicio