Day1 通用游戏编程指南

1. 不要在时间关键代码部分和内存关键代码部分使用高级API

你可以信任像DirectX之类经过精简的高性能函数,但应该避免使用基于Win32 API的高级函数。如memset,或许你觉得它的速度很快,但它只使用单字节进行填充。更好的填充方法是使用QUAD(四元数),因为它可以一次写入4字节。

inline void Mem_Set_QUAD(void *dest, UINT data, int count)
{     
    //count为QUAD数目     
    //该函数用来移动32位对齐内存
    _asm
    {         
        mov edi, dest;   //edi指向目标内存         
        mov ecx, count;  //要移动的32位字数 
        mov eax, data;   //32位数据         
        rep stosd;       //移动数据
    }
}                                                                                
//使用WORD(2字节数据)进行填充
inline void Mem_Set_WORD(void *dest, USHORT data, int count)
{
     //该函数填充16位对齐内存
     //count为WORD数目
    _asm
    {
         mov edi, dest;  //edi指向目标内存
         mov ecx, count; //要移动的16位字数
         mov ax, data;   //16位数据
         rep stosw;      //移动数据
    }
}

2. 使用内嵌函数

可以使用编译指令inline来完全避免函数调用。

编译器的数据别名处理(data aliasing)?

3. 尽可能使用32位变量而不是8位或16位变量

对于32位或者64位的CPU来说,更小的数据将会由于高速缓存和其他相关的内容寻址问题,降低程序的运行速度。

4. 不用害怕使用全局变量

很多游戏在对于时间要求很严格的函数中都不实用参数,而是简单地使用全局参数。

比如,对于以下函数:

void Plot(int x, int y, int color)
{     //在屏幕上绘制一个像素
     video_buffer[x + y*MEMORY_PITCH] = color;
}

函数体调用的时间比函数本身花费的时间还要多,这是由于参数进栈和出栈引起的,更好的方法是创建一个全局参数,在调用函数前给它赋值:

int gx, gy, gcolor;                                               
void Plot_G(void)
{     //根据全局变量来绘制像素
     video_buffer[gx + gy * MEMORY_PITCH] = gcolor;
}

5. 以RISC(Reduced Instruction Set Computer,精简指令集计算机)方式进行编程

使代码尽可能简单,不要编写类似下面的代码:

if (x += (2 * buffer[index++]) > 10)
{     //执行处理
}

而是应该修改为如下:

x += (2 * buffer[index]);
index++;                                     
if (x > 10)
{     //执行处理
}

后一种编码方式允许调试器在代码段之间设置断点,其次使得编译器更容易为奔腾系列CPU简化代码,允许它使用多个执行单元并行处理更多代码。

6. 对于乘以/除以2的幂这种简单运算,应该使用二进制移位

int y_pos = 10;
//将y_pos乘以64
y_pos = (y_pos << 6); // 2^6 = 64
//将y_pos除以8
y_pos = (y_pos >> 3); //2^3 = 8

7.慎用C++和多重继承,除非你非常熟悉C++和游戏编程

8.对于简单对象,不要编写复杂的数据结构

视频游戏90%的工作是数据操作,保持数据尽可能简单并可见。确保数据结构与需要解决的问题相称。

posted @ 2013-11-26 00:05  小甚  Views(177)  Comments(0)    收藏  举报