文章目录

  • 前言
    • 本文章主要讲解我和朋友一起用Qt开发的小游戏《愤怒的小鸟》,游戏素材来源于游戏截图和网上查找。这是一款曾经在手机上风靡一时的横屏小游戏,游戏具体怎么玩想必我就不用跟大家介绍了吧。主要说说里面最不好实现的一个东西:“物理引擎”,就是小鸟的飞行轨迹和小鸟和障碍物的撞击效果。
  • 一、游戏效果
  • 二、代码功能模块
    • 1.第一个模块(主模块) 登录界面
    • 2.第二个模块 游戏开始界面
    • 3.第三个模块 关卡选择界面
    • 4.第四个模块 游戏界面
    • 5.第五个模块 鸟对象
  • 总结

前言

本文章主要讲解我和朋友一起用Qt开发的小游戏《愤怒的小鸟》,游戏素材来源于游戏截图和网上查找。这是一款曾经在手机上风靡一时的横屏小游戏,游戏具体怎么玩想必我就不用跟大家介绍了吧。主要说说里面最不好实现的一个东西:“物理引擎”,就是小鸟的飞行轨迹和小鸟和障碍物的撞击效果。

一、游戏效果

​​​​


二、代码功能模块

1.第一个模块(主模块) 登录界面

核心代码如下(示例):

void Widget::regiser(bool)
{//查询用户是否已经存在QString  str = QString("select * from usertable where account='%0';")\.       arg(le_account->text());QSqlQuery query;query.exec(str);while(query.next()){QMessageBox msgBox;msgBox.setText("该用户已存在!请重新注册!");msgBox.exec();return ;}//不存在就注册bool ok;QString username = QInputDialog::getText(this, "Angry Birds","User name:",QLineEdit::Normal,QDir::home().dirName(),&ok);if (ok && !username.isEmpty()){//向入据库中加入一条用户信息QString  str = QString("insert into usertable values('%0', '%1', '%2', '0');")\.arg(le_account->text()).arg(le_password->text()).arg(username);//插入用户 账号,密码,用名QSqlQuery query;query.exec(str);QMessageBox msgBox;msgBox.setText("恭喜你!注册成功!");msgBox.exec();}
}
void Widget::login(bool)
{//账号√ 密码√QString  str = QString("select * from usertable where account='%0' and password='%1';")\.arg(le_account->text()).arg(le_password->text());QSqlQuery query;query.exec(str);while(query.next()){qDebug() << query.value(0).toString();qDebug() << query.value(1).toString();qDebug() << query.value(2).toString();qDebug() << query.value(3).toString();emit login_successed();//发射登录成功的信号hide();//隐藏当前界面return ;}//账号√密码×str = QString("select * from usertable where account='%0';")\.arg(le_account->text());query.exec(str);while(query.next()){QMessageBox msgBox;msgBox.setText("密码错误!请重新输入!");msgBox.exec();return ;}//账号xQMessageBox msgBox;msgBox.setText("该用户不存在!请先注册!");msgBox.exec();
}

2.第二个模块 游戏开始界面

核心代码如下(示例):

Start::Start(QWidget *parent) : QWidget(parent)
{setFixedSize(1800,967);setGeometry(70,50,1800,967);this->setWindowIcon(QIcon(":/img/icon.png"));this->setWindowTitle("愤怒的小鸟");//界面跳转choose = new choosepoint;connect(this, &Start::start, this, [&](){choose->setGeometry(this->geometry());choose->show();});//绑定当前界面 发射的start开始游戏的信号 给选择关卡界面choose 让它显示connect(choose, &choosepoint::choosesceneback, this, [&](){this->setGeometry(choose->geometry());this->show();});//绑定choose选择关卡界面 发射的choosesceneback返回信号 给当前界面 让它显示/*connect(choose, &choosepoint::choosesceneback, [=](){//绑定choose选择关卡界面 发射的choosesceneback返回信号 给当前界面 让它显示choose->hide();this->show();});*/
}
void Start::paintEvent(QPaintEvent *event)
{QPainter p(this);p.drawPixmap(0, 0, 1800, 967, QPixmap(":/img/start.jpg"));p.drawPixmap(1713, 10, 77, 32, QPixmap(":/img/BackButton.png"));
}
void Start::mousePressEvent(QMouseEvent *event)
{//点击密码的显示与隐藏if(event->pos().x() > 760 && event->pos().x() < 1040 && event->pos().y() > 510 && event->pos().y() < 640){emit start();hide();//隐藏当前界面}if(event->pos().x() > 1713 && event->pos().x() < 1790 && event->pos().y() > 10 && event->pos().y() < 42){emit back();hide();//隐藏当前界面}
}

