C++ Develop 12 --- 2020.9.3

tech2023-07-22  97

记录开发


目录

13. 翻硬币小游戏3. 关卡选择4. 游戏关卡场景


13. 翻硬币小游戏

3. 关卡选择

首先要添加新的类,命名为 ChooseLevelScene,即关卡选择,然后新建并维护一个该对象 chooseScene;chooseScene = new ChooseLevelScene;,随后要隐藏原窗口,显示新窗口;

QTimer::singleShot(500, this,[=](){ this->hide(); chooseScene->show(); });

上述用到的是延时函数,原因在于代码的执行速度快,上一节中的弹跳动画还未演示完就会被隐藏; 接下来配置新窗口的一些基本信息;

ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent) { //设置窗口基本信息; this->setFixedSize(320, 588); this->setWindowIcon(QPixmap(":/res/Coin0001.png")); this->setWindowTitle("ChooseLevel"); //添加菜单栏; QMenuBar *bar = menuBar(); setMenuBar(bar); QMenu *startMenu = bar->addMenu("开始"); QAction *quitAction = startMenu->addAction("退出"); //关联窗口关闭; connect(quitAction, &QAction::triggered, [=](){ this->close(); }); } void ChooseLevelScene::paintEvent(QPaintEvent *) //画入背景及标题; { QPainter painter(this); QPixmap pix; pix.load(":/res/OtherSceneBg.png"); painter.drawPixmap(0, 0, this->width(), this->height(), pix); pix.load(":/res/Title.png"); painter.drawPixmap(10, 30, pix); }

接下来要配置带动态效果的返回按键,需要用到上一节的 MyPushButton,重载两个鼠标事件;

void MyPushButton::mousePressEvent(QMouseEvent *e) { if(this->pressImgPath != "") { QPixmap pix; bool ret = pix.load(this->pressImgPath); if(!ret) { qDebug() << "Error"; return; } this->setFixedSize(pix.width(), pix.height()); this->setStyleSheet("QPushButton{border:0px}"); //边框为 0 像素; this->setIcon(pix); this->setIconSize(QSize(pix.width(), pix.height())); } //其余交给父类; return QPushButton::mousePressEvent(e); } void MyPushButton::mouseReleaseEvent(QMouseEvent *e) { if(this->pressImgPath != "") { QPixmap pix; bool ret = pix.load(this->normalImgPath); if(!ret) { qDebug() << "Error"; return; } this->setFixedSize(pix.width(), pix.height()); this->setStyleSheet("QPushButton{border:0px}"); //边框为 0 像素; this->setIcon(pix); this->setIconSize(QSize(pix.width(), pix.height())); } //其余交给父类; return QPushButton::mouseReleaseEvent(e); }

接下来要使得点击按钮后返回主场景,我们从主场景切换到 Level 场景是用的是 hide 函数,然后 chooseLevel->show(),这是因为 chooseLevel 是主窗口中的一个窗口成员,所以可以调用,而 mainscene 不是 ChooseLevelScene 下的成员,所以需要借助信号来实现返回

class ChooseLevelScene : public QMainWindow { Q_OBJECT public: explicit ChooseLevelScene(QWidget *parent = nullptr); void paintEvent(QPaintEvent *); signals: //自定义返回信号; void chooseSceneBack(); //信号不需要实现; }; //chooselevelscene.cpp connect(backBtn, &MyPushButton::clicked, [=](){ emit this->chooseSceneBack(); }); //mainscene.cpp connect(chooseScene, &ChooseLevelScene::chooseSceneBack, [=](){ chooseScene->hide(); this->show(); });

接着创建关卡选择按钮,步骤差不多,用的也是自建按钮,设置好位置以及 text;

//用一个循环写一个矩阵; for(int i = 0; i < 20; i++) { MyPushButton * menuBtn = new MyPushButton(":/res/LevelIcon.png"); menuBtn->setParent(this); menuBtn->move( 25 + i%4 * 70 , 130 + i/4 * 70 ); //监听每个按钮的点击事件,会被下方的 Label 覆盖,所以需要设置鼠标穿透; connect(menuBtn,&MyPushButton::clicked,[=](){ QString str = QString("您选择的是第 %1 关 ").arg( i + 1); qDebug() <<str; }); //单独用 Label 显示数字,不规则按钮显示会出问题; QLabel *label = new QLabel; label->setParent(this); label->setFixedSize(menuBtn->width(),menuBtn->height()); label->setText(QString::number(i+1)); label->move(25 + i%4 * 70 , 130 + i/4 * 70 ); //设置 label上的文字对齐方式 水平居中和 垂直居中 label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); //设置让鼠标进行穿透 51号属性 label->setAttribute(Qt::WA_TransparentForMouseEvents); }

4. 游戏关卡场景

所要设置的场景内容相似,就是一些背景,图标以及返回按键

class PlayScene : public QMainWindow { Q_OBJECT public: //explicit PlayScene(QWidget *parent = nullptr); PlayScene(int levelNum); int levelIndex; //记录所选关卡; void paintEvent(QPaintEvent *); signals: void playSceneBack(); }; PlayScene::PlayScene(int levelNum) { //初始化游戏场景 //设置固定大小 this->setFixedSize(320,588); //设置图标 this->setWindowIcon(QPixmap(":/res/Coin0001.png")); //设置标题 this->setWindowTitle("FlipScene"); //创建菜单栏 QMenuBar * bar = menuBar(); setMenuBar(bar); //创建开始菜单 QMenu * startMenu = bar->addMenu("开始"); //创建退出 菜单项 QAction * quitAction = startMenu->addAction("退出"); //点击退出 实现退出游戏 connect(quitAction,&QAction::triggered,[=](){ this->close(); }); //返回按钮; MyPushButton *backBtn = new MyPushButton(":/res/BackButton.png", ":/res/BackButtonSelected.png"); backBtn->setParent(this); backBtn->move(this->width() - backBtn->width(), this->height() - backBtn->height()); connect(backBtn, &MyPushButton::clicked, [=](){ emit this->playSceneBack(); }); //显示当前关卡数 QLabel * label = new QLabel; label->setParent(this); QFont font; font.setFamily("华文新魏"); font.setPointSize(20); QString str1 = QString("Level: %1").arg(this->levelIndex); //将字体设置到标签控件中 label->setFont(font); //都是用类去做参数; label->setText(str1); label->setGeometry(30, this->height() - 50, 120, 50); } void PlayScene::paintEvent(QPaintEvent *) { //创建背景 QPainter painter(this); QPixmap pix; pix.load(":/res/PlayLevelSceneBg.png"); painter.drawPixmap(0,0,this->width(),this->height(),pix); //加载标题 pix.load(":/res/Title.png"); pix = pix.scaled(pix.width()*0.5,pix.height()*0.5); painter.drawPixmap( 10,30,pix.width(),pix.height(),pix); }

在游戏场景里同样创建了返回按钮,加上了信号,所以在关卡选择中需要监听该信号;

//chooselevelscene.cpp connect(play, &PlayScene::playSceneBack, [=](){ this->show(); delete play; //让旧场景完全释放; play = NULL; });
最新回复(0)