总结自Tricks of the Windows® Game Programming Gurus, Second Edition
游戏组成
现在让我们看一下开发游戏与其他类型程序的不同。游戏编程是软件开发中及其复杂的一类,事实上,游戏开发毫无疑问是最难开发的应用程序。因此需要发明一种新的编程方法来更利于实时性应用和模拟,而不是从前你开发过的单线的,事件驱动,或者线性逻辑程序。游戏的基本组成是由一个循环构成其中包含了逻辑控制和画面绘制,通常画面在每秒30帧的速度或更多。这和电影的放映很相似,除了按照你的想法去创造画面。
游戏通常的循环机构
步骤一:初始化
对程序进行初始化,例如内存分配,资源获取,从硬盘加载数据。
步骤二:进入游戏循环
这里是动作的开始和延续直到玩家退出主循环。
步骤三:获取玩家输入
玩家的输入被ai和逻辑部分立即处理或者加入到缓存区中稍后进行处理。
步骤四:AI和游戏逻辑
这个部分包含了大量的游戏代码,人工智能,物理系统 和 通用程序逻辑被执行,运算后的结果被用来绘画下一帧的画面到屏幕上。
步骤五:渲染下一帧
玩家输入与游戏ai和逻辑协同计算后产生了下一帧画面。换面通常先存储到缓冲区域,因此你不能看到渲染过程。之后这个缓冲区非常迅速的被拷贝到显存区进行显示。
步骤六:同步显示
很多计算机由于负载因素导致了游戏画面的显示质量的分级。例如,如果有1000个物体在屏幕上运动,cpu会比仅有10个物体运动的负载要高很多。游戏帧速的频繁变化,是让人无法接受的。因此,你必须同步使游戏固定在一定范围的帧速,可以使用一些延时函数限定帧速。一般,30fps被认为是最优的。
步骤七:循环
这部分很简单,仅仅是重复之前一些步骤的操作。
步骤八:游戏退出
在玩家退出前,必须释放所有资源。
之前的介绍可能过于简化,但具备了所有必要因素。在大多数情况下,游戏循环是一个FSM(有限状态机(学过编译原理的不会陌生吧)),其中包含了许多状态量。下面用c/c++给出游戏循环的梗概表示。
1 // 定义状态量 2 #define GAME_INIT // 游戏初始化 3 #define GAME_MENU // 游戏菜单模式 4 #define GAME_STARTING // 游戏将要开始状态 5 #define GAME_RUN // 游戏正在运行状态 6 #define GAME_RESTART // 游戏将要重新启动 7 #define GAME_EXIT // 游戏正在退出 8 9 // 全局变量 10 int game_state = GAME_INIT; 11 int error = 0; // 用来向操作系统发送错误 12 13 14 // main begins here 15 16 int main() 17 { 18 // 游戏主循环实现 19 while (game_state!=GAME_EXIT) 20 { 21 switch(game_state) 22 { 23 case GAME_INIT: // 游戏正在初始化 24 { 25 // 分配内存和其他资源 26 Init(); 27 // 切换至菜单状态 28 game_state = GAME_MENU; 29 } break; 30 31 case GAME_MENU: // 游戏在菜单模式 32 { 33 // 调用主菜单函数并且切换状态 34 game_state = Menu(); 35 36 // 注意: 我们将在这强制将状态转为运行态 37 } break; 38 39 case GAME_STARTING: // 游戏将要运行 40 { 41 // 这个状态是可选的 42 // 在游戏运行前万事准备完毕 43 Setup_For_Run(); 44 45 // 切换到运行态 46 game_state = GAME_RUN; 47 } break; 48 49 case GAME_RUN: // the game is now running 50 { 51 // 包含整个游戏的逻辑循环 52 // 清空显示 53 Clear(); 54 // 获取输入 55 Get_Input(); 56 // 逻辑和ai 57 Do_Logic(); 58 // 显示下一帧动画 59 Render_Frame(); 60 // 同步显示 61 Wait(); 62 } break; 63 64 case GAME_RESTART: // 游戏正在重新启动 65 { 66 67 Fixup(); 68 game_state = GAME_MENU; 69 } break; 70 71 case GAME_EXIT: 72 { 73 Release_And_Cleanup(); 74 error = 0; 75 } break; 76 77 default: break; 78 } // end switch 79 80 } // end while 81 // return error code to operating system 82 return(error); 83 84 } // end main
游戏循环状态转换图