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%的工作是数据操作,保持数据尽可能简单并可见。确保数据结构与需要解决的问题相称。

浙公网安备 33010602011771号