生活随笔
收集整理的这篇文章主要介绍了
小游戏“终结者”程序的设计与实现
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活。此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/details/7747205
面向对象程序设计
这是我们学习程序设计的第一课。我也在这门课上第一次接触程语言、写代码。我们以影印版的《C++ Program Design : An Introduction to Programming and Object-Oriented Design 》为教材。
现在想来那段“入门”的经历真是痛苦不堪,很多概念难以理解,就只能一点点把书中的代码一遍遍的敲。但每次跑出一点小东西也都觉着兴奋到不行。大一末的时候有个“大”的课程设计:两人一组编写一个小游戏。我和小琦一组,写了一个比较简略的闯关游戏,这次经历之后才真的对编程有了“入门”的感觉。
小游戏"YingMu"
【游戏功能需求说明】
本游戏是基于日本漫画《灌篮高手》而设计的,相信大家对游戏中的人物都相当熟悉。在游戏中我们采用了键盘上、下、左、右控制玩家的移动,空格键发射子弹。如果玩家碰到敌人,则游戏结束;消灭所有敌人,则通关。游戏共分为两关,每一关的地图是随机产生的,敌人的移动速度也逐渐加快。虽然功能看似简单,但其中乐趣无穷,是一款集娱乐、冒险为一体的游戏。
我们这次是在Microsoft Visual C++ 6.0, EzWindow library的开发环境下设计完成的,一些程序的功能我们一时没有想到好的方法来实现,所以在这款游戏中没有呈现给大家。相信在以后的学习中,我们能更好地掌握并对这款小游戏进行升级更新。
【游戏总类图】
【游戏中的关键类】
Player
[cpp] view plaincopy
enum Floor{FLoor1=0,Floor2,Floor3,Floor4}; class Player { public: Player(SimpleWindow &w); public: SimpleWindow& GetWindow() const; Position GetPosition() const; Direction GetDirection() const; BitMap& GetBmp(const Direction &d,int i); const BitMap& GetBmp(const Direction &d,int i) const; Floor GetFloor()const; bool IsDying(); bool AtRightEdge() const; bool AtLeftEdge() const; void Create(); void Kill(); void Move(); void Fire(); void OKUp(); void OKDown(); void CannotUpDown(); void SetPosition(const Position &p); void SetFloor(Floor &f); void SetDirection(const Direction &d); vector<Bullet*> bullets; private: void Draw(); void Erase(); SimpleWindow &Window; vector<vector<BitMap> > Bmp; Direction CurrentDirection; Position CurrentPosition; bool bUpOk; bool bDownOk; Floor CurrentFloor; int Steps; }; Enemy 和 Bullet
[cpp] view plaincopy
#ifndef ENEMY_H #define ENEMY_H const int EnemyBitMaps=2; enum EnemyStatus {Alive,Dead,DeadAlready}; class Enemy{ public: Enemy(SimpleWindow &W,const Position &p1=(0,0),const Position &p2=(0,0),double h=1 ); public: SimpleWindow& GetWindow() const; Position GetPosition() const; Direction GetDirection() const; double GetHorizMovement() const; BitMap &GetBmp(const Direction &d); const BitMap &GetBmp(const Direction &d) const; EnemyStatus GetStatus()const; void SetWindow(SimpleWindow &W); void SetDirection(const Direction &d); void SetPosition(const Position &p); void SetStatus(EnemyStatus s); void SetHorizMovement(double h); void SetP1P2(const Position &pp1,const Position &pp2); void Create(); void Kill(); void Move(); void Draw(); void Erase(); Position NewPosition() const; void ChangeDirection(); private: SimpleWindow& Window; vector<BitMap> Bmp; double HorizMovement; Direction CurrentDirection; Position CurrentPosition; Position P1,P2; EnemyStatus CurrenStatus; }; #endif #ifndef ENEMY_1_H #define ENEMY_1_H #include "enemy.h" class Enemy_1 : public Enemy{ public: Enemy_1(SimpleWindow &W,const Position &p1=(0,0), const Position &p2=(0,0) ,double h=0.5); }; #endif #ifndef ENEMY_2_H #define ENEMY_2_H #include"enemy.h" class Enemy_2 : public Enemy{ public: Enemy_2(SimpleWindow &W, const Position &p1=(0,0), const Position &p2=(0,0),double h=0.8 ); }; #endif #ifndef BULLET_H #define BULLET_H #include "enemy.h" class Bullet : public Enemy{ public : Bullet(SimpleWindow &W,Direction d , const Position &p1=(0,0), const Position &p2=(0,0)); bool AtRightEdge() const; bool AtLeftEdge() const; void B_Creat(); }; #endif GameController
[cpp] view plaincopy
#ifndef GAMECONTROL_H #define GAMECONTROL_H enum GameLevel { One, Second, Done }; class GameController { public: GameController(const string &Title = "终结者(樱木花道版)", const Position &WinPosition=Position(2.0,2.0), const float WinLength =16, const float WinHeight = 13); ~GameController(); SimpleWindow *GetWindow(); GameLevel CurrentLevel() const; void Play(const GameLevel Level); void TestGap(Player* player,vector<Gap*> gap); void TestBullet(vector<Enemy_1*> e,vector<Bullet*> b); void TestBullet(vector<Enemy_2*> e,vector<Bullet*> b); bool TestPlayer(Player* player,vector<Enemy_1*> e); bool TestPlayer(Player* player,vector<Enemy_2*> e); int TimerTick(); private: SimpleWindow *GameWindow; GameLevel Level; Player *player; vector<Gap*> gaps; vector<Layer*> layers; vector<Enemy_1*> enemy1; vector<Enemy_2*> enemy2; }; #endif 全局的类:Global 和 Welcome
[cpp] view plaincopy
#ifndef WEL_H #define WEL_H SimpleWindow End("终结者(樱木花道版)",15.0,12.0,Position(2.0,2.0)); BitMap WellDone(End); BitMap Quit(End); BitMap Fail(End); void SetWindows(){ Fail.Load("bmp\\fail.bmp"); assert(Fail.GetStatus()==BitMapOkay); WellDone.Load("bmp\\done.bmp"); assert(WellDone.GetStatus()==BitMapOkay); double width=Fail.GetWidth(); double height=Fail.GetHeight(); Quit.Load("bmp\\quit.bmp"); Quit.SetPosition(Position(0.6*width,0.8*height)); assert(Quit.GetStatus()==BitMapOkay); } int MouseClickEnd(const Position& MousePosition){ if(Quit.IsInside(MousePosition)){ End.Close(); } return 1; } #endif welcome.h
[cpp] view plaincopy
#ifndef WELCOME_H #define WELCOME_H #include "assert.h" SimpleWindow Welcome("终结者(樱木花道版)",15.0,12.0,Position(2.0,2.0)); BitMap PlayButton(Welcome); BitMap InstructionButton(Welcome); BitMap Instruction(Welcome); void SetWelcomeWindows(){ BitMap WelcomeBmp(Welcome); WelcomeBmp.SetPosition(Position(0,0)); WelcomeBmp.Load("bmp\\hello.bmp"); WelcomeBmp.Draw(); assert(WelcomeBmp.GetStatus()==BitMapOkay); double width=WelcomeBmp.GetWidth(); double height=WelcomeBmp.GetHeight(); PlayButton.SetPosition(Position(0.1*width,0.85*height)); PlayButton.Load("bmp\\play.bmp"); assert(PlayButton.GetStatus()==BitMapOkay); Instruction.SetPosition(Position(0,0)); Instruction.Load("bmp\\in.bmp"); assert(Instruction.GetStatus()==BitMapOkay); InstructionButton.SetPosition(Position(0.1*width,0.35*height)); InstructionButton.Load("bmp\\inbutton.bmp"); assert(InstructionButton.GetStatus()==BitMapOkay); InstructionButton.Draw(); } #endif 【游戏控制逻辑框图】
【游戏说明】
本游戏无需安装。打开文件夹“YingMu”,双击“YingMu.exe”可直接开始游戏。
打开会出现游戏的进入窗口——显示有灌篮高手剧照图,单击窗口中的“Instruction”图标可以看到具体的游戏操作说明,之后单击“Play”图标即可开始游戏。
游戏开始后,玩家可以看到左下角的樱木花道以及三个在窗口中不停移动的敌人,玩家以键盘的左右键控制樱木花道在窗口中移动,当走到篮筐下时,可以有上下键控制实现层的跳跃。游戏中,玩家按空格键发射子弹(子弹的数目没有限制),子弹遇到敌人即可消灭敌人。当消灭玩所有的敌人,游戏会弹出对话框提示玩家进入下一关。第二关所有敌人被消灭后,游戏胜利。玩家会看到恭喜的窗口,单击左下角的“Quit”图标即可退出游戏。如果游戏中,玩家不小心被敌人捉到,游戏失败,会出现提示游戏失败的界面,单击“Quit”图标退出游戏。
【游戏截图】
【项目总结】
通过大一的C++语言学习后,我们小组完成了第一个项目编程—终结者(樱木花道版)。
接到任务,我们迅速开始……
我们首先上网查阅了相关资料,并下载了一些相关的小游戏进行试玩,揣摩游戏的设计架构及功能实现,汲取别人的长处。接着我们进行课程设计“终结者”的构思,我们最初的设计是界面分为几层,玩家可以在每一层上走动,通过方向键左右移动,遇到楼梯可以上下爬动,空格键发射子弹,并设有各种不同的食物,玩家控制小人走过去“吃”,不同的食物增加或减少相对应的属性(如:生命值、速度等)。然而在真正动手的时候,才发现敲代码远远不像读代码那么简单。我们分工合作,两个人分别编写不同的类,几乎是白手起家,决定和实现每个类有怎样的功能显得异常的生疏和困难,尤其在派生的时候才发现总结出对象必要的属性、行为是多么重要。而这只是困难的开始,当我们把零零散散的代码拼在一起时,终于见识到所谓的“面向对象”并没有我们想象的那么简单。虽然都认真的开了书中的BugHunt程序,可实际上我们很多地方并没有理解到位,尤其是GameController的重要——把一个个孤立的对象联系起来,可以相互“交流”的才是真正“活”的对象,才组成了生动的游戏。我们熬了几个通宵,重写了很多次,删减了许多一开始野心勃勃想要实现的内容,于是有了想在这个终结者的雏形。
之后的时间是我们一起小心翼翼的在游戏中添加一些功能,比如发射子弹,樱木的“走动”效果,以及图片的处理等等……游戏进入和退去的界面也是在这个时期完成的。
在游戏最终出品前期,我们在实验室进行试玩,却发现一个问题:不同的屏幕和分辨率造成了窗口及图片坐标的偏移,我们最初是在自己的电脑上设定的坐标,因为偷懒而直接使用的数字——迅速显出弊端,而在实验室的电脑上,图片甚至发生了重叠。我们随即想到的是把游戏做成两个版本(标屏和宽屏),但后来我们又发现分辨率也会对坐标产生影响,所以两个版本的计划无法实施。我们也去请教了别人查阅了资料,最后用图片的大小来调整层之间的坐标(因为似乎不同的屏幕图片还是不变的),但问题也没有得到根本的解决,结果没有预期的好,这让我们尤其以为可以自慰的地方——游戏的整体美观度大打折扣,希望在以后的学习中能更好的解决该问题,进行游戏的升级与更新。
游戏问世,不是期望的样子……
现在再回头看我们自己编写的第一个游戏,即使抱着“敝帚自珍”的心态,依旧觉得她有那么多不尽人意的地方,毕竟最终的成果有点简单,和当初的设想差得太远,许多功能都没有实现——因为ezwin的功能有限,添加游戏背景甚至是在“梯子”上的走动,都有很明显的闪图,就改成了跳跃;死掉的子弹和敌人都被我们投机取巧的藏在游戏图中,没有真正的delete以释放内存;时间有限,也没有再去在界面中做“生命值”、“速度”等……应该是在开始进行程序架构时,我们就缺乏严谨的逻辑思考,想法太杂太乱,导致有些功能实现起来太过复杂,而使得程序显的臃肿且不利于阅读。
一月奋战,我们还是收获了很多……
这次课程设计中,我们深切的体会到调试的重要,很多问题都是在编译、连接中发现的,看着自己编写的程序一编译出现那么多的错误,信心肯定受到打击,但是通过一次次的修改,看着错误数量的减少,还是很有成就感的。总的来说,我们用于调试的时间远远多与编写代码的时间。
通过课程设计,我们不仅锻炼了自己的实践能力,更培养了团队合作能力。遇到问题时,大家一起互相讨论,一起请教别人,最终找到解决方法,我想这应该是最好的学习过程,在实践中提高自己,比看书的效率高太多了。同时我们也意识到书本上的那些知识对于编程是远远不够的,教科书只是介绍一些皮毛而已,它只是引导你入门而已。我们更多的是要主动的学习,一起做项目就是一种好的方法。
我们知道,我们差的太远太远,要走的路还很长很长……
这次我们小组出品的游戏——终结者(樱木花道版)虽然有些粗糙,功能也十分有限,但是做为这款游戏的整个框架与体系,它实现了我们利用面向对象思想设计游戏的初衷。而在编写以及后来的程序调试与排错的过程中也练习了我们使用C++语言的熟练度以及对常见问题解决的经验积累。更主要的是,他使我们深深地看到自己的差距——学习了一年,还没用过MFC;不能短时间内迅速掌握HGE;即便是参考别人的代码,还要一个字一个字的读……这个挺普通的程序也许是对我们贫乏知识的真实写照,但,这绝不是终点,我们会在今后的学习中努力提高自己的水平,努力创造出优秀的作品。
这是我们软件学习上的第一次试炼,也是我们大一面向对象程序设计学习的成果,相信我们每个人都将终生难忘……
转载请注明出处:http://blog.csdn.net/xiaowei_cqu/article/details/7747650
总结
以上是生活随笔为你收集整理的小游戏“终结者”程序的设计与实现的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。