[Qt 5.6.2] 利用Qt实现一个难度可变的2048小游戏

Posted NULL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Qt 5.6.2] 利用Qt实现一个难度可变的2048小游戏相关的知识,希望对你有一定的参考价值。

利用Qt实现一个难度随时可调的2048小游戏

 

一、游戏简介

1、规则创新

  胜利条件:达成2048

  难度变化:玩家可以通过调整难度条来控制随机池(2、4、8、16)中各个数出现的概率,同时也会改变分数的加成比例

  移动触发:每次移动后会从随机池中按照概率随机选取一个数,将其随机放置在一个空余位置上

  分数计算:总分=基础分+加成分,基础分+=合并的数值,加成分+=随机生成的数值*加成比例

 

2、游戏效果

   

 

 

二、设计思路

  先将该项目分为游戏入口、主窗口设计与游戏逻辑三个主要模块,再在这三个模块的基础上继续细分,分割成若干个小的功能模块,最后逐一实现。由MainWindow与GameLogic两个类分别实现主界面的显示功能与游戏的实现逻辑。

  程序入口较为简单,故不赘述。

  主窗口设计主要实现棋盘数据的显示与颜色变化、分数与难度的显示、检测方向键并连接进入游戏逻辑的入口。

  游戏逻辑是整个项目的核心部分,主要实现整个游戏的逻辑判断,根据主窗口提供的难度计算出难度系数与随机池各个数据出现概率。

 

 

三、代码分析

  文件具体分为gamelogic.cpp、main.cpp与mainwindow.cpp三个.cpp文件,gamelogic.h、mainwindow.h两个.h文件与一个mainwindow.ui文件。

1、程序入口:main.cpp

 1 #include "mainwindow.h"
 2 #include <QApplication>
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     QApplication a(argc, argv);
 7     MainWindow w;
 8     w.show();
 9 
10     return a.exec();
11 }

 如果想进行人员管理与登陆的拓展可改为以下代码,可自行设计login登录规则:

 1 #include "mainwindow.h"
 2 #include <QApplication>
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     QApplication a(argc, argv);
 7     MainWindow w;
 8     w.show();
 9 
10     return a.exec();
11 }
View Code

 

 

2、主窗口设计:mainwindow.cpp/.h/.ui

2.1 mainwindow.ui

      

 

2.2 mainwindow.h

 1 #ifndef MAINWINDOW_H
 2 #define MAINWINDOW_H
 3 
 4 #include <QMainWindow>
 5 #include <QKeyEvent>
 6 #include <QDebug>
 7 #include <QMessageBox>
 8 #include <QTextBrowser>
 9 #include "gamelogic.h"
10 
11 namespace Ui {
12 class MainWindow;
13 }
14 
15 class MainWindow : public QMainWindow
16 {
17     Q_OBJECT
18 
19 public:
20     GameLogic* game;
21     explicit MainWindow(QWidget *parent = 0);
22     ~MainWindow();
23     void initAll(); 
24     void showMessage();
25     void showBroad();
26     void keyPressEvent(QKeyEvent *event);
27     void changeColor(QLabel* label, int num);
28 
29 private slots:
30     void on_pushButton_start_clicked();
31 
32     void on_pushButton_close_clicked();
33 
34     void on_horizontalSlider_valueChanged(int value);
35 
36 private:
37     Ui::MainWindow *ui;
38 };
39 
40 #endif // MAINWINDOW_H

 

