游戏程序设计报告
课题名称:3D 赛车游戏
姓 名:
学 号:
班 级:
引言
随着个人电脑的深入普及,人们运用计算机完成许多重要的工作,计算机在人们的生活
中变得越来越重要。而计算机的应用和发展计算机已经不单纯是一个工作工具,人们开始重
视计算机的娱乐性。近年来游戏产业规模持续成长,全球每年游戏业总产值已经突破 200
亿美金,远远超越好莱坞电影产业以及音乐娱乐事业,而成为目前娱乐事业的最大流。不过
游戏产业光鲜亮丽的背景后却隐含着高风险、高成本的危机,显示游戏业慢慢步入微利时代。
计算机游戏是融合了技术和艺术的文化产品,随着网络的发展,休闲化游戏拥有了大量
的玩家,且逐渐发展出棋牌类、音乐类、竞速类、体育类、格斗类和益智类等多种游戏类型,
最常见的竞速类游戏就是赛车游戏,玩家可从疾驰的速度中获得刺激感,而从高超技巧带来
的流畅性操作中还可获取一定的满足感。
摘要
本课题实现了一款 3D 赛车游戏,该游戏分为场景渲染、天空渲染、赛车的地形跟踪和
碰撞检测等几个部分。场景渲染和天空渲染等构成游戏的渲染画面,基于 OpenGL 技术实现。
赛车在场景中的漫游和赛车的地形跟踪系统和碰撞检测构成了游戏的主要逻辑。
本 课 题 选 用 Microsoft Visual C++6.0 并 配 置 OpenGL 来 进 行 开 发 的 。 开 发 环 境 为
Windows7 操作系统。
一、游戏的总体分析与设计
1. 游戏实现的功能
通过仿真游戏地图和游戏场景,完成本系统后能通过 W、A、D、Space 键控制赛车行
驶方向。
2. 创建新游戏
创建新游戏的第一步是创建 GRaceGame 类的对象。通过调用该类的 initGameRes()函数
进行游戏资源的初始化,通过调用该类的 loadMap()函数载入游戏地图,通过调用该类的
updateFrame()函数更新帧,通过调用该类的 drawGame()函数用于绘制每一帧。
3. 系统结构图
初始化
关闭
进入游戏
图形渲染
接收玩家输入
执行游戏逻辑
初始化:这部分执行与其他任何程序类似的标准操作,如内存分配,资源获取,从磁盘
加载数据等。
进入游戏循环:这部分进入游戏循环,用户将在这里不断地执行动作,直到退出主循环
为止。
接受玩家输入:这部分处理玩家输入,或将其存储到缓冲区,供游戏逻辑使用。
执行游戏逻辑:这部分包含游戏代码的主体部分,将执行人工智能,物理系统和通用游
戏逻辑,并根据结果在屏幕上绘制下一帧。
图形渲染:在这一部分中,根据玩家输入以及逻辑的执行结果,生成下一个游戏动画帧。
关闭:退出游戏。、
4. 主要类设计
4.1 地图类:GGameMap
方法:
<1>载入位图高程
bool gLoadHightMap(const char *fileName, int **&ymap, int &w, int &h);
<2>构造地图单列对象
static GGameMap * create();
<3>释放地图单例对象
static void destroy();
<4>得到地图单例对象指针
static GGameMap * getCurrent();
<5>检测指定点与赛道是否发生碰撞
bool isCollision(double x, double z);
<6>清空数据结构, 释放资源
void clear();
<7>载入地图
bool load(const char *fileName, GTreeBillboard *pTreeBillboard);
4.2 池塘类:Gpool
方法:
<1>吃糖构造函数,传入池塘地面纹理和水波纹理
GPool(GTexture2D *pLandTex, GTexture2D *pWaterTex);
<2> 绘制池塘
virtual void draw();
4.3 天空穹类:GSkyDome
方法:
<1>初始化
GSkyDome(GTexture2D *pTex, double r=1000);
<2>绘制
virtual void draw();
4.4 树木类:GTree
方法:
<1>从文件流中载入树木
bool load(FILE *fp);
<2>根据视点坐标更新旋转角度和距离
void update(double cx, double cz);
<3>绘制树木
virtual void draw();
4.5 弯道类:GCurvedRoad
方法:
<1>得到旋转角
double getRotAngle();
<2>设置旋转角
void setRotAngle(double rot);
<3> 绘制直赛道(调用前, 请先设置正确的旋转角度和顺时针标志)
virtual void draw();
4.6 汽车类:GCar
方法:
<1>判断是否刹车
bool isBreak();
<2>设置状态为刹车
void setBreak(bool isBreak);
<3>判断是否转向角
double getSteerAngle();
<4>设置转向角
void setSteerAngle(double af);
<5>绘制汽车
virtual void draw();
4.7 汽车速度表类:GDashBoard
方法:
<1>速度变化,更新指针角度
void changePointer(double v);
<2>绘制仪表盘
virtual void draw();
4.8 迷你地图类:GMiniMap
方法:
<1>绘制道路瓦片
void drawRoadTile(char typ);
<2>汽车的位置
void setCarPos(const GVector3d &pos);
<3>绘制迷你地图
virtual void draw();
二、详细设计
1. 地图资源的加载
赛车地图资源共分为平原高程、山地高程、池塘高程的加载。在功能的实现主要是在
GGameMap 类中实现的。该类中使用 load()方法用于对资源的加载。
2. 天空渲染
天空的渲染主要是使用天空穹技术来实现的。天空穹是一个笼罩在整个赛场之上的半
球,它会随着赛道的改变而发生变化,从而使人感觉一直都在场景之中。在三维赛车游戏中
我们的视线一直是小于 45 度的,所以在绘制天空时不必将半圆形全部画上,只画在我们视
线内的部分就足够。在绘制是主要使用三角网格技术,将没有顶盖的半球分解成若干个三角
形,分别计算出每个三角形各定点的坐标和纹理坐标,在显示列表中绘制这些三角形。
在程序当中,天空穹主要是用 GSkyDome 类来实现的。该类继承于 GShape 类。在
GSkyDome 类得数据成员:
GTexture2D *mpSkyTex;
double
double
double
int
mRadius;
*mTexBuf;
*mVertexBuf;
mTriCount;
// 天空纹理
// 天空穹半径
// 纹理缓冲
// 顶点缓冲
// 三角形数目
同时还有一个 draw()方法用来实现对天空穹的绘制。
3. 赛车道路的绘制
赛道共分为 2 种,分别为直道和弯道。直道的绘制相对比较简单只需要绘制一个矩形即
可,而弯道要用三角网格技术来将赛道分解成许多三角形,弯道有四种类型,但是我们只需
要绘制其中一种,其他三种可以通过旋转绘制出来的那种类型来得到。由于在游戏中并不可
能看到整个赛道,所以在绘制时只需要绘制部分可见的赛道即可。
直 道 的 绘 制 是 在 GStraightRoad 类 当 中 完 成 的 , 该 类 同 样 继 承 于 GShape 类 , 在
GStraightRoad 的构造函数中实现了各个定点的坐标和纹理坐标的计算,最后在通过调用该
类的 draw()方法实现直道的绘制。
弯道的绘制是在 GRoadCirque 类中完成的,同样它也是继承于 GShape 类,它的构造函
数实现了各个定点的坐标和纹理坐标的计算。最后再调用 draw()方法绘制。
4. 赛车模型的加载和绘制
汽车模型需要从文件读取,为了显示汽车轮胎的转动和是否刹车(尾灯的亮与不亮),
车身与四个轮胎和尾灯要分别绘制。用 load()读取汽车模型的文件,汽车也是用三角网格方
法绘制。
在程序当中,使用 GTriMesh 类来实现赛车模型的加载首先通过 loadFromObj()方法对赛
车模型的加载,同时使用 GCar 类对赛车模型进行绘画。
5. 树木的绘制
树木的绘制是采用广告牌的方式进行绘制的。广告牌技术及无论赛车怎样旋转始终是图
片与我们视线锤子,即赛车旋转多少度,图片亦随之旋转相应的角度。树木图片加载后还要
对其进行消影,对树木按与视点的远近进行排序,远处的树排在前面,绘制的时候最后绘制。
树木的绘制主要是在 GTreeBillboard 类中实现的,该类首先通过 load()方法实现对树木
图片的加载,其次使用 update()方法获得树木需要旋转的角度以及树木的距离,最后在调用
draw()进行树木的绘画。
6. 速度仪的绘制
汽车速度表盘的设计与实现:先绘制一个正方形表盘,再贴上红色纹理表示指针。指针
要先平移后旋转,从而达到指针跟随汽车速度的增加与减少而在不同的位置绘制的效果。
速度仪的绘制是在 GDashBoard 中完成的,首先该类使用 changePointer()方法获得在速
度改变是指针需要的旋转的角度,在使用 draw()方法对速度表盘进行绘制。
7. 迷你地图的绘制
迷你地图绘制先是绘制一个地图模型,然后再贴上纹理指针,最后根据汽车的移动计算
出指针的移动速度。
迷你地图的绘制是在 GMiniMap 类中实现的,该类首先通过 drawRoadTile()方法绘制道
路瓦片,然后通过 setCarPos()方法计算出指针一定要速度和方向,最后使用 draw()绘制迷你
地图。
8. 碰撞检测
赛车与公路边界碰撞模式中,赛车的坐标由 4 个轮子进行标定。首先通过公路边界数据,
建立公路边界的两条空间直线的方程。其次获得赛车的实时空间坐标。最后检查赛车坐标是
否位于两直线方程之间。
9. 光照技术
光照是一门为 3D 场景增加真实感的技术,它以某种方式通过对物体分布不同的亮度和
黑暗形成阴影而实现真实感。如同现在许多游戏中见到的一样,光照可以将场景带入到一个
全新的真实感层次。为场景增加光照会对以渲染的场景产生巨大的影响。在计算机图形学中
就三类光源需要考虑,分别是点光源、聚光光源和方向性光源。每类光源分别描述了日常生
活中见到的不同类型的光。计算机图形中有许多不同的反射模型,但最常用的模型分别是环
境光反射模型、满反射模型和镜面反射模型,反射与物体的材质有关。反射模型和光属性一
起确定了 3D 场景中物体的外观。在游戏中,关照通过 GLight 类来实现。通过设置光源类
型、灯光颜色、光源朝向以及光源序号实现该序号光源在实现场景中的光照效果。
三、运行效果
四、总结
光照是一门为 3D 场景增加真实感的技术,它以某种方式通过对物体分布不同的亮度和黑暗
形成阴影而实现真实感。如同现在许多游戏中见到的一样,光照可以将场景带入到一个全新
的真实感层次。为场景增加光照会对以渲染的场景产生巨大的影响。在计算机图形学中就三
类光源需要考虑,分别是点光源、聚光光源和方向性光源。每类光源分别描述了日常生活中
见到的不同类型的光。计算机图形中有许多不同的反射模型,但最常用的模型分别是环境光
反射模型、满反射模型和镜面反射模型,反射与物体的材质有关。反射模型和光属性一起确
定了 3D 场景中物体的外观。在游戏中,关照通过 GLight 类来实现。通过设置光源类型、
灯光颜色、光源朝向以及光源序号实现该序号光源在实现场景中的光照效果。