C++ Develop 12 --- 2020.9.3

记录开发



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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值