雷 霆 战 机 By—谷恩轩&余万全
游戏简介 游戏的总体分析 目录 链表和文件储存的使用 后期的游戏优化
游 戏 简 介
游 戏 开 始 界 面
游 戏 界 面
1 ,背景故事 以AD2090地球殖民地为背景,与从宇宙来了的未知侵略部队作战,地球方面的最先进机“雷霆”投入战斗。从这场战争中俘虏了侵略部队的一些士兵,从而得知他们曾经也征服过其它行星。并且发现了绿色的行星地球。他们将地球最先进的“雷霆”称为“恶梦”。他们将使用更高性能战斗机部队来作战。
1. 素材选取:首选“太空战机”的人物、地图图片,经过PS等软件的处理后,分别做成我们所需的人物动画、地图背景以及游戏的道路等等。 2 ,作品创意 1. 素材选取:首选“太空战机”的人物、地图图片,经过PS等软件的处理后,分别做成我们所需的人物动画、地图背景以及游戏的道路等等。 2. 游戏速度变化:游戏进行到一半时,游戏速度会进行一次加速,同时难度会增加,敌方战机的生命值也增大。 3. 代码原创:游戏的代码90%以上是原创,没有借鉴任何word文档以及网上资源。 4. 背景滚动:滚动图之间没有间隙,同时图片有一定的滚动速度,从而给玩家一身临其境的体验。
3,功能设计 1. 游戏运行,初试界面会出现‘空格开始’的提示,并且游戏的主角---我方战机会出现在界面。 2. 玩家单击space键开始游戏。 3. 游戏开始后,玩家每按一次空格键,我方战机会发射子弹攻击敌方战机。 4. 游戏中,玩家控制的战机如果碰到敌方战机,则会减少一定生命值,并且增加一定的分数。如果碰到炮弹则会减去一定生命值并且增加一定的分数。 5. 游戏进行到一半时,敌方战机移动速度和子弹飞行速度会变快,从而增加游戏难度。
4,功能实现 数据结构 int g_iGameState float g_fGameTime float g_fDifficulControl int g_iMaxScore int g_iCreatedSpriteCount float g_fWorldLeft float g_fWorldRight
float g_fWorldTop float g_fWorldBottom float g_fVelocityLeft float g_fVelocityRight float g_fVelocityTop float g_fVelocityBottom bool g_bControlCanFire float g_fBossCreateTime float g_fRotateCreateTime float g_fHorCreateTime float g_fVerCreateTime float g_fHealthCreateTime
5,关键问题 1,游戏中途难度如何加大 答:当此变量到达路总数一半时,出现背景滚动加快的效果,同时速度增加。游戏难度增加。 2,人物动画制作 答:我们的动画先用photoshop裁剪,然后根据标尺,精确定位。然后计算图片制作时所需要减去的宽度,制作一张包含各帧的图片,最后进行制作动画。
游戏的总体分析
1. 采用太空战机类型,画面没用过于炫酷的界面,给玩家一种舒适的游戏体验过程。 2. 采用五键式操作,操作简单。此作品由于时间短,工作量大,我们只做了游戏的一个简略版,并想在以后进行完善。 3. 道路随机产生,每次游戏随机生成地图,路精灵之间的距离每次都是随机产生。 4. 敌方战机生命值和移动速度改变,当boss出现时,子弹速度速度变慢。
链表和文件储存的使用
链表的使用 1,为了便于对战机和子弹的管理,我们使用结构体来将战机和子弹的变量存放在一起。战机和子弹的管理我们都放在链表中进行管理,并且将这两个文件添加到工程当中;接着我们用宏定义定义一些极限值;之后我们用枚举类型列出本游戏需要用的几种类型;最后完成了一个结构体
2,对游戏中的精灵进行链表管理 精灵是个体,我们将这些个体联系在一起便于管理; 我们可以根据链表由名字获得精灵,遍历精灵链表,添加精灵到链表, 从而可以根据名字删除链表,删除所有精灵; 具体用到的函数如下:
extern int GList_GetListSize(); // 根据名字获取Sprite extern SGameSprite *GList_GetSpriteByName( const char *szName ); // 根据索引获取Sprite,如果要遍历链表并删除其中的某个元素,请从后面往前面遍历(即索引初始化为链表大小然后递减),否则必然出错 extern SGameSprite *GList_GetSpriteByIndex( const int iIndex ); // 添加一个Sprite到链表里 extern SpriteStruct *GList_AddSprite( SGameSprite *pSprite ); // 根据名字删除Sprite. bDeleteImage : 是否删除该Sprite在地图上的图片显示
extern void. GList_DeleteSprite( const char extern void GList_DeleteSprite( const char *szName, bool bDeleteImage = true ); // 根据指针删除Sprite. bDeleteImage : 是否删除该Sprite在地图上的图片显示 extern void GList_DeleteSprite( SGameSprite *pSprite, bool bDeleteImage = true ); // 删除所有Sprite. bDeleteImage : 是否删除该Sprite在地图上的图片显示 extern void GList_DeleteAllSprite( bool bDeleteImage = true );
文件储存的使用 游戏最佳表现的记录:我们使用文件将最高分写入到文件当中,每局打完之后可以将现在的分数和文件中的分数比较,如果本局中的分数比最高分数要高,那么就更新最高分数,如果不如原来的最高分数高,就保持原来的最高分数。
因为最高分要与本局最后的分数进行比较,所以一下代码要加到GameEnd中,添加代码如下: if( g_iMaxScore < g_ControlSprite.iScore ) { g_iMaxScore = g_ControlSprite.iScore; // 写文件 FILE *pfp = fopen( "Score.dat", "wb" ); if( NULL != pfp ) fwrite( &g_iMaxScore, sizeof(g_iMaxScore), 1, pfp ); fclose( pfp ); } // [End Your Code] //更新最大积分 dSetTextValue( "MaxScoreText", g_iMaxScore );
这样编译之后,能够保存本局的最高分,如何去保存以前的最高分呢,我们在GameInit中添加代码 static int iInited = 0; if( !iInited ) { // 从文件里读取历史最高积分 // 本案例只记录单一积分值,有兴趣的话,可以做多个积分的排名然后 // 进行存储与读取 // 后面游戏结束那里,文件的存储将作为教学任务 FILE *pfp = fopen( "Score.dat", "rb" ); if( NULL != pfp ) fread( &g_iMaxScore, sizeof(g_iMaxScore), 1, pfp ); fclose( pfp ); //更新最大积分 dSetTextValue( "MaxScoreText", g_iMaxScore ); } 然后编译运行就可以看到游戏可以记录最高分数,并且每次开始游戏,都会显示以前游戏的最高分数。
后期的游戏优化
为了我们程序实现的简便,我们使用了枚举数据类型。 但是发现每次编译的时候都会提示warning
另外,后期测试游戏的时候,我们发现在开始游戏一段时间之后游戏会出现卡顿现象,后来请教老师后发现是因为游戏开始一段时间后,游戏界面外的精灵太多,导致游戏运行内存不够,最后我们通过判断敌方战机和子弹是否碰撞到了世界边界,碰到世界边界,就将其删除,最后游戏比原来就流畅了许多
感谢各位的倾听 Thank you for listening