课程设计任务书
设计题目:
学生姓名 | XXX | |||
课程名称 | 程序设计课程实训 | 专业班级 | XXX | |
地 点 | 起止时间 | |||
设计内容及要求 | 设计内容:flappy_bird游戏的实现 要求:
| |||
设计 参数 | 窗口大小480*640 游戏速率 2 画面更新率 16 鸟扑闪翅膀速率 80 管道宽度 260 | |||
进度 要求 | 系统分析:2021-6-15——2021-6-17 系统设计:2021-6-18——2021-6-19 系统实现:2021-6-20——2021-6-25 系统测试:2021-6-25——2021-6-27 答辩:2021-6-28 | |||
参考资料 | [1] 钱晓捷.汇编语言程序设计.电子工业出版社,2003. [2] 姜仲秋等主编,c语言程序设计,南京大学出版社,1998年1月 [3] 计算机二级教程 1996年10月 [4] c程序设计(第5版)谭浩强 2001年 | |||
其它 | 无 | |||
说明 | 这是一款简单又困难的游戏,游戏中玩家必须控制一只胖乎乎的小鸟,跨越由各种不同长度水管所组成的障碍。2014年2月份在100多个国家/地区的榜单一跃登顶,尽管没有精细的动画效果,没有有趣的游戏规则,没有众多的关卡,却突然大火了一把,下载量突破5000万次。在《FlappyBird》这款游戏中,玩家只需要用一根手指来操控,点击触摸屏幕,小鸟就会往上飞,不断的点击就会不断的往高处飞。放松手指,则会快速下降。所以玩家要控制小鸟一直向前飞行,然后注意躲避途中高低不平的管子 | |||
指导教师:丘处机
2012年 6 月 29 日
目录
1 设计内容、任务及具体要求
1.1设计内容
实验题目:flappy bird游戏
问题描述:
这是一款简单又困难的手机游戏,游戏中玩家必须控制一只胖乎乎的小鸟,跨越由各种不同长度水管所组成的障碍。上手容易,但是想通关可不简单。Flappy bird 于2013年5月在苹果App Store上线,2014年2月份在100多个国家/地区的榜单一跃登顶,尽管没有精细的动画效果,没有有趣的游戏规则,没有众多的关卡,却突然大火了一把,下载量突破5000万次。在《Flappy Bird》这款游戏中,玩家只需要用一根手指来操控,点击触摸屏幕,小鸟就会往上飞,不断的点击就会不断的往高处飞。放松手指,则会快速下降。所以玩家要控制小鸟一直向前飞行,然后注意躲避途中高低不平的管子。
1、在游戏开始后,点击屏幕,要记住是有间歇的点击屏幕,不要让小鸟掉下来。
2、尽量保持平和的心情,点的时候不要下手太重,尽量注视着小鸟。
3、游戏的得分是,小鸟安全穿过一个柱子且不撞上就是1分。当然撞上就直接挂掉,只有一条命。
1.2设计任务及具体要求
具体要求:
- 实现图片和音频资源的插入
- 通过图片的轮播实现画面的移动
- 通过刷新速率的调整,实现鸟扑闪翅膀的画面
- 通过随机数生成随机管道
- 通过文件的读取实现最高分的记录
- 实现碰撞检测
- 实现计分功能
2 概要设计
2.1该游戏的功能简介
玩家通过点击鼠标操纵小鸟飞过一系列随机生成的管道,每通过一个管道计分加一,实现最高记录的静态存储。
2.2 总体程序框图
2.3 各个模块之间的主要关系
Start(按钮按下开始游戏)后动态更新画面,随机生成管道,并进行碰撞检测,若无碰撞则游戏一直运行,并持续计分,当鸟碰撞管道或者地面,游戏停止,按钮弹出,再次按下按钮后初始化游戏,初始化速度,重复上述过程。
3 系统功能模块的具体设计
3.1各个模块的程序流程图及运行界面
图3.1-1 程序流程图
图3.1-2 程序运行界面图
3.2对关键代码加以分析说明
(1)绘制地面
for(int i = 0; i < groundSize; i++)
{
pos = (*v)[i];
painter.drawPixmap(pos,this->height() - height, ground);//绘制一个地面图像
// 改变坐标 移动起来
pos -= moveSpeed;
if(pos <= -ground.width()){
pos = (groundSize-1) * ground.width();
}
(*v)[i] = pos;
}
分析说明:绘制地面向左移动,营造鸟向右飞的效果,采用多个地面从右到左移动实现。
图3.2-1 地面图片
(2)绘制鸟扑闪翅膀
//绘制哪一个 (动画效果)
if(birdNo < birdNoMax/3){
bird = bird1;
}else if(birdNo < birdNoMax/3 * 2){
bird = bird2;
}else{
bird = bird3;
}
birdNo++;
if(birdNo > birdNoMax){
birdNo = 1;
分析说明:通过鸟的三张图片实现鸟扑闪翅膀动画(80ms更新一次)
图3.2-2像素鸟图片
(3)绘制背景图
ground=QPixmap( QCoreApplication::applicationDirPath().append("/res/ground.png")); // 使用绝对路径
分析说明:通过绝对路径打开图片
图3.2-3 背景图
(4)碰撞检测
(birdY >= this->height() - ground.height() - bird1.height())
//是否碰撞地面
//是否碰撞管道
birdX + bird1.width() > c->getX() && birdX < c->getX() + c->getPipeWidth()&& (birdY < c->getPiPe2Height() || birdY+bird1.height() > c->getY1())
说明分析:当像素鸟的x坐标值在管道的左右边界之间时,判断鸟的y坐标是否碰到上下管道
(5)管道随机生成
winHeight 窗口高度 h1 底下管道高度 x 位置横坐标 groundHeight 地面高度 parent
PipeChannel::PipeChannel(int winHeight,int h1, int x, int groundHeight, QObject *parent) : QObject(parent)
(*pipeChannels)[0] = new PipeChannel(height(), 100+l, width()+100, ground.height(), this);//窗口高度 底下管道高度 x位置横坐标 地面高度 objet parent
(*pipeChannels)[1] = new PipeChannel(height(), 150 +l, 2 * width() + l, ground.height(), this);
说明分析:存放管道的vector中只有两个管道,两个管道分别有着上下两部分,当管道向左移出窗口时,重新设置,从右边进入画面,通过rand()和clock()函数实现随机数的生成。
(6)管道的绘制
pipeImage=QImage( QCoreApplication::applicationDirPath().append("/res/pipe.png"));
imageMirror = pipeImage.mirrored(false, true);
pipe1 = QPixmap::fromImage(pipeImage);
pipe2 = QPixmap::fromImage(imageMirror);
int h2 = getPiPe2Height();
pipe1 = pipe1.copy(0, 0, pipe1.width(), h1);
pipe1 = pipe1.scaled(pipeWidth, h1);
pipe2 = pipe2.copy(0, pipe2.height()-h2, pipe2.width(), h2);
pipe2 = pipe2.scaled(pipeWidth, h2);
isScore = false;
说明分析:管道图只有一张,另外一张为上下相反的镜像(管道结尾有特殊形状),经过拉伸裁剪后形成的,控制两管道之间距离为260像素(可通过此改变游戏难度)
图3.2-4 管道图片
(6)像素鸟的加速度和上升下降仰角
birdY += birdDownSpeed;
birdDownSpeed+=0.1;
matrix.rotate(1); //下降的同时旋转
bird = bird.transformed(matrix, Qt::SmoothTransformation);
说明分析:加速度为0.1,使动画更贴近自然,使像素鸟在上升或下降时产生仰角
(7)利用qlabel实现分数的显示
scoreLabel = new QLabel(this);
scoreLabel->setGeometry(width()/2, 0, 50, 50);
QFont font ( "Microsoft YaHei", 20, 75); //第一个属性是字体(微软雅黑),第二个是大小,第三个是加粗(权重是75)
scoreLabel->setFont(font);
QPalette pa;
pa.setColor(QPalette::WindowText,Qt::white);
scoreLabel->setPalette(pa);
this->score = 0;
scoreLabel->setText(QString::number(this->score));
说明分析:实现了分数的显示
4 程序调试分析
(1)对画面更新的速度进行了视觉测试,发现更新太慢,上网搜寻资料,改为16毫秒一更新(60帧每秒)
(2)进行了像素鸟碰撞管道和地面的测试
(3)进行了鸟扑动翅膀的调试,最终改为80毫秒一改动
(4)进行了分数的动态显示测试
(5)进行了音效的测试,去除了鸟扑闪翅膀的音乐(会造成程序卡顿)
(6)进行了管道随机生成的测试,一个画面管道个数过多会造成游戏无解的情况,控制了管道之间的宽度,每个画面只会出现两个及一下的管道
5 程序使用说明
(1)若debug输出 ground is not null 将res文件夹移动到exe文件同目录下即可
(2)点击start进行游戏,控制像素鸟穿过管道,目标为没有最高分只有更高分!
6 总结
第一学年的小学期已经落下来帷幕,这期间我不仅仅对之前的学习内容有了更深的理解,认识以及使用,也学到许多知识。
在刘老师的带领下,我们熟悉了qt运行环境,并在实践和学习中做出了第一个游戏“五子棋”,在选题阶段我选择了flappy bird。在项目收集图片和音频资源时便遇到了极大的困难,该游戏在14年便被开发者下架,资料收集可谓难上加难。在设置游戏参数时也遇到了困难,本来想设计横屏的适合电脑的游戏,但是迫于图片资料的分辨率不高且是手机版的还是做成了竖屏的,设置游戏更新速度和鸟的加速度还有画面更新速度时都遇到了各种隐蔽的问题,最终在老师的帮助和自己上网查找下解决了。在管道的随机产生设计中,经过长达3个小时的调试才最终确定了两个管道之间的最小的间距,防止了bug的发生,出现让玩家无法通过的情况。
但这些困难也都磨练了我,使我的专业水平提升不少,通过文件存储最高分锻炼了我的文件存取能力;通过游戏参数的设置使我对游戏的设计有了更深入的了解;通过图片和音乐资源的调用让我的资源管理水平提到提升。
最后,非常感谢学校给我们这次实训的机会。极高的锻炼了我们的逻辑思维能力。人非生而知之,虽然我们现在的知识结构还很差,但是我们知道要学的知识,一靠努力学习,二靠潜心实践。没有实践,学习就是无源之水,无本之木。在剩下的时间里,我们会更加努力的学习。
在这次C++语言课程设计中,刘老师以及班上的同学给予了我们很大的帮助。刘老师为我提出了许多宝贵的意见,解决了许多程序上的问题,感谢刘老师实训以来对我的诸多教诲以及严格要求,这对我将来的成长非常有帮助。刘老师讲课幽默风趣,平易近人。他是一位恩师更是一位值得信任的朋友。在这几天紧张忙碌的学习和实训中,我掌握了不少知识,在此我想向刘老师表示衷心的感谢,给了我这样一个开阔视野,深入学习C++语言的机会。从项目构想到最终测试,刘老师一直陪伴着我们,让我们非常感动,谢谢您!刘老师
[1] 钱晓捷.汇编语言程序设计.电子工业出版社,2003.
[2] 姜仲秋等主编,c语言程序设计,南京大学出版社,1998年1月
[3] 计算机二级教程 1996年10月
[4] c程序设计(第5版)谭浩强 2001年