




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、毕毕 业业 设设 计计( 论论 文文) 基于基于 vcvc 的飞行模拟游戏的设计及实现的飞行模拟游戏的设计及实现 论论文作者姓名:文作者姓名: 申申请请学位学位专业专业: : 申申请请学位学位类别类别: : 指指导导教教师师姓姓名名( (职职称称) ): : 论论文提交日期:文提交日期: 基于基于 vcvc 的飞行模拟游戏的设计及实现的飞行模拟游戏的设计及实现 摘摘 要要 电子游戏的出现代表了一种全新娱乐方式的诞生。目前,电子游戏正以其 独特的魅力吸引着众多的玩家。随着游戏产业的蓬勃发展,越来越多的人加入 到了游戏开发的行业。游戏开发涵盖了程序设计、文学、历史、音乐及美术等 诸多方面的内容,除
2、去市场价值的意义,电子游戏的发展的必要性还在于对我 国文化产业的发展的重要性,游戏作为一种特殊的创意文化产品形态,是文化 产业链中不可缺少的一环。设计在利用已有的开发包和已有的游戏框架的基础 上,采用 microsoft visual c+2005 为开发平台,这些开发包和框架已经完美地 解决了游戏图像和音效方面的问题,设计的主要工作就是向框架中添加自己所 设计的类,用于实现设计所要实现的功能。在进行类的设计时,运用 c+所具 有的继承和派生功能,使很大一部分代码能够得到重用,从而实现多态,同时, 还要在父类中很好地引入虚函数,为指针能够指向子类的同名成员提供方便, 然后利用开发包里的方法来实
3、现游戏背景的显示,最终得到一个在 microsoft visual c+2005 上运行的飞行模拟游戏,同时在运行时不会出现重大尤其是会 令游戏崩溃的 bug。 关键词关键词:飞行模拟;多态;代码重用 design and realization of a flight simulation game based on vc abstract the appearance of computer game has represented the naissance of a totally new sort way of entertainment. at present, the compu
4、ter game has attracted a great deal of players by its unique charm. along with the game industry flourishing, more and more people has joined the profession of game development. game development has covered many contents including programming, literature, history, music, arts ,etc. eliminate the sig
5、nificance of market value, game develop is quite important to the culture evolution of our nation to be a special kind of creativity culture production. game is indispensable to the chain of culture industry. the design based on the develop package and the game frame which already exist uses microso
6、ft visual c+2005 to be the platform. these develop package and game frame has raveled out the problem which relate to image and sound effect perfectly. the main task of the design is to add classes that planed by oneself to the game frame, to actualize the function which the design have to realize.
7、when we carry through the classes design, use the inherit and derive function, we need to enable a majority of code can be reused, aim to actualize polymorphism, at the same time. it is necessary to use virtual function in the baseclass, to make pointer can point to the member which has the same nam
8、e in the subclass more convenience, afterwards, utilize the develop package to realize the demonstration of game background, finally obtain a flight simulation game which can run on microsoft visual c+2005, and theres no seriously bugs especially that can make the game crash when running. key words:
9、 flight simulation; polymorphism; code reuse 目目 录录 论文总页数:26 页 1引言 .1 1.1课题背景 .1 1.2国内外研究背景 .1 1.3本课题研究的意义 .1 1.4本课题研究的方法 .1 2游戏软件的现状和 vc 的概况 .1 2.1中国游戏软件的现状 .1 2.2c+简介 .2 2.3microsoft visual c+简介 .3 2.4利用 visual c+开发游戏简介.3 3开发环境介绍 .3 3.1开发环境 .3 3.2关于 allegro.4 4游戏程序的开发 .4 4.1游戏的思路和构想 .4 411 游戏想法的产生
10、.4 412 对游戏设计的初步认识 .4 413 模块成型阶段 .4 4.2程序的类结构 .5 4.3游戏的实现 .5 431 主类 level 的实现 .5 432 object 类的实现.11 433 plane 类的实现.12 434 player 类的实现.14 435 enemy 类的实现.15 436 bullet 类的实现.16 437 prize 类的实现.17 5程序设计过程中遇到的一些重要问题 .18 5.1关于碰撞的问题 .18 5.2关于游戏画面的问题 .21 5.3关于玩家控制的问题 .23 结 论 .24 参考文献 .24 致 谢 .25 声 明 .26 第 1 页
11、 共 26 页 1 1引言引言 1.11.1 课题背景课题背景 现今,游戏软件已经成为盈利最高的软件之一,而且还在向着复杂化、大 型化发展,其中,很多由 visual c+作为开发工具的游戏都取得了巨大的成功, 比如暴雪公司的魔兽争霸系列和魔兽世界,这说明 visual c+开发游 戏具有一定的优势。所以,在 visual c+平台上设计游戏是极为方便的,这也 是优势所在。 1.21.2 国内外研究背景国内外研究背景 无论是在国内还是国外,游戏编程已经成为了一种时尚,许多程序员都忘 我地投入到其中,他们其中有很多人不光是为了盈利,也有很多是纯粹为了兴 趣,许多著名的游戏编程员本身就是狂热的游戏
12、玩家,所以,无论是国内还是 国外,诞生了很多经典的游戏,其中利用 visual c+作为开发平台的更是不胜 枚举,但是由于我国的游戏编程相对于国外起步较晚,所以在很多地方还存在 不小的差距,甚至成了很多游戏软件业比较发达的国家的游戏加工厂。 1.31.3 本课题研究的意义本课题研究的意义 目前,市面上的游戏可以说是层出不穷,并且随着电脑硬件系统的改良, 未来的游戏必将更智能化,更艺术化,更人性化,在高性能的硬件设备支持下, 游戏的驱动引擎更具威力,控制功能更加完备,给人们带来更丰富的娱乐和体 验,好的游戏给人们的生活带来了健康愉快的补充,唯美的艺术享受,潜默的 教育功效,时尚的情感陶冶,如果没
13、有足够的优质游戏,那么市场就不免会被 粗劣的游戏充斥,可以说,对于青少年来说,谁对游戏编程有着更深入的理解 和掌握,谁就掌握着游戏的导向权。 1.41.4 本课题研究的方法本课题研究的方法 采用 microsoft visual c+2005 为开发平台,在利用已有的开发包和已有 的游戏框架的基础上,这些开发包和框架已经完美地解决了游戏图像和音效方 面的问题,设计的主要工作就是添加自己所设计的类,用于实现本设计所要实 现的功能,在进行类的设计时,运用 c+所具有的继承和派生功能,使很大一 部分代码能够得到重用,同时,还要在父类中很好地引入虚函数,为指针能够 子类的同名成员提供方便,最后利用开发
14、包里的方法来实现一个游戏背景的显 示。 2 2游戏软件的现状和游戏软件的现状和 vcvc 的概况的概况 2.12.1 中国游戏软件的现状中国游戏软件的现状 软件产业是当前世界上增长最快的朝阳产业之一,并将成为 21 世纪推动 世界经济发展和社会进步的重要动力。近年来,主要国家软件业平均以 11以 第 2 页 共 26 页 上的增长率快速发展。据“oecd2000 年信息技术展望”报告,1997 年,其增长 率成员国仅软件包产值就占世界市场份额的 94,达 1080 亿美元,并自 1990 年以来年 11.2。美国是世界上最大的软件生产国,1997 年的软件产值为 1705.9 亿美元,占其当年
15、 gdp 的 2.1,出口额为 155.5 亿美元。日本其次, 1998 年软件产值约 570 亿美元,但出口仅为 0.82 亿美元。英国列第三,1999 年的软件产值为 377.46 亿美元,占其 gdp 的 1.2,出口约 16.2 亿美元。据 对各国软件业发展的轨迹分析,虽然各国的产业规模和出口额相差较大,但其 成功的因素可归纳为以下几点:1. 对软件知识产权的严格保护,营造一种谁投 资谁受益的良好商业和法治氛围; 2. 服务到位的融资机构,促进软件成果转 化快; 3. 高素质的软件专业人才,配合制定灵活的技术移民政策; 4. 具有 第一流的大学教育,能够迅速适应市场对人才的需求; 5.
16、 发达的通信设施; 6. 长期磨炼的企业家精神; 7. 巨大的市场需求。 相比于其他国家,我国的软件产业特别是游戏产业起步较晚,在很多地方 上都不及一些软件大国,但是近年来我国软件业发展迅速,有关统计数据显示, 2001 年,软件产业销售收入仅为 796 亿元,到了 2006 年年底已经达到 4800 亿 元,5 年增长了 6 倍多。但与软件产业发达国家相比,差距依然很大,绝大部 分市场被国外软件业巨头垄断,国产软件占据的市场份额很少。在国际市场上, 2005 年国产软件出口额为 35.9 亿美元,仅占全球软件市场份额的 5.9%。 2.22.2 c+c+简介简介 c+语言是在 c 语言的基础
17、上为支持面向对象的程序设计而研制的通用程序 设计语言,它是由 at 同时,在游戏运行中会发生不同的事件,也需要一一定义,由于游戏事件 较多,同理,也需要定义一个枚举类型来定义众多的事件 enum event e_renewplayer,/! 创建玩家,关闭所有事件 e_readydelay,/! 显示ready前的等待,并启动e_ready 事件 e_ready,/! 显示ready,启动e_renewplayer 事件 e_levelend,/! 使关卡处于完成状态,表示通关 e_levelfailed,/! 使关卡处于失败状态 e_levelfaileddelay,/! 关卡失败前的等待,
18、并启动e_levelfailed 事件 e_levelenddelay,/! 关卡通关前的等待,并启动e_levelend 事件 ; 接下来,我们所要做的,便是创建关卡,从关卡文件中读入物体数据,创 建物体并加入到关卡中 bool create (char *name, dev:resourcemanager* rs, dev:keyboard *kb); 在关卡最初创建时,需要把敌机数目设置为 0,把关卡状态设置为运行, 同时应该关闭定时器。接着就是使用 io 包内的 readfile 创建对象 rf,方便读 取文件,以实现关卡中敌机的初始化,由于 io 包不透明,所以无法了解其内部 是如何
19、实现这一功能的,在此,只能列出在文本中的格式,格式如下: 视图 奖子 爆炸 子弹 体力 坐标 x 坐标 y 策略号 第 7 页 共 26 页 视图有两种:编号 1 表示使用第一个敌机图片,编号 2 表示使用第二个敌 机图片;奖子有四种:编号 0 表示没有奖子,编号 1 表示奖一个生命的奖子, 编号 2 表示奖励三发子弹武器的奖子,编号 3 表示奖励 20 分的奖子;爆炸有三 种:编号 0 表示小型爆炸,编号 1 表示普通爆炸,编号 2 表示大型爆炸;子弹 有四种:编号 0 表示小单发子弹,编号 1 表示双发子弹,编号 2 表示三发子弹, 编号 3 表示反弹型单发子弹,编号 4 表示高速双发子弹
20、;体力的数值就表示可 以被攻击多少次;坐标的两个数值即为敌机在关卡中的坐标位置。 比如说,要设置一个使用第一张敌机图片,掉落一个奖励 20 分的奖子,爆 炸类型为普通爆炸,发射小单发的子弹,可被攻击 1 次,坐标为 60 80 的敌机, 那么就在文本文件中输入 1 3 1 0 1 60 80 由于这里涉及设备层中的资源管理器,提供加载图片和声音的服务以及设 备层中的键盘,提供输入查询,具体的实现将放到重要问题说明中详细介绍。 关卡创建完毕,就应该向其中添加我们想要的东西,并使其工作 void level:add (object *o)/向关卡里添加敌机的实现 int id = o-getrun
21、timeclassid();/获取物体运行时的类id if (id=enemy:classid)/如果物体是敌机,增加敌机数目 mnumenemies+; 在这里向关卡中添加敌机时先要判断当前被添加物体是否为敌机,如果是 才添加,如果不是,则不添加。 敌机添加完毕就需要创建玩家,玩家的位置是固定的,把玩家的坐标位置 设置为:x 轴坐标设置为当前关卡 x 轴的二分之一,y 轴坐标设置为当前关卡 y 轴最大值减 20 p-setpos ( 要添加,就必须要移出,所以相应的,也就有摧毁物体,比如在关卡结束 后,我们需要摧毁关卡中所有的资源,所以我们定义一个 destroy 方法,摧毁 关卡中的所有物
22、体,释放资源给资源管理器,比如图片和声音 void destroy (dev:resourcemanager* rs); 同时,关卡还需要处理玩家或者敌机的死亡,我们定义一个 processdie 的 方法来实现,流程如下 第 8 页 共 26 页 图 2 处理飞机死亡流程 其中在判断物体的类别,并且完成玩家和或者敌机的死亡后继续判断玩家 的生命是否用尽和敌机数目是否为 0,这样做的目的是为了避免在玩家和最后 一个敌机同归于尽的时候依然进入关卡结束事件。 而 update 方法算是 level 类中比较关键的方法,他更新关卡中的所有物体, 包括检测碰撞,更新定时器,处理碰撞等,其中最主要的方法
23、便是物体的越界 第 9 页 共 26 页 处理,首先计算物体的坐标与关卡边缘是否发生相交,其中判断是否在 x 轴越 界的算法为:取出物体的坐标,判断其是否小于关卡的坐标 x1 或者其是否大于 关卡的坐标 x2,若满足一项时,则调用 object 类中的 onoutofarea 方法,实 现每个物体不停的越界实现,流程图如下 图 3 判断物体是否在 x 轴上越界流程 其中,关于检测物体碰撞由于是本设计的重点和难点,将放在后面的重要 说明中具体说明。 关卡还需要实现两个方法,那就是 getnearestenemy 和 getnumcompanies,它们主要是用来实现敌机的攻击策略的,这里首先要声
24、明一 下,当玩家,敌机和奖子类被创建时,都会获取一个 id,以表明其身份,同样 的,凡是通过这几个类创建的对象也具有与其所属类相同的 id,通过这样的方 法,就可以把关卡中众多的物体相互之间区分开。 getnearestenemy 主要是实现敌机将离其最近的玩家作为目标,以实现跟 踪策略,其基本思想是,以当前物体作为中心,对整个关卡中的物体进行一个 遍历,若它们同为敌机,则继续,若它们一个为玩家,一个为敌机,则计算出 与其的距离,选出其中与自己距离最小的物体,判断其是否小于最小距离,若 小于,则把当前物体锁定为自己的目标,流程如下 开始 取出当前物体的坐标 是否大于关卡坐标 x2 或者小于关卡
25、坐标 x3 通知物体做越界处理 结束开始 第 10 页 共 26 页 图 4 锁定最近敌人的流程 getnumcompanies 方法主要是用于给敌机策略提供一个接口,它是基于这 样一个想法,那就是当敌机总数大于一个数值时,敌机不会做出任何攻击动作, 而当玩家消灭一定数量后,敌机便会实行攻击策略,getnumcompanies 就是让 敌机获取当前敌机总数,当其返回值小于一定的值时便执行攻击策略,实现的 方法仍然是对以当前所指向的物体为中心进行遍历,若被遍历到的物体与其为 第 11 页 共 26 页 同一队伍且同为敌机或玩家,则同伴数目增加 1,最开始时,同伴数目设置为 0,流程如下 图 5
26、取得同伴数目流程 此外,关卡还需要管理增加玩家生命和得分,用于实现玩家“吃”掉奖子 后的属性改变,分别定义为 addplayerlife 和 addscore 方法实现,实现方法为 他们实现自加即可。 4 43 32 2 objectobject 类的实现类的实现 object 类主要管理物体的可视性,速度,以及判断设置物体的队伍和判断 队伍是否一样等,他抽象了所有的物体,也就是说,其中所有的属性和方法是 一切物体都具有的,这样做是为了增加代码的重用量,这也是运用 c+开发游 戏的好处之一,但是,这样做就要求把 object 类的析构函数设为虚函数,这是 因为如果不将析构函数设为虚函数的话,那
27、么当用一个 object 类的指针删除一 个其子类的对象时,子类的析构函数就不会被调用,虽然这样做并没有什么实 际意义,但是这却符合用 c+进行软件开发的时候一般用来做基类的类的析构 函数设为虚函数的默认规定,因此,需要将析构函数设为虚函数。 第 12 页 共 26 页 此外,还有几个方法是需要重点提及的: objecttracer* settracer 是设置越界处理器,这个处理器将处理物体的 越界事件 objecttracer* settracer (objecttracer* tr)/指针指向新的越界处 理器 objecttracer* old = mtracer; mtracer =
28、tr; return old;/返回旧的越界处理器 setdirection 是用来设置物体的移动方向,这个方向为用来修改物体的当 前运动速度 void setdirection (vector* dir)/指针指向新方向向量 vector* vel = getvelocity(); dir-normalize ();/ 单位化这个向量 vel-multiply (dir);/ 应用这个向量到速度上 onoutofarea方法是为了实现物体越界的处理函数,将任务代理给mtrancer 处理,这样实现了objecttracer接口的类都可以处理物体的越界 void onoutofarea (bo
29、ol onx)/onx 为真的话表示在x轴上越界,否 则在y轴上 if (mtracer) mtracer-onoutofarea (this, onx); 通过这样的方法,在前面提及的level类中的update方法就可以成功地实现 越界处理。 另外,顾名思义,所谓object类,肯定是要设定所有物体的属性的,这些 属性包括是否可见visible,是否可碰撞collidable,物体所属队伍号team,设 置位置setpos和获取位置getpos,设定速度setvelocity和获取速度 getvelocity,需要说明的是,这里的速度不是普通的标量,而是一个矢量,即 它是有方向的,这样做的
30、好处就是由于飞机是只能向前开火,并且其面朝的方 向应该和其速度的方向一致,那么如何来实现这两点呢?这就需要把速度设置 第 13 页 共 26 页 为一个矢量,这样一来,就可以把飞机的开火方向和面朝方向与速度方向取一 致。 4 43 33 3 planeplane 类的实现类的实现 plane 类是 object 类的子类,它通过 object 类公有继承而来,所以,凡 是 object 类中有的方法和属性,它也具有,当然,我们必须为起添加新的函数 或者数据,那么飞机相对于其他物体特有的属性是什么呢?对,那就是它们死 亡的时候会发生爆炸,它们也能发射子弹,而每种飞机所产生的爆炸类型和所 发射的子
31、弹类型都是不同的,所以,我们在 plane 类中就设定几个方法来设定 物体的爆炸类型,所发射的子弹类型以及他们的速度 飞机的死亡会产生爆炸,同时也会变得不可见 void plane:die(void)/死亡的实现 object *obj = mef-create (mexpltype); if (obj) obj-setpos (this-getpos(); mlevel-add (obj); disappear (); 凡是玩过飞机游戏的人都知道, 飞机是不能连续发射子弹的,在两 次发射子弹之间,必须要有一定的 冷却时间,而这个功能是由 plane类的一个update方法实现,思 路为:对每
32、一个飞机都设定一个定 时器cooltimer,初始值为10,然后 不断对它进行检查,只要它的值不 为0,就进行自减,如果某个飞机有 开火请求的话,就检查定时器的值是否为0,如果为0,则允许开火,同时定时 器的值复位为初值,如果定时器的值不为0,则开火请求无效,流程如下: 第 14 页 共 26 页 图 6 飞机开火冷却流程 同时,由于假定飞机只能向前运动,而不能向后运动,所以飞机的朝向向 量也就必须和它的速度向量一致,在前面已经介绍过,在设定object类中设定 了物体的速度为矢量,这样就可以把飞机的朝向向量与其速度矢量取一致了 if (getvelocity()-length()/ 如果物体
33、有速度,那么物体的朝向 向量就根据他的速度来进行调整 mfacedirection.scale(0); mfacedirection.add (getvelocity(); mfacedirection.normalize (); object:update(); 此外还有一个问题,那就是本游戏假定的是所有飞机都只能向前方发射子 弹,所以在发射子弹的实现中,就必须把子弹的方向与飞机所面对的方向取一 致,同样的,也只需要把子弹的方向与飞机的速度方向取一致就可以了 void plane:fire () bullet* b = mbf-create (getbullettype(), getteam
34、(); if (b=0) return; b-setpos (getpos (); b-setdirection (/将子弹的方向与飞机面 朝的方向取一致 第 15 页 共 26 页 mlevel-add (b); 4 43 34 4 playerplayer 类的实现类的实现 player 类主要实现了玩家的一些方法,它继承了飞机类的所有参数和方法, 玩家和敌机除了操作不一样以外,其余的属性基本一致,比如说,玩家一样有 开火的冷却时间,另外,为了和所有已有的飞行游戏接轨,需要将玩家刚诞生 时的一段时间设为无敌时间,即在这段时间内,所有敌机的攻击都对玩家无效, 而且,照以往飞行游戏的惯例,在这
35、段无敌时间内,玩家是在不停闪烁的,为 此,我们设定为其无敌时间为 100,再取名一个为 matchlesstimer 的定时器, 让其不停自减,当减为 0 时,无敌效果取消,那么,如何实现玩家的闪烁呢? 其实所谓“闪烁”,意思就是其可视性在不停地变化,在这 100 时间内,不停 地对其视图可视性取非运算,以实现其闪烁的效果,当无敌时间耗尽时,只需 要干两件事:第一,取消玩家无敌状态,通过设置玩家 collidable 属性为真实 现;第二,取消玩家的闪烁,通过设置玩家 visible 属性为真实现。 关于玩家的控制,将在后面的重要问题中说明。 4 43 35 5 enemyenemy 类的实现
36、类的实现 enemy 类主要实现的功能是设定敌机的生命值,设定掉落奖子类型,其他 一些行为全部由父类 plane 继承而来,但是对于 update 这个方法,enemy 类进 行了重写,目的就是为了实现在不同时间敌机采用不同的攻击策略来攻击玩家, 我们现在设定敌机每 5 个周期就执行一次攻击策略,那么如何实现敌机每 5 个 周期就更新一次其攻击策略呢?这同样需要设置一个定时器 updateaitimer 来 实现,首先设置 updateaitimer 的初值为 0,然后对它进行自加,同时对 updateaitimer 的值进行检查,当它的值为 5 的倍数时,敌机的攻击策略就进 行更新,再进一步
37、,如何判断 updateaitimer 的值是否为 5 的倍数呢?当然通 过把 updateaitimer 的值对 5 取余,当得到的值等于 0 时,updateaitimer 的 值即为 5 的倍数,敌机的攻击策略也就进行相应的更新。 那敌机的攻击策略由谁负责管理?所有敌机的攻击策略都是由 ai 指针管理, 在关卡刚创建时,ai 指针指向的是 defaultai,这时敌机的攻击策略是不作出 任何动,作在敌机执行 defaultai 时,他会调用 level 中的 getnumcompanies 方法,当返回值小于最小友军数目时,它便会调用 level 中的 getnearestenemy 方
38、法,它的目的是寻找是否有玩家,若玩家已被击毁,则执 行 defaultai,停止任何动作,如果玩家仍然存在,那么就把玩家的坐标取出, 第 16 页 共 26 页 与自己的坐标相减,算出距离,若 距离小于最小距离mmindist,则 实施随机开火策略, 开火几率是 1%到100%之间的一 个随机数,流程如下: 图7 敌机攻击策略更新流程 那么,如何保证开火几率为0%至100%之间的一个随机数呢?这就要通过一 个随机数rnd来实现,把它的值设为rand()%100,这样就保证rnd总是小于100了。 第 17 页 共 26 页 4 43 36 6 bulletbullet 类的实现类的实现 bul
39、let 类主要实现的就是子弹的创造了销毁,以及设定子弹与飞机的碰撞, 它也是 object 类的子类,继承了 object 类的所有属性和方法,其中,子弹都 是由子弹工厂 bulletfct 创造的,也是由其销毁的,子弹共有 3 种,同前面介 绍的一样,为了方便,可以定义一个枚举类型来描述它 typedef enum bullettype bt_normal, bt_double, bt_three, ; 接下来,就要创建子弹, 但是由于 bulletfct 不 知道是要创建哪种子弹,所以 在创建子弹的时候,需要一条 switch 语句来判断所要创建子 弹的类型,共有3 种子弹类型, 所以 s
40、witch 语 句就应该有 3 种case,分别对 每一种子弹进行相应的视图创 建。 在这里有一个问题,那就 是bulletfct一次性地创建了 200个子弹,如果不对其进行回收,这就势必会大大增加了系统的开销,导致运 行速度的缓慢,如何解决着一问题呢?可以创建一个“池子”,创建的所有子 弹都先放入这个池子中,当飞机开火需要子弹时,再从池中取出子弹供其使用, 同理,当关卡中有不用的子弹时,也放入池中以供以后使用,这样就大大增强 了资源的重利用,也节省了许多不必要的系统开销,这个表的主要思想是:存 放一群物体。根据物体的使用情况,存放到两个表内。一个表存放所有物体, 另外一个表存放无效的物体。当
41、用户需要物体时,从无效的物体表内取给用户。 当用户用完后回收时,存放这个物体到无效物体表内以供下次使用,流程如下: 第 18 页 共 26 页 图8 子弹调用和回收流程 在本游戏中,所有的子弹只能是直线向上或者向下运动,所以它的更新方 法比较简单,只需要先判定子弹是否诞生,如果诞生的话,就取出它的坐标以 及它的速度向量,然后以其速度向量为方向对其坐标作加。 4 43 37 7 prizeprize 类的实现类的实现 prize 类和 bullet 类似,也是 object 类的子类,它的主要功能是实现奖 子的创建和销毁,以及设定和玩家的碰撞行为,奖子一共有 3 种,但是我们把 没有奖子也算成一
42、种,所以共有 4 种奖子,同样用一个枚举类型来定义它 typedef enum prizetype bt_no,/没有奖子 bt_life,/增加玩家生命的奖子 bt_three_bullet,/子弹变为三发的奖子 bt_score,/增加玩家得分的奖子 ; 奖子都是由prizefct创建的,3种不同的奖子的创建方法是不同的,所以, 也需要一条switch语句来分别实现4种(其实只有3种,因为没有奖子是不需要 创建任何东西的)不同奖子的创建。 在本游戏中,子弹的更新方法只是与子弹类似,也同样是取出它的坐标以 及它的速度向量,然后以其速度向量为方向对其坐标作加。 第 19 页 共 26 页 那么
43、奖子如何实现改变玩家的相关属性的呢?为了实现不同奖子改变玩家 不同属性,我们又用 prize 类派生出 3 个子类:addlifeprize 类, changebulletprize 类和 scoreprize 类,分别用来实现增加玩家生命值,改变 玩家子弹和增加玩家得分,以 addlifeprize 类举例,它增加玩家的生命就通 过调用 level 类中的 addplayerlife 函数实现 void addlifeprize:changeattribute(player *p)/增加玩家生命的实现 mlevel-addplayerlife (); 同样,changebulletprize
44、 类改变玩家子弹通过调用 player 类中的 setbullettype 函数来实现 void changebulletprize:changeattribute (player* p)/改变玩家子弹 类型的实现 p-setbullettype (mtype); scoreprize 类增加玩家得分通过调用 level 类中的 addscore 来实现 void scoreprize:changeattribute(player *p)/增加玩家得分 mlevel-addscore (mscore); 5 5程序设计过程中遇到的一些重要问题程序设计过程中遇到的一些重要问题 5.15.1 关于
45、碰撞的问题关于碰撞的问题 碰撞检测问题是本程序的难点和重点,也是所有飞行射击游戏的难点和重 点,所谓碰撞检测,就是指检测在某一时刻是否有 2 个或者以上的碰撞矩形相 交。那么我们首先要做的就是设定一个物体的碰撞矩形,具体做法为,在 planeview 中以此物体视图的中心为点,上,下,各取视图高度的一半,左, 右各取视图宽度的一半,然后调用 object 类中的 setcollshape 方法来设定其 碰撞矩形 void planeview:changeshape (object *obj) float w = m_plane-getw(), h = m_plane-geth (); obj-
46、setcollshape ( 第 20 页 共 26 页 虽然给物体的碰撞矩形设定完毕了,但是我们设想一下,当物体开始移动 时,也就是视图开始移动,但是它的碰撞矩形却还留在原地,这显然会造成碰 撞检测不能正确地完成,如何解决呢? virtual void update(void) mnewshape = mcollshape; mnewshape.translate (/将碰撞矩形移动到物体的当前坐标 上 ; 接下来,我们所要做的就是进行碰撞检测,这个方法是由 level 类实现的, 先从一个物体 a 开始,若 a 被设定为不能碰撞,则继续从下一个物体开始,若 a 能发生碰撞,则又判断是否有物
47、体 b 的碰撞矩形和其相交,若有,则判断 a 和 b 是否属于同一队伍以及物体 b 是否为不能碰撞,若其中有一为真,则不进 行任何处理,否则就调用 object 类中的 oncollide 方法实现碰撞,流程如下: 第 21 页 共 26 页 图 9 物体实现碰撞流程 而 object 类中的 oncollide 方法很简单,就是令发生碰撞的物体消失 void object:oncollide(object* obj) disappear ();/令物体消失 而 disappear 方法又调用 level 类中的 processdie 方法,processdie 方 法在之前已经清楚地利用流程
48、图进行了表示。至此,玩家与敌机的碰撞就完美 解决了,但是子弹与玩家,子弹与敌机,奖子和玩家之间的碰撞还没有实现, 为了实现子弹与玩家和子弹与敌机之间的碰撞,在 bullet 类中重写 object 类 中的 oncollide 方法,因为各个子弹之间和子弹与奖子之间是不能发生碰撞的, 所以,还必须先对与子弹的碰撞矩形相交的物体进行检测 void bullet:oncollide (object* obj) int id = obj-getruntimeclassid(); if (id=prize:classid | id=bullet:classid) /子弹与奖子,子弹之间不能发生碰撞 e
49、lse /子弹与玩家和敌机碰撞的实现 explosion* ep = mef-create (explfct:et_small); if (ep) ep-setpos (getpos(); mlevel-add (ep); 第 22 页 共 26 页 object:oncollide (obj); 最后,便是奖子与玩家碰撞的实现,同样,在 prize 类中也重写 object 类中的 oncollide 方法,因为奖子和子弹以及敌机是不能发生碰撞的,所以我 们也必须对与奖子的碰撞矩形相交的物体进行检测 void prize:oncollide (object* obj) int id = ob
50、j-getruntimeclassid(); if (id=bullet:classid | id=enemy:classid) /奖子不能与敌机和子弹发生碰撞 else object:oncollide (obj); /奖子可以与玩家发生碰撞 mbeeaten = true; 5.25.2 关于游戏画面的问题关于游戏画面的问题 由于我之前对于游戏编程只是一个初步认识,所以完全没有接触过关于图 像渲染及其他方面的知识,所以之前这个方面我感到无能为力,所以我只有使 用了同学给我提供的整个游戏框架,在这个框架中,所有的关于图像资源的初 始化,渲染和摧毁都已完成,而且实现这些功能的开发包 alleg
51、,dev,io 对外都 是不透明的,所以无法看到其内部的方法,但是我还是通过这几个包实现了游 戏背景的显示,背景主要就是表现一些星星不停地闪烁,这主要是通过 background 类实现的。 首先把星星放入关卡中,因为放置星星的区域不能超过关卡的区域,所以 要设定放置星星的区域的宽度为关卡坐标 x2-x1,高度设为关卡坐标 y2-y1,同 理,星星的位置也不能超过放置星星的区域,所以令星星的 x 坐标和 y 坐标分 别取放置星星区域的宽和高的一个随机值,通过如下语句来实现 s-pos.x = rand () % w; 第 23 页 共 26 页 s-pos.y = rand () % h; 为
52、了让星星闪烁,就必须让其每隔一段时间更新一次,现在设定每 30 个周 期更新一次,这只需要判断时间是否为 30 的倍数即可(s-delay = rand () % 30)另外,要实现闪烁,就要有颜色的变化,那么如何实现颜色的变化呢?dev 包中有一个方法 color,只要赋给其一定的值,便能显示出一定的颜色,颜色 左端点的值为 col1,右端点的值为 col2,当前颜色为 col,开始时设定 col=col1。 接下来的工作就是令星星开始闪烁,闪烁是通过定时器timer实现的,其基 本思想是:对每一个星星都设置一个定时器timer,把其初值设为0,对它进行 自加,然后随时对其进行检测,如果它的
53、值大于delay,则把它复位为0,如果 它的值小于delay,则计算其占delay的比例(float sc = (float)s-timer / s-delay),然后根据比例对两个颜色端点进行线形插值计算当前颜色(color 方法规定颜色有3个分量,所以颜色的每个分量都要计算),最后根据计算出的 新颜色并更新星星的当前颜色,流程如下: 第 24 页 共 26 页 图 10 星星颜色变化流程 到这里,我们的工作似乎结束了,但是运行游戏会发现背景并没有星星的 显示,为什么呢?这是因为我们定义的一个星星只是一个像素点,对于我们人 的肉眼来说是很小的,我们自然看不见,所以只有把其放大成为一个矩形,这
54、 样我们就能够看见了 int rg = 1; for (int i=0; irectfill (s-pos.x-rg, s-pos.y-rg, s-pos.x+rg, s- pos.y+rg, dev:color(s-col); 5.35.3 关于玩家控制的问题关于玩家控制的问题 玩家的控制是由 dev 包中的 keyboard 类实现的,由于其不透明,所以只能 说明如何实现,首先要设定玩家的控制键位 player:player(level* l, view* v, explfct* ex, bulletfct* bf, dev:keyboard *kb): plane (l, v, ex,
55、bf) mkb = kb; mkeyup = key:w;/按住w键则向上 mkeydown = key:s;/按住s键则向下 mkeyleft = key:a;/按住a键则向左 mkeyright = key:d;/按住d键则向右 mkeyfire = key:space;/按住space键则向开火 设定完毕后就是具体实现,由于共有5个控制键,所以需要用判断语句来实 现分别按住5个不同的键实现5个具体的功能,所要实现的具体功能就是:按住w 键,则玩家y坐标减();按住s键,则玩家y坐标加;按住a键,则玩家x坐标减; 按住d键,则玩家x坐标加;按住space键,则玩家实现开火。 其中,玩家开火
56、的实现调用了plane类中的requestfire方法 if (mkb-getkeystate (mkeyfire) 第 25 页 共 26 页 requestfire (); /space键将调用plane类中的requestfire方法 结结 论论 通过本次课题的研究,在 vc 平台上得到了一个可运行的飞行射击游戏,在 编程中很好地使用了继承技术,提高了代码的重用率,同时也成功地在父类中 引入了虚函数,使得指针能够成功地指向子类中与父类同名的成员,从而实现 多态,而且虽然游戏比较简单,但是游戏中没有可令程序崩溃的 bug,另外游 戏上手简单,但是游戏中也存在以下问题: 1level 类的代
57、码过于复杂; 2在游戏中没有实现反弹型子弹; 3在游戏中没有实现多关卡制度。 参考文献参考文献 1 郑莉,董渊. c+语言程序设计m.北京:清华大学出版社,2004。 2 黄维通. visual c+面向对象与可视化程序设计m.北京:清华大学出版社,2004。 3 丁展. visual c+游戏开发技术与实例m.北京:人民邮电出版社,2005。 4 荣钦科技. visual c+游戏设计m.北京:北京科海电子出版社,2005。 5 荣钦科技.visual c+游戏编程基础m.北京:北京科海电子出版社,2005。 6 唐明理. 传奇的故事-学 vc 编游戏m.北京:机械工业出版社,2004。 7
58、 andre lamothe美. windows 游戏编程大师技巧m.北京:机械工业出版社,2004。 致致 谢谢 本文是在金虎老师的热情关心和指导下完成的,他渊博的知识和严谨的治 学作风使我受益匪浅,对顺利完成本设计起到了极大的作用。在此向他表示我 最衷心的感谢! 感谢李凇同学在整个编程过程中给予的帮助,在李凇同学的帮助下编码才 得以继续,同时也是在他的帮助下得以完成图像方面的工作 在论文完成过程中,本人还得到了其他老师和许多同学的热心帮助,本人 向他们表示深深的谢意! 最后向在百忙之中评审本文的各位专家、老师表示衷心的感谢! 第 26 页 共 26 页 作者简介 姓 名:林丹 性别:男 出
59、生年月:1985 年 8 月 14 日 民族:汉 e-mail: 第 27 页 共 26 页 声声 明明 本论文的工作是 2007 年 2 月至 2007 年 6 月在成都信息工程学院网络工程 系完成的。文中除了特别加以标注地方外,不包含他人已经发表或撰写过的研 究成果,也不包含为获得成都信息工程学院或其他教学机构的学位或证书而使 用过的材料。除非另有说明,本文的工作是原始性工作。 关于学位论文使用权和研究成果知识产权的说明: 本人完全了解成都信息工程学院有关保管使用学位论文的规定,其中包括: (1)学校有权保管并向有关部门递交学位论文的原件与复印件。 (2)学校可以采用影印、缩印或其他复制方
60、式保存学位论文。 (3)学校可以学术交流为目的复制、赠送和交换学位论文。 (4)学校可允许学位论文被查阅或借阅。 (5)学校可以公布学位论文的全部或部分内容(保密学位论文在解密后 遵守此规定)。 除非另有科研合同和其他法律文书的制约,本论文的科研成果属于成都信息 工程学院。 特此声明! 作者签名: 2007 年 06 月 日 第 28 页 共 26 页 t was not until mid-afternoon that the inspector ambled up on his pony. my father pulled himself together, and went out to
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 装修工程劳务合同样本简版
- 公司生产合同标准文本
- 临时用工安全合同标准文本
- bt 回购协议 合同范例
- 公司质权合同范例
- 企业市场咨询服务合同范例
- 中介装修验收合同范例
- 与狗合作合同标准文本
- 交通保险合同范例
- 店铺租赁合同范本
- 药店托管合同协议书
- 2025年中国医药市场分析:规模突破4万亿元 基因药物增速领跑行业
- 2024-2025学年人教版七下地理第一单元测验卷
- 2025年上半年江苏南通醋酸纤维限公司招聘20人易考易错模拟试题(共500题)试卷后附参考答案
- 更换绝缘子施工方案
- 玉盘二部合唱简谱
- 日本2 课件-2024-2025学年人教版地理七年级下册
- 2025年《圆的认识》标准课件标准课件
- 2025年陕西延安四大国林管理局历年高频重点模拟试卷提升(共500题附带答案详解)
- 2025年徽商职业学院单招职业适应性测试题库一套
- 2025年河南应用技术职业学院单招职业技能测试题库完美版
评论
0/150
提交评论