近日读书,学习游戏编程,收获的知识列举如下:
1、把游戏对象放在世界坐标系(World Coordination),绘图的时候把世界坐标系中的坐标转换到屏幕坐标(Screen Coordination)。世界坐标系完全就是模型,与绘图分离。游戏引擎往往需要引入一个Camera类,负责这两者之间的转换。
2、世界坐标系常常用浮点数float,屏幕坐标(像素)只能用整数(int),因此绘图的时候需要把float 转换为 int 。之所以要使用浮点数,是因为如果要把角色移动 0.5像素的话(或者假如一个物体移动得比较慢,每次10个像素,分20次移动,每次0.5像素),结果是角色在屏幕上静止不动。因为0.5被转换为int之后,变为了0。游戏中经常出现需要移动距离小于1的情况。用int来表示物体在模型空间中的数据是游戏编程中新手经常犯的一个错误。
3、世界坐标系通常使用“米(meter)”作为单位,而不是外国人比较喜欢使用的“英里(mile)”、“英尺(cm)”
4、2D 游戏开发,几乎所有的坐标、速度、加速度等等参数都是用二维向量描述(Vector2),Vector2 在2D游戏中相当基础
5、在2D游戏中引入加速度,会带来比较好的游戏体验(比如超级玛丽,当你跳起来的时候,离地时刻到最高点之间速度是逐渐减小的,加速度起的作用)
6、屏幕坐标系与世界坐标系的对应关系: 屏幕坐标系仅仅是世界坐标系的一小部分,当游戏进行的时候,镜头需要跟随需要来移动,因此我们需要设定一个“窗口”来表示屏幕在一个时刻能够看到的那一部分,这个“窗口”叫 frustum,它要封装屏幕对应世界坐标系多大的区域,和一个点,表示这个区域在世界坐标系中的位置(常用中点)。例如 (8.0,4.8) 表示世界坐标系 8米宽,4.8米高的区域,而指定观察点为 (10,15) 的话,则我们能看到的区域就是屏幕上 (10 - 8 / 2, 15 - 4.8 / 2) 到 (10 + 8/2, 15 + 4.8/2) 确定的矩形区域(这里跟分辨率和 aspect ratio 无关)。如果再给 frustum 加上一个比例因子,则可以实现放大(缩小)查看一个区域的功能。
7、在世界坐标是中,物体的坐标常常以这个物体的中心点为准
8、游戏中也少不了碰撞检测,碰撞检测有3种类型:Triangle Mesh, Bounding Box, Boundin Circle。碰撞检测完成之后是如何响应的问题——碰撞响应。
9、在世界坐标系当中,一般仅用简单几何体(常用矩形)作为一个物体的占位符,在绘图的时候,把图片以纹理(texture)的形式“贴”到这块区域。
10、要实现碰撞检测,往往需要根据图片素材,实现建立好外形数据。然而这个数据是根据图片得来的,也是在屏幕坐标系当中的,以像素为单位,是整数;然而我们的碰撞检测是在世界坐标系中进行的,以米为单位,是浮点数。碰撞检测跟绘图没有关系,而跟模型有关系。所以就需要把碰撞外形(Bounding Rectangle)由绘图坐标空间转换到模型坐标空间。
11、OpenGL 渲染小技巧: Alpha 混合是一种开销很大的操作,能不使用的就尽量不要使用,因此,在画游戏的背景的时候关闭Alpha混合,在画游戏物体的时候再打开Alpha混合,既能提高性能又能满足要求。