3.第三个模块 关卡选择界面

choosepoint::choosepoint(QWidget *parent) : QMainWindow(parent)
{//选择关卡场景this->setFixedSize(1800, 967);setGeometry(70,50,1800,967);this->setWindowIcon(QIcon(":/img/icon.png"));this->setWindowTitle("关卡场景");//返回按钮mybushbutton * backbtn = new mybushbutton(":/img/BackButton.png",":/img/BackButtonSelected.png");backbtn->setParent(this);backbtn->move(1713, 10);//跳转到上一个界面connect(backbtn, &mybushbutton::clicked,[=](){QTimer::singleShot(300,this,[=](){emit this->choosesceneback(); //为了看到动画效果hide();});});int i;//跳转到关卡界面   创建选择关卡的按钮for( i = 0; i < 20; i++){mybushbutton * menubtn = new mybushbutton(":/img/LevelIcon.png");menubtn->setParent(this);menubtn->move( 560 + i % 5 * 160, 300 + i / 5 * 130);  //一维数构造二维数组connect(menubtn, &mybushbutton::clicked,[=](){this->hide();//隐藏当前界面//界面跳转shot = new slingshot(i + 1);shot->setGeometry(this->geometry());shot->show();//设置游戏场景初始位置//监听返回connect(shot, &slingshot::back, this, [=](){this->setGeometry(shot->geometry());shot->deleteLater();this->show();});//});QLabel * label = new QLabel;label->setParent(this);label->setFixedSize(menubtn->width(),menubtn->height());label->setText(QString::number(i+1));label->move(560 + i % 5 * 160, 300 + i / 5 * 130);//设置label上的文字对齐方式label->setAlignment(Qt::AlignHCenter | Qt:: AlignVCenter);//设置鼠标穿透事件  51号label->setAttribute(Qt::WA_TransparentForMouseEvents);}}
//重写绘图事件
void choosepoint::paintEvent(QPaintEvent *)
{QPainter painter(this);QPixmap pix;//加载图片pix.load(":/img/choose.jpg");painter.drawPixmap(0,0,this->width(),this->height(),pix);
}

4.第四个模块 游戏界面

void slingshot::mouseMoveEvent(QMouseEvent *event)
{//判断拉动皮筋if(event->pos().x() > 440 && event->pos().x() < 490 && event->pos().y() > 546 && event->pos().y() < 556)pullflag = true;if(pullflag && event->pos().x() >0 && event->pos().x() < 900 && event->pos().y() > 0 && event->pos().y() < 967)posline = event->pos();update();
}
void slingshot::mouseReleaseEvent(QMouseEvent *event)
{//判断在拉动皮筋后松开皮筋if(pullflag){emit Releaseline();check->b->current_vx = check->b->current_vy = 0;vx = 465 - posline.x();vy = 551 - posline.y();resistance_const = 0.0003;accg = -30.6;qDebug() << 465 - posline.x() << 551 - posline.y() << "hhhhh";posline = QPoint(465, 551);pullflag = false;}update();
}
void slingshot::mousePressEvent(QMouseEvent *event)
{//退出游戏if(event->pos().x() > 1740 && event->pos().x() < 1790 && event->pos().y() > 10 && event->pos().y() < 60){QMessageBox msgBox;msgBox.setText("你确定要退出游戏吗?");msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);if( QMessageBox::Yes == msgBox.exec()){emit back();hide();//隐藏当前界面}}
}void slingshot::slig(QPoint p)
{//判断拉动皮筋if(p.x() > 440 && p.x() < 490 && p.y() > 546 && p.y() < 556)pullflag = true;if(pullflag && p.x() >100 && p.x() < 763 && p.y() > 240 && p.y() < 840)posline = p;update();
}

5.第五个模块 鸟对象

void bird::port(qreal vx, qreal vy, qreal resistance_const, qreal accg)
{if(current_vy == 0 && current_vx == 0 && time == 0){current_vx = vx;current_vy = vy;this->resistance_const = resistance_const;this->accg = accg;}if(time == 0){wpos = this->geometry().topLeft();track_x = track_y = 0;}resistance_ax = resistance_const * current_vx * current_vx / bird_weight;//resistance_ay = resistance_const * current_vy * current_vy / bird_weight;//qDebug() << resistance_ax << "ax";last_vx = current_vx;current_vx -= (resistance_ax + 0.4 * 0.01);if(flag == true){current_vy +=  (accg * 0.1 + 2);energy -= (accg * 0.1 + 2);if(energy < 0)flag = false;}else{current_vy -=  (accg * 0.1 - 2);energy += (accg * 0.1 - 2);if(current_vy < 0)flag = true;}if( qAbs(current_vx + last_vx) != qAbs(qAbs(current_vx) + qAbs(last_vx)) ) //单位统一{vx_flag = false;}time += 0.1;qDebug() << current_vx << "vx";qDebug() << current_vy << "vy";if(vx_flag == true) //{track_x += current_vx * 0.1;//track_x = vx * time - 1/2.0 * resistance_ax * time * time - 0.2 * time *time * time;}//last_y = track_y;track_y += current_vy * 0.1;//track_y = vy * time - 1/2.0 * accg * time * time ;//emit bird_move(track_x, track_y);qDebug() << wpos.x() + track_x << wpos.y() + track_y;move(wpos.x() + track_x , wpos.y() + track_y );if(wpos.x() + track_x > 1800 || wpos.y() + track_y  > 967 || wpos.y() + track_y < 0 ||wpos.x() + track_x < 0 || (current_vx == 0 && current_vy == 0  )){//move(wpos);move(10 , 600);timer->stop();time = 0;track_x = track_y = 0;}emit bird_move(QPoint(geometry().topLeft().x() + width()/2,geometry().topLeft().y() + height()/2));}void bird::mouseMoveEvent(QMouseEvent *event)
{//move(event->globalX() - pos.x(), event->globalY() - pos.y());pos1 = event->globalPos();
//    qDebug() << "pos1" << pos1.x() << pos1.y();
//    qDebug() << "pos" << pos.x() << pos.y();
//    qDebug() << "wpos" << wpos.x() << wpos.y();//qDebug() << wpos.x()+pos1.x()-pos.x() << wpos.y()+pos1.y()-pos.y() << "mouse";move(wpos.x()+pos1.x()-pos.x(),wpos.y()+pos1.y()-pos.y());emit bird_move(QPoint(geometry().topLeft().x() + width()/2,geometry().topLeft().y() + height()/2));
//    qDebug() <<  "x " << geometry().topLeft().x() + width()/2 <<
//             "y" << geometry().topLeft().y() + height()/2;}void bird::mousePressEvent(QMouseEvent *event)
{pos = event->globalPos();wpos = this->geometry().topLeft();if(event->buttons() ==  Qt::RightButton){//emit botton_clicek(50);current_vx = current_vy = 0;}// pos = event->pos();}void bird::paintEvent(QPaintEvent *event)
{QPainter p(this);p.drawPixmap(0, 0, *pix);}

总结

`本文章尚未完成,期待作者后续补充更改。。。。

用Qt开发小游戏《愤怒的小鸟》相关推荐

  1. 【Unity3D开发小游戏】《愤怒的小鸟》开发教程

    [Unity3D开发小游戏]<愤怒的小鸟>开发教程 2019年09月11日 10:34:36 恬静的小魔龙 阅读数 1698更多 分类专栏: Unity3D日常 Unity3d手游开发 U ...

  2. linux qt 俄罗斯方块,使用Qt开发俄罗斯方块游戏

    使用Qt开发俄罗斯方块游戏,可能大家都比较感兴趣吧.那么就快看下面的详细讲解吧! 其实在QtCreator中已经有了俄罗斯方块的例子,大家可以在帮助中搜索Tetrix进行查看.其内容如下: 但是对于初 ...

  3. Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk

    Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk 程序依赖:pygame2.0.1, pymunk5.5.0 直接运行main.py 完整代码下载地址:Python版经典小游戏 ...

  4. java愤怒的小鸟代码_用java实现小游戏“愤怒的小鸟”附源码和效果演示

    推荐下我自己的群:6915 72518,不管你是小白还是大牛,小编我都挺欢迎,不定期分享干货,包括我自己整理的一份最新资料和零基础入门教程!,欢迎初学和进阶中的小伙伴 今天跟大家分享一个用纯Java代 ...

  5. 个人使用CocosCreator开发小游戏路上的一些“坑坑洼洼”

    个人使用CocosCreator开发小游戏路上的一些"坑坑洼洼" 开场自白 微信小游戏 适配 一般界面弹窗节点适配 套路的需求适配 PS ps中的ps 摄像机的新手操作 tiled ...

  6. 【Unity3D开发小游戏】专栏文章导读清单

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一.前言 本专栏,以小游戏的开发为手段,以学习为目的,在学习的道路中,总是要 ...

  7. [python] 开发小游戏 豆豆吃花瓣

    今天来做一个python游戏 使用python的游戏框架pygame开开发一个自创的豆豆吃花瓣的游戏[还没有取名字?] 首先看下游戏主目录下有些什么文件 就一个img的文件夹,和一个py的文件 img ...

  8. C语言开发小游戏—编译器篇graphic.h的安装

    用C语言开发小游戏的前期准备-以VS2015编译器为例 要开发小游戏很大 程度上C和C++都会涉及,并且会涉及不少库函数的知识,在这里简单起见,我先把开发一个简单的图形界面游戏需要的东西在这里写一下, ...

  9. 智力开发小游戏集含游戏过程中数据存取-C#入门教学程序

    对于初学C#程序开发的学员,一般进行采取开发小游戏程序,这样做首先不会让学员失去学习的兴趣,其次可以将C#中基本的控件与类的写法整合到这些游戏程序中,再次将对数据库的操作也教给学员.通过几年的观察这样 ...

最新文章

  1. 语音计算矩形面积_LeetCode85-最大矩形
  2. python 合并 循环list_阿里巴巴鼎力推荐,Python入门至精通,24招加速你的Python
  3. git 基本命令记录
  4. art-template入门(六)之解析规则
  5. java script的trim_Javascript中实现trim()函数的两种方法
  6. 用户DSN、 系统DSN 、文件DSN
  7. 三维点云学习(3)4-Expectation-Maximization (EM)
  8. 斐波那契数列的递归与迭代写法比较
  9. 工作要求,写了一些没用的设计文档
  10. html5抓娃娃机微信小游戏源码
  11. 深度学习系列18:开源人脸识别库
  12. godspeed机器人_cs1.6kz地图包下载
  13. 北大人工智能前沿讲座--第二讲 嵌入式人工智能
  14. Python Rule Engine
  15. 【分析】Ceph数据一致性检查 - Scrub的执行
  16. orge,Nebula与klayGE对比
  17. Django 解决CSRF 跨域问题总结
  18. PMP第十二章:项目采购管理
  19. 怎么把录音转文字?只需三步,手把手教会你
  20. iphone xr xs_如何关闭iPhone X,XS和XR

热门文章

  1. VisualC++逆序存放
  2. html5服务器推送消息的各种解决办法,WEB服务器推送消息的各种解决办法
  3. mysql 1亿条数据建索引时间_单表 13 亿记录创建索引需要多长时间?
  4. Linux系列6:bash学习
  5. JS DOM获取标签/元素style样式
  6. vue.使用popstate监听点击浏览器自带返回按钮
  7. nginx 404 not found错误查找
  8. LeetCode509(力扣509) :斐波那契数列 C++ 多种思路与详细解析
  9. 什么是谐波?谐波的危害
  10. FPGA芯片的GTX/GTH/GTY/GTP/GTZ/GTM高速信号有什么区别?