当前位置: 首页 > news >正文

用Qt开发小游戏《愤怒的小鸟》


文章目录

  • 前言
    • 本文章主要讲解我和朋友一起用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);}

总结

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


http://www.taodudu.cc/news/show-6309738.html

相关文章:

  • 【physx/wasm】在physx中添加自定义接口并重新编译wasm
  • excel---常用操作
  • Lora训练Windows[笔记]
  • linux基础指令讲解(ls、pwd、cd、touch、mkdir)
  • InnoDB 事务处理机制
  • 启明云端ESP32 C3 模组WT32C3通过 MQTT 连接 AWS
  • [效率提升]webstorm配置Prettier:代码自动格式,格式化时清除空行,修改使用代码模板
  • WebStorm+Vue-cli 配置alias 点击跳转无效问题
  • JavaScript葵花宝典(基础)
  • js Console 对象 - Kaiqisan
  • JS_01_变量_数据类型
  • vanilla_使用Vanilla JavaScript构建Cookie库
  • 笔记 - JavaScript - 超哥视频
  • JS知识点总结(全)
  • Vue.js + Vuex + TypeScript 实战项目开发与项目优化
  • node.js 从基础到操作数据库
  • vscode css智能补全_在 Webstorm 伤透我的心后,我决定尝试 VS Code
  • Js定时器倒计时及堆叠问题解析(附源码)
  • Webstorm干货(开发效率快到飞起!!!)
  • webstorm配置和使用
  • webstorm 风扇一直响_在 Webstorm 伤透我的心后,我决定尝试 VS Code
  • 如何使用 Javascript 截断/切片/修剪字符串中的最后一个字符?
  • 宝塔安装Jdk1.8
  • curl php 宝塔 开启_宝塔安装php失败
  • 安装宝塔后手动安装php,宝塔 安装 php扩展步骤
  • 测试工具和测试自动化
  • Linux下自动化工具
  • 自动化测试概述/自动化工具
  • 自动化测试工具简介
  • 【选型】常用的自动化测试工具
  • 如何选择合适的网络自动化工具
  • 十大最佳自动化测试工具
  • Python自动化工具(自动化操作)
  • 推荐一个强大的工作流自动化工具...
  • 自动化测试.工具
  • 常见自动化测试工具,你用过哪些?