版权声明:访问者可将本网站提供的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。除此以外,将本网站任何内容或服务用于其他用途时,须征得本网站及相关权利人的书面许可,并支付报酬。转载需表明文章地址。
本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,予以删除。
作者QQ:1765813715
由于C++课程设计的原因 打算用QT来写一个Flappy bird 锻炼一下自己对QT的掌握.
还是花了不少时间
总结一下 这次我没有把游戏元素 抽象为类 所以代码可读性很差. 导致后面修改的时候自己都晕了 以后要习惯用类来开发
挺累的所以这次我就不写设计报告什么的了
直接贴关键代码 文件我还是上传到百度云
http://pan.baidu.com/s/1dF8CTQp
1 //mainwindow.h 2 #ifndef MAINWINDOW_H 3 #define MAINWINDOW_H 4 5 #include<QMainWindow> 6 #include<QKeyEvent> 7 #include<QPainter> 8 #include<QPixmap> 9 #include<QMouseEvent> 10 #include<QTimer> 11 #include<QTime> 12 #include<QFile> 13 #include<QDataStream> 14 #include<QMediaPlayer> 15 using namespace std; 16 namespace Ui { 17 class MainWindow; 18 } 19 20 class MainWindow : public QMainWindow 21 { 22 Q_OBJECT 23 24 public: 25 explicit MainWindow(QWidget *parent = 0); 26 void paintEvent(QPaintEvent *); 27 void keyPressEvent(QKeyEvent* e); 28 void mousePressEvent(QMouseEvent* m); 29 void QTimerEvent(int timerId); 30 void welcome(); 31 void lead(); 32 void game(); 33 ~MainWindow(); 34 35 private: 36 QMediaPlayer* m_fly; 37 QMediaPlayer* m_die; 38 QMediaPlayer* m_hit; 39 QMediaPlayer* swoosh; 40 QMediaPlayer* m_point; 41 bool cheat; 42 int last; 43 void gradesave(); 44 void gradeload(); 45 void Rank(); 46 void reset(); 47 int distance; //上下两管道之间的距离 48 void drawgrades(int x, int y, int grade_); 49 void over(); 50 bool doesadd; //用于加分判断 51 bool collisionjudge(); 52 QRect* pipe[6]; 53 QTimer* timer; 54 int land_site; 55 int grades; //保存得分 56 int best_grades; 57 int tag; //表示现在窗口位于哪一个界面 58 int bird_tag; 59 int l_tag; //记录引导界面位于在绘制哪一个图像 60 int fly; 61 int v,a1,a2; 62 int graderank[4]; // 63 QRect menu; 64 QRect begin; //保存开始按钮的矩形区域 65 QRect rank; //保存排行按钮的矩形区域 66 QPixmap medal; 67 QPixmap gameover; 68 QPixmap again; 69 QPixmap ank; 70 QPixmap socreboard; 71 QPixmap b_pixmap; //背景图片 72 QPixmap w_pixmap; //欢迎界面 73 QPixmap c_pixmap; //通用的 保存的图片会改变 74 QPixmap land; 75 QPixmap pip_up; 76 QPixmap pip_down; 77 QPixmap bird; //保存鸟的图片 78 QPixmap number[10]; 79 QRect r_bird; //保存鸟的坐标 80 Ui::MainWindow *ui; 81 }; 82 83 #endif // MAINWINDOW_H
1 //mainwindow.cpp 2 #include "mainwindow.h" 3 #include "ui_mainwindow.h" 4 QString dat[3][4]={ 5 ":/图片/鸟/上20.png",":/图片/鸟/上0.png",":/图片/鸟/上-20.png",":/图片/鸟/上-90.png", 6 ":/图片/鸟/中20.png",":/图片/鸟/中0.png",":/图片/鸟/中-20.png",":/图片/鸟/中-90.png", 7 ":/图片/鸟/下20.png",":/图片/鸟/下0.png",":/图片/鸟/下-20.png",":/图片/鸟/下-90.png" 8 }; 9 MainWindow::MainWindow(QWidget *parent) : 10 QMainWindow(parent), 11 ui(new Ui::MainWindow) 12 { 13 QTime t; 14 t= QTime::currentTime(); 15 qsrand(t.msec()+t.second()*1000); 16 ui->setupUi(this); 17 tag=1; 18 best_grades=0; 19 cheat=0; 20 for(int i=0;i<4;i++) graderank[i]=0; 21 gradeload(); 22 23 m_fly=new QMediaPlayer; 24 m_fly->setMedia(QUrl("qrc:/m/sounds/sfx_wing.mp3")); 25 m_fly->setVolume(100); 26 27 m_die=new QMediaPlayer; 28 m_die->setMedia(QUrl("qrc:/m/sounds/sfx_die.mp3")); 29 m_die->setVolume(100); 30 31 m_hit=new QMediaPlayer; 32 m_hit->setMedia(QUrl("qrc:/m/sounds/sfx_hit.mp3")); 33 m_hit->setVolume(100); 34 35 swoosh=new QMediaPlayer; 36 swoosh->setMedia(QUrl("qrc:/m/sounds/sfx_swooshing.mp3")); 37 swoosh->setVolume(100); 38 39 m_point=new QMediaPlayer; 40 m_point->setMedia(QUrl("qrc:/m/sounds/sfx_point.mp3")); 41 m_point->setVolume(100); 42 distance=140; 43 a1=5; a2=-5; 44 timer=new QTimer(this); 45 connect(timer,SIGNAL(timeout()),this,SLOT(repaint()));//将计时器和 重绘 关联起来 46 begin.setTop(370); begin.setBottom(445); begin.setLeft(35); begin.setRight(170); 47 rank.setTop(370); rank.setBottom(445); rank.setLeft(210); rank.setRight(345); 48 menu.setTop(400); menu.setBottom(427); menu.setLeft(290); menu.setRight(367); 49 socreboard.load(":/图片/其他/记分牌.png"); 50 b_pixmap.load(":/图片/背景/白天.png"); 51 w_pixmap.load(":/图片/其他/开始.png"); 52 land.load(":/图片/背景/地.png"); 53 pip_up.load(":/图片/柱子/反.png"); 54 pip_down.load(":/图片/柱子/正.png"); 55 gameover.load(":/图片/其他/gameover.png"); 56 again.load(":/图片/其他/重来.png"); 57 ank.load(":/图片/其他/排行榜.png"); 58 number[1].load(":/图片/数字/1.png"); number[2].load(":/图片/数字/2.png"); number[3].load(":/图片/数字/3.png"); 59 number[4].load(":/图片/数字/4.png"); number[5].load(":/图片/数字/5.png"); number[6].load(":/图片/数字/6.png"); 60 number[7].load(":/图片/数字/7.png"); number[8].load(":/图片/数字/8.png"); number[9].load(":/图片/数字/9.png"); 61 number[0].load(":/图片/数字/0.png"); 62 reset(); 63 this->setFixedSize(385,448); 64 this->setWindowTitle("Flappy Bird_by lyon"); 65 this->setWindowIcon(QIcon(":/bird.ico")); 66 } 67 void MainWindow::reset() 68 { 69 bird_tag=1; 70 fly=0; 71 doesadd=0; 72 v=0; 73 land_site=385; 74 l_tag=1; 75 grades=0; 76 bird.load(":/图片/鸟/中0.png"); 77 r_bird.setTop(240); r_bird.setLeft(95); r_bird.setRight(138); r_bird.setBottom(270); 78 79 int zz=qrand()%150+100-250; 80 pipe[0]=new QRect(460,zz,65,250); 81 pipe[1]=new QRect(460,zz+250+distance,65,250); 82 zz=qrand()%150-150; 83 pipe[2]=new QRect(460+220,zz,65,250); 84 pipe[3]=new QRect(460+220,zz+250+distance,65,250); 85 zz=qrand()%150-150; 86 pipe[4]=new QRect(460+220*2,zz,65,250); 87 pipe[5]=new QRect(460+220*2,zz+250+distance,65,250); 88 89 } 90 void MainWindow::paintEvent(QPaintEvent* ) //窗口重绘 91 { 92 switch (tag) 93 { 94 case 1: 95 welcome(); 96 break; 97 98 case 2: 99 lead(); 100 break; 101 case 3: 102 game(); 103 break; 104 case 4: 105 over(); 106 break; 107 case 5: 108 Rank(); 109 break; 110 default: 111 break; 112 } 113 } 114 115 void MainWindow::keyPressEvent(QKeyEvent *e) //键盘事件 116 { 117 switch(e->key()) 118 { 119 case Qt::Key_Space: 120 { 121 if(tag==2) 122 { 123 tag=3; 124 timer->start(70); 125 } 126 else if(tag==3) //这里后面再写 127 { 128 //if(fly>=0) return; 129 m_fly->stop(); 130 m_fly->play(); 131 fly=4; v=10; 132 //repaint(); 133 } 134 break; 135 } 136 case Qt::Key_F1: 137 if(distance==140) distance=200; 138 else if(distance==200) distance=140; 139 break; 140 case Qt::Key_F2: 141 cheat=!cheat; 142 break; 143 default: 144 return ; 145 146 } 147 } 148 149 void MainWindow::mousePressEvent(QMouseEvent *m) 150 { 151 switch(tag) 152 { 153 case 1: 154 { 155 if(begin.contains(m->x(),m->y())) 156 { 157 timer->start(300); 158 tag=2; 159 swoosh->stop(); 160 swoosh->play(); 161 } 162 else if(rank.contains(m->x(),m->y())) 163 { 164 last=1; 165 tag=5; 166 swoosh->stop(); 167 swoosh->play(); 168 repaint(); 169 } 170 171 break; 172 } 173 case 4: 174 { 175 if(begin.contains(m->x(),m->y())) 176 { 177 timer->start(300); 178 tag=2; 179 swoosh->stop(); 180 swoosh->play(); 181 reset(); 182 } 183 else if(rank.contains(m->x(),m->y())) 184 { 185 last=4; 186 tag=5; 187 swoosh->stop(); 188 swoosh->play(); 189 repaint(); 190 } 191 192 break; 193 } 194 case 5: 195 if(menu.contains(m->x(),m->y())) 196 { 197 tag=last; 198 swoosh->stop(); 199 swoosh->play(); 200 repaint(); 201 } 202 break; 203 } 204 } 205 206 void MainWindow::welcome() //欢迎界面 tag 1 207 { 208 QPainter painter(this); 209 painter.drawPixmap(0,0,w_pixmap); 210 } 211 212 void MainWindow::lead() //引导界面 tag 2 213 { 214 switch(l_tag) 215 { 216 case 1: 217 c_pixmap.load(":/图片/引导/白天/上.png"); l_tag=2; break; 218 case 2: 219 c_pixmap.load(":/图片/引导/白天/中.png"); l_tag=3; break; 220 case 3: 221 c_pixmap.load(":/图片/引导/白天/下.png"); l_tag=1; break; 222 } 223 QPainter painter(this); 224 painter.drawPixmap(0,0,c_pixmap); 225 c_pixmap.load(":/图片/数字/0.png"); 226 painter.drawPixmap(180,100,c_pixmap); 227 painter.drawPixmap(0,423,land); 228 //painter.drawPixmap(95,240,bird); 229 } 230 231 void MainWindow::game() //画出游戏开始时 鸟 管道 232 { 233 if(!cheat) 234 { 235 if(collisionjudge()) 236 { 237 m_hit->play(); 238 timer->stop(); 239 tag=4; 240 best_grades=max(best_grades,grades); 241 gradesave(); 242 repaint(); 243 } 244 } 245 QPainter painter(this); 246 //painter.drawPixmap(50,50,pip_down); 247 painter.drawPixmap(0,0,b_pixmap); 248 //if(pipe[0]->right()<r_bird.left()) grades++; 249 for(int i=0;i<6;i++) 250 { 251 //painter.drawRect(*pipe[i]); 252 253 if(i%2==0) 254 painter.drawPixmap(pipe[i]->left(),pipe[i]->top(),pip_up); 255 else 256 painter.drawPixmap(pipe[i]->left(),pipe[i]->top(),pip_down); 257 258 if(i%2==0) //判断加分 259 { 260 if(pipe[i]->right()<r_bird.left()&&!doesadd) 261 { 262 doesadd=1; 263 grades++; 264 m_point->stop(); 265 m_point->play(); 266 } 267 } 268 pipe[i]->translate(-8,0); 269 } 270 if(pipe[0]->right()<0) 271 { 272 doesadd=0; 273 for(int i=0;i<4;i+=2) 274 { 275 pipe[i]=pipe[i+2]; 276 pipe[i+1]=pipe[i+3]; 277 } 278 int zz=qrand()%150-150; 279 pipe[4]=new QRect(pipe[2]->left()+220,zz,65,250); 280 pipe[5]=new QRect(pipe[3]->left()+220,zz+250+distance,65,250); 281 } 282 painter.drawPixmap(land_site-385,423,land); 283 painter.drawPixmap(land_site,423,land); 284 land_site-=5; 285 if(land_site<0) 286 land_site=384; 287 288 //painter.drawRect(r_bird); 289 290 painter.drawPixmap(r_bird.left(),r_bird.top(),bird); 291 if(fly>0) 292 { 293 r_bird.translate(0,-(v+a1/2)); 294 v+=a1; 295 bird.load(dat[bird_tag][0]); 296 fly--; 297 bird_tag++; 298 if(bird_tag==3) bird_tag=0; 299 } 300 else if(fly==0) 301 { 302 v=0; 303 bird.load(dat[bird_tag][1]); 304 fly--; 305 bird_tag++; if(bird_tag==3) bird_tag=0; 306 } 307 else if(fly<0) 308 { 309 r_bird.translate(0,-(v+a2/2)); 310 v+=a2; 311 if(fly>=-5) 312 bird.load(dat[bird_tag][2]); 313 else bird.load(dat[bird_tag][3]); 314 fly--; 315 bird_tag++; if(bird_tag==3) bird_tag=0; 316 } 317 318 if(r_bird.top()< -2) r_bird.translate(0,10); 319 drawgrades(180,100,grades); 320 321 } 322 323 MainWindow::~MainWindow() 324 { 325 delete ui; 326 } 327 328 void MainWindow::gradesave() //保存排行榜 329 { 330 for(int i=0;i<4;i++) 331 { 332 if(grades>graderank[i]) 333 { 334 for(int j=3;j>i;j--) 335 graderank[j]=graderank[j-1]; 336 graderank[i]=grades; 337 break; 338 } 339 } 340 QFile file("rank.b"); 341 file.open(QIODevice::WriteOnly); 342 QDataStream out(&file); 343 for(int i=0;i<4;i++) 344 out<<graderank[i]; 345 } 346 347 void MainWindow::gradeload() //加载排行榜 348 { 349 QFile file("rank.b"); 350 if(file.open(QIODevice::ReadOnly)) 351 { 352 QDataStream in(&file); 353 for(int i=0;i<4;i++) 354 in>>graderank[i]; 355 } 356 357 358 } 359 360 void MainWindow::Rank() 361 { 362 QPainter painter(this); 363 painter.drawPixmap(0,0,b_pixmap); 364 medal.load(":/图片/奖牌/金牌.png"); painter.drawPixmap(0,0,medal); 365 medal.load(":/图片/奖牌/白金牌.png"); painter.drawPixmap(0,62,medal); 366 medal.load(":/图片/奖牌/银牌.png"); painter.drawPixmap(0,124,medal); 367 medal.load(":/图片/奖牌/铜牌.png"); painter.drawPixmap(0,186,medal); 368 c_pixmap.load(":/图片/其他/menu.png"); 369 painter.drawPixmap(290,400,c_pixmap); 370 int t=10; 371 for(int i=0;i<4;i++) 372 { 373 drawgrades(100,t,graderank[i]); 374 t+=61; 375 } 376 377 } 378 379 380 void MainWindow::drawgrades(int x,int y,int grade_) 381 { 382 QPainter painter(this); 383 if(grade_==0) 384 { 385 painter.drawPixmap(x,y,number[0]); 386 } 387 int a=grade_; 388 int bite=0; 389 while(a) 390 { 391 a/=10; 392 bite++; 393 } 394 int head=x+bite/2*25; 395 a=grade_; 396 while(a) 397 { 398 painter.drawPixmap(head,y,number[a%10]); 399 head-=25; 400 a/=10; 401 } 402 } 403 404 void MainWindow::over()// 游戏结束的画面 405 { 406 QPainter painter(this); 407 painter.drawPixmap(0,0,b_pixmap); 408 for(int i=0;i<6;i++) 409 { 410 if(i%2==0) 411 painter.drawPixmap(pipe[i]->left(),pipe[i]->top(),pip_up); 412 else 413 painter.drawPixmap(pipe[i]->left(),pipe[i]->top(),pip_down); 414 } 415 painter.drawPixmap(r_bird.left(),r_bird.top(),bird); 416 painter.drawPixmap(land_site-385,423,land); 417 painter.drawPixmap(land_site,423,land); 418 painter.drawPixmap(45,130,socreboard); 419 painter.drawPixmap(70,50,gameover); 420 painter.drawPixmap(begin.left(),begin.top(),again); 421 painter.drawPixmap(rank.left(),rank.top(),ank); 422 if(grades>=100) 423 medal.load(":/图片/奖牌/金牌.png"); 424 else if(grades>=50) 425 medal.load(":/图片/奖牌/白金牌.png"); 426 else if(grades>=20) 427 medal.load(":/图片/奖牌/银牌.png"); 428 else if(grades>=10) 429 medal.load(":/图片/奖牌/铜牌.png"); 430 if(grades>=10) 431 { 432 painter.drawPixmap(75,177,medal); 433 } 434 435 drawgrades(278,166,grades); 436 drawgrades(278,224,best_grades); 437 } 438 439 bool MainWindow::collisionjudge() //碰撞检测 440 { 441 if(r_bird.bottom()>=423) return true; 442 for(int i=0;i<6;i++) 443 { 444 if(r_bird.intersects(*pipe[i])) 445 { 446 return true; 447 } 448 } 449 return false; 450 }