2.3 mainwindow.cpp(代码共177行,折叠)

  1 #include "mainwindow.h"
  2 #include "ui_mainwindow.h"
  3 #include "gamelogic.h"
  4 
  5 MainWindow::MainWindow(QWidget *parent) :
  6     QMainWindow(parent),
  7     ui(new Ui::MainWindow)
  8 {
  9     game = new GameLogic;
 10     ui->setupUi(this);
 11     showBroad();
 12 }
 13 
 14 MainWindow::~MainWindow()
 15 {
 16     delete ui;
 17 }
 18 
 19 void MainWindow::initAll()
 20 {
 21     game->initAll();
 22     on_horizontalSlider_valueChanged(ui->horizontalSlider->value());
 23 }
 24 
 25 
 26 void MainWindow::on_pushButton_start_clicked()
 27 {
 28     ui->pushButton_start->setText("重新开始");
 29     initAll();
 30 
 31     game->createNum();
 32     game->createNum();
 33     game->setGameStart(true);
 34 
 35     showBroad();
 36     showMessage();
 37 }
 38 
 39 void MainWindow::on_pushButton_close_clicked()
 40 {
 41     this->close();
 42 }
 43 
 44 void MainWindow::on_horizontalSlider_valueChanged(int value)
 45 {
 46     value = ui->horizontalSlider->value();
 47     ui->label_showGradeUpCoefficient->setText(QString::number(value*2)+"%");
 48     game->setGradeUpCoefficient((float)ui->horizontalSlider->value()/100);
 49 
 50     if     (20 > value) ui->label_showDifficult->setText("简单");
 51     else if(40 > value) ui->label_showDifficult->setText("正常");
 52     else if(60 > value) ui->label_showDifficult->setText("困难");
 53     else if(80 > value) ui->label_showDifficult->setText("地狱");
 54     else                ui->label_showDifficult->setText("混沌");
 55 }
 56 
 57 void MainWindow::keyPressEvent(QKeyEvent *event)
 58 {
 59     if(!game->getGameStart()) return;
 60     switch(event->key())
 61     {
 62     case Qt::Key_Up:    game->process(CMD_UP);    break;
 63     case Qt::Key_Down:  game->process(CMD_DOWN);  break;
 64     case Qt::Key_Left:  game->process(CMD_LEFT);  break;
 65     case Qt::Key_Right: game->process(CMD_RIGHT); break;
 66     }
 67     showBroad();
 68     showMessage();
 69     switch(game->judge())
 70     {
 71     case STAT_PROCESS: break;
 72     case STAT_WIN:  QMessageBox::information(NULL,"2048","大吉大利,今晚吃鸡!"); break;
 73     case STAT_LOSE: QMessageBox::information(NULL,"2048","再接再厉,永不放弃!"); break;
 74     }
 75 }
 76 
 77 void MainWindow::showMessage()
 78 {
 79     ui->label_showGrade->setText(QString::number(game->getGrade()));
 80     ui->label_showGradeBasic->setText(QString::number(game->getGradeBasic()));
 81     ui->label_showGradeUp->setText(QString::number(game->getGradeUp()));
 82     ui->label_showStep->setText(QString::number(game->getStep()));
 83 }
 84 
 85 void MainWindow::showBroad()
 86 {
 87     //第一行
 88     if(game->getData(0,0)) ui->label_00->setText(QString::number(game->getData(0,0)));
 89     else                   ui->label_00->setText(" ");
 90     if(game->getData(0,1)) ui->label_01->setText(QString::number(game->getData(0,1)));
 91     else                   ui->label_01->setText(" ");
 92     if(game->getData(0,2)) ui->label_02->setText(QString::number(game->getData(0,2)));
 93     else                   ui->label_02->setText(" ");
 94     if(game->getData(0,3)) ui->label_03->setText(QString::number(game->getData(0,3)));
 95     else                   ui->label_03->setText(" ");
 96     changeColor(ui->label_00, game->getData(0,0));
 97     changeColor(ui->label_01, game->getData(0,1));
 98     changeColor(ui->label_02, game->getData(0,2));
 99     changeColor(ui->label_03, game->getData(0,3));
100 
101     //第二行
102     if(game->getData(1,0)) ui->label_10->setText(QString::number(game->getData(1,0)));
103     else                   ui->label_10->setText(" ");
104     if(game->getData(1,1)) ui->label_11->setText(QString::number(game->getData(1,1)));
105     else                   ui->label_11->setText(" ");
106     if(game->getData(1,2)) ui->label_12->setText(QString::number(game->getData(1,2)));
107     else                   ui->label_12->setText(" ");
108     if(game->getData(1,3)) ui->label_13->setText(QString::number(game->getData(1,3)));
109     else                   ui->label_13->setText(" ");
110     changeColor(ui->label_10, game->getData(1,0));
111     changeColor(ui->label_11, game->getData(1,1));
112     changeColor(ui->label_12, game->getData(1,2));
113     changeColor(ui->label_13, game->getData(1,3));
114 
115     //第三行
116     if(game->getData(2,0)) ui->label_20->setText(QString::number(game->getData(2,0)));
117     else                   ui->label_20->setText(" ");
118     if(game->getData(2,1)) ui->label_21->setText(QString::number(game->getData(2,1)));
119     else                   ui->label_21->setText(" ");
120     if(game->getData(2,2)) ui->label_22->setText(QString::number(game->getData(2,2)));
121     else                   ui->label_22->setText(" ");
122     if(game->getData(2,3)) ui->label_23->setText(QString::number(game->getData(2,3)));
123     else                   ui->label_23->setText(" ");
124     changeColor(ui->label_20, game->getData(2,0));
125     changeColor(ui->label_21, game->getData(2,1));
126     changeColor(ui->label_22, game->getData(2,2));
127     changeColor(ui->label_23, game->getData(2,3));
128 
129     //第四行
130     if(game->getData(3,0)) ui->label_30->setText(QString::number(game->getData(3,0)));
131     else                   ui->label_30->setText(" ");
132     if(game->getData(3,1)) ui->label_31->setText(QString::number(game->getData(3,1)));
133     else                   ui->label_31->setText(" ");
134     if(game->getData(3,2)) ui->label_32->setText(QString::number(game->getData(3,2)));
135     else                   ui->label_32->setText(" ");
136     if(game->getData(3,3)) ui->label_33->setText(QString::number(game->getData(3,3)));
137     else                   ui->label_33->setText(" ");
138     changeColor(ui->label_30, game->getData(3,0));
139     changeColor(ui->label_31, game->getData(3,1));
140     changeColor(ui->label_32, game->getData(3,2));
141     changeColor(ui->label_33, game->getData(3,3));
142 }
143 
144 //改变方块的StyleSheet
145 void MainWindow::changeColor(QLabel* label, int num)
146 {
147     label->setAlignment(Qt::AlignCenter);
148     switch (num)
149     {
150     case 2:    label->setStyleSheet("background-color: rgb(238,228,218);"
151                                     "font:bold 75 30pt ""微软雅黑"""); break;
152     case 4:    label->setStyleSheet("background-color: rgb(237,224,200);"
153                                     "font:bold 75 30pt ""微软雅黑"""); break;
154     case 8:    label->setStyleSheet("background-color: rgb(242,177,121);"
155                                     "font:bold 75 30pt ""微软雅黑"""); break;
156     case 16:   label->setStyleSheet("background-color: rgb(245,150,100);"
157                                     "font:bold 75 30pt ""微软雅黑"""); break;
158     case 32:   label->setStyleSheet("background-color: rgb(245,125,95);"
159                                     "font:bold 75 30pt ""微软雅黑"""); break;
160     case 64:   label->setStyleSheet("background-color: rgb(245,95,60);"
161                                     "font:bold 75 30pt ""微软雅黑"""); break;
162     case 128:  label->setStyleSheet("background-color: rgb(237,207,114);"
163                                     "font:bold 75 25pt ""微软雅黑"""); break;
164     case 256:  label->setStyleSheet("background-color: rgb(237,204,97);"
165                                     "font:bold 75 25pt ""微软雅黑"""); break;
166     case 512:  label->setStyleSheet("background-color: rgb(237,204,97);"
167                                     "font:bold 75 25pt ""微软雅黑"""); break;
168     case 1024: label->setStyleSheet("background-color: rgb(237,204,97);"
169                                     "font:bold 75 20pt ""微软雅黑"""); break;
170     case 2048: label->setStyleSheet("background-color: rgb(237,204,97);"
171                                     "font:bold 75 20pt ""微软雅黑"""); break;
172     default:   label->setStyleSheet("background-color: rgb(238,228,218);"
173                                     "font:bold 75 40pt ""微软雅黑"""); break;
174     }
175 }
View Code
    ① 初始化所有数据,锁定检测:
    void initAll();
    ② 通过按钮开始或结束游戏,并且可随时调节游戏难度:
    void on_pushButton_start_clicked();

    void on_pushButton_close_clicked();
    void on_horizontalSlider_valueChanged(int value);
    ③ 显示界面与各类信息,根据各个方块的数值来调整游戏显示画面:
    void showMessage();

    void showBroad();
    void changeColor(QLabel* label, int num);
    ④ 检测方向键,执行成员变量game的逻辑函数:
    void keyPressEvent(QKeyEvent *event);


