[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 }
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 }
① 初始化所有数据,锁定检测:
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可显示基本的图像类型,利用QImageQPxmap类可以实现图像的显示