3、游戏逻辑:gamelogic.cpp/.h
3.1 gamelogic.h
 1 #ifndef GAMELOGIC_H
 2 #define GAMELOGIC_H
 3 
 4 #include <iostream>
 5 
 6 #define ROW 4
 7 #define COL 4
 8 
 9 enum CMD
10 {
11     CMD_UP,
12     CMD_DOWN,
13     CMD_LEFT,
14     CMD_RIGHT,
15 };
16 
17 enum STAT
18 {
19     STAT_WAIT,
20     STAT_PROCESS,
21     STAT_WIN,
22     STAT_LOSE,
23 };
24 
25 class GameLogic
26 {
27 public:
28     GameLogic();
29     bool createNum();
30     void process(int cmd);
31     int judge();
32     void initAll();
33     void calProb();
34 
35     void moveUp();
36     void moveDown();
37     void moveLeft();
38     void moveRight();
39 
40     bool getGameStart();
41     void setGameStart(bool);
42     void setGradeUpCoefficient(float);
43     int getData(int,int);
44     int getGrade();
45     int getGradeBasic();
46     int getGradeUp();
47     int getStep();
48 
49 private:
50     bool gameStart;
51     int data[4][4];
52     float grade;
53     int gradeBasic;
54     float gradeUp;
55     int step;
56     float gradeUpCoefficient;
以上是关于[Qt 5.6.2] 利用Qt实现一个难度可变的2048小游戏的主要内容,如果未能解决你的问题,请参考以下文章

Qt Widget 利用 Qt4.5 实现酷炫透明窗体

QT如何设置可变的全局变量

Qt可显示基本的图像类型,利用QImageQPxmap类可以实现图像的显示

Qt中如何利用 png 图片来实现自定义形状的窗口

Qt利用QLocalSocket和QLocalServer实现IPC

linux下qt开发难度大吗