Qt浅谈之二十五2048游戏(原始代码来自网络)
来源:互联网 发布:龙江网络农垦广电 编辑:程序博客网 时间:2024/06/05 14:20
一、简介
Qt改写2048游戏,在linux系统下找寻android的视觉效果。
二、运行图
启动运行图:三、详解
1、代码
(1)widget.h
#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <QLabel>#include <QPushButton>#include <QMessageBox>#include <QFile>#include <QtGui>#include "GameWidget.h"// 主窗口部件类class Widget : public QWidget{ Q_OBJECTpublic: // 构造&析构函数 Widget(QWidget *parent = 0); ~Widget();private: // “restart”按钮 QPushButton *restartBtn; QPushButton *closeBtn; // “score”标签 QLabel *titleLabel; QLabel *tipsLabel; QLabel *scoreLbl; // “HightScore”标签 QLabel *highScoreLbl; // 游戏部件 GameWidget *gameWidget; // 宽度和高度的缩放比例 用来使窗口部件随主窗口的尺寸改变而改变位置与尺寸 qreal ratioW, ratioH; // 记录最高分 int highScore; QPoint dragPosition; bool bPressFlag;protected: // 窗口尺寸改变触发的事件 void resizeEvent(QResizeEvent *); void keyPressEvent(QKeyEvent * event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event);public slots: // 处理分数增加信号的槽函数 void onScoreInc(int); // 处理游戏结束信号的槽函数 void onGameOver(); // 处理游戏获胜信号的槽函数 void onWin();};#endif // WIDGET_H(2)widget.cpp
#include "widget.h"Widget::Widget(QWidget *parent) : QWidget(parent, Qt::FramelessWindowHint) , bPressFlag(false){ setAutoFillBackground(true); QPalette pal = palette(); pal.setColor(QPalette::Background, QColor("#FAF8F0")); setPalette(pal); titleLabel = new QLabel(tr("2048"), this); titleLabel->setStyleSheet("color:#746D65;"); titleLabel->setFont(QFont("arial", 45, QFont::Black)); tipsLabel = new QLabel(tr("Join the numbers and get to the 2048 tile!"), this); tipsLabel->setStyleSheet("color:#B3AFA7;"); tipsLabel->setFont(QFont("arial", 10, QFont::Normal)); // 初始化最高分为0 highScore = 0; // 读取存储最高分的文件 QFile file("score.j"); if (file.open(QIODevice::ReadOnly)) { file.read((char *)&highScore, sizeof(highScore)); file.close(); } // 构造一个游戏部件对象 gameWidget = new GameWidget(this); //gameWidget->setGeometry(2, 200, 400, 400); gameWidget->setFocus(); connect(gameWidget, SIGNAL(ScoreInc(int)), this, SLOT(onScoreInc(int))); connect(gameWidget, SIGNAL(GameOver()), this, SLOT(onGameOver())); connect(gameWidget, SIGNAL(win()), this, SLOT(onWin())); // 构造一个字体对象 QFont font; font.setFamily("Arial"); font.setBold(true); font.setPixelSize(15); // 构造一个按钮对象 restartBtn = new QPushButton("New Game", this); //restartBtn->setGeometry(100, 120, 200, 50); restartBtn->setFont(font); restartBtn->setStyleSheet("QPushButton{color: white;background:#907963;border-style:flat;}"); //restartBtn->setFlat(true); restartBtn->setFocusPolicy(Qt::NoFocus); connect(restartBtn, SIGNAL(clicked()), gameWidget, SLOT(restart())); // 构造一个标签对象 highScoreLbl = new QLabel(QString("BEST\n%1").arg(highScore),this); //highScoreLbl->setGeometry(220, 30, 150, 50); highScoreLbl->setFont(font); highScoreLbl->setAlignment(Qt::AlignCenter); highScoreLbl->setStyleSheet("QLabel{color:#FFFFEE;background:#BEAD9D}"); // 构造一个标签对象 scoreLbl = new QLabel("SCORE\n0", this); //scoreLbl->setGeometry(30, 30, 150, 50); scoreLbl->setFont(font); scoreLbl->setAlignment(Qt::AlignCenter); scoreLbl->setStyleSheet("QLabel{color:#FFFFEE;background:#BEAD9D}"); closeBtn = new QPushButton("x", this); closeBtn->setFocusPolicy(Qt::NoFocus); closeBtn->setFont(QFont("Arial", 11, QFont::Normal)); closeBtn->setStyleSheet("QPushButton{border-style:flat;color:#BDAD9F}" "QPushButton:hover{border-style:flat;color:#FF0000}"); closeBtn->setCursor(Qt::PointingHandCursor); closeBtn->setGeometry(400 - 18, 3, 15, 15); connect(closeBtn, SIGNAL(clicked()), this, SLOT(close())); // 重置窗口大小 resize(400, 510); move((QApplication::desktop()->width() - width())/2, (QApplication::desktop()->height() - height())/2);}Widget::~Widget(){ // 释放相关对象 delete restartBtn; delete scoreLbl; delete highScoreLbl; delete gameWidget;}void Widget::onScoreInc(int score){ // 更新分数显示 scoreLbl->setText(QString("Score:\n %1").arg(score)); // 如果当前分数高于最高分 if (score > highScore) { // 更新最高分 highScore = score; highScoreLbl->setText(QString("BEST:\n %1").arg(highScore)); // 将新的最高分存入文件 QFile file("score.j"); file.open(QIODevice::WriteOnly); file.write((char *)&highScore, sizeof(highScore)); file.close(); }}void Widget::onGameOver(){ QMessageBox::information(this, "GameOver", "You lost !");}void Widget::onWin(){ QMessageBox::information(this, "Congratulation", "You win !");}void Widget::resizeEvent(QResizeEvent *){ // 计算宽度和高度的缩放比例 ratioW = width() / 400.0f; ratioH = height() / 510.0f; // 重置子部件大小和位置 titleLabel->setGeometry(20 * ratioW, 40 * ratioH , 130 * ratioW, 50 * ratioH); tipsLabel->setGeometry(20 * ratioW, 100 * ratioH , 300 * ratioW, 20 * ratioH); gameWidget->setGeometry(18 * ratioW, 140 * ratioH, 365 * ratioW, 365 * ratioH); restartBtn->setGeometry(280 * ratioW, 90 * ratioH, 100 * ratioW, 30 * ratioH); highScoreLbl->setGeometry(300 * ratioW, 40 * ratioH, 80 * ratioW, 40 * ratioH); scoreLbl->setGeometry(210 * ratioW, 40 * ratioH, 80 * ratioW, 40 * ratioH);}void Widget::keyPressEvent(QKeyEvent *event){ gameWidget->setFocus(); QWidget::keyPressEvent(event);}void Widget::mousePressEvent ( QMouseEvent * event){ bPressFlag = true; dragPosition = event->pos(); QWidget::mousePressEvent(event);}void Widget::mouseMoveEvent(QMouseEvent *event){ if (bPressFlag) { QPoint relaPos(QCursor::pos() - dragPosition); move(relaPos); } QWidget::mouseMoveEvent(event);}void Widget::mouseReleaseEvent(QMouseEvent *event){ bPressFlag = false; QWidget::mouseReleaseEvent(event);}(3)GameWidget.h
#ifndef GAMEWIDGET_H#define GAMEWIDGET_H#include <QWidget>#include <QMouseEvent>#include <QEventLoop>#include <QTimer>#include <QPainter>#include <QList>// 手势的方向enum GestureDirect{ LEFT = 0, // 向左 RIGHT = 1, // 向右 UP = 2, // 向上 DOWN = 3 // 向下};// 定义动画的类型enum AnimationType{ MOVE = 0, // 方格移动动画 APPEARANCE = 1 // 方格出现动画};// 动画结构体struct Animation{ AnimationType type; // 动画类型 GestureDirect direct; // 方向 QPointF startPos; // 起始点坐标 出现动画仅仅使用这个坐标 QPointF endPos; // 终止点坐标 移动动画的终点坐标 int digit; // 数码 int digit2; // 第二数码 数码可能被合并};// 游戏部件类 继承自QWidgetclass GameWidget : public QWidget{ Q_OBJECTpublic: // 构造函数 explicit GameWidget(QWidget *parent = 0);protected: void keyPressEvent(QKeyEvent * event);private: // 游戏面板 存储每个格子的数值 int board[4][4]; // 数码的个数 存储当前面板上的数字的个数 int digitCount; // 分数 存储当前得分 int score; // 起始点坐标 存储手势起点坐标 QPoint startPos; // 存储所有需要展现的动画 QList<Animation> animationList; // 小格子的宽度和高度 qreal w, h; // 缓存图像 QImage *cacheImg; // 是否在播放动画效果 bool isAnimating; // 检测游戏是否结束 bool checkGameOver(); // 检测游戏是否获胜 bool checkWin(); /* 获取一个数字的二进制位数 当然这里获取的不完全是二进制位数 而是对应颜色数组的下标 比如 2 对应 0 8 对应 2*/ int getBitCount(int); // 绘制动画效果 bool playAnimation(Animation&, QPainter&); // 鼠标按下触发的事件 void mousePressEvent(QMouseEvent *); // 鼠标释放触发的时间 void mouseReleaseEvent(QMouseEvent *); // 绘制事件 void paintEvent(QPaintEvent *); // 以下为一些信号signals: // 手势移动信号 void GestureMove(GestureDirect); // 分数增加信号 void ScoreInc(int); // 游戏结束信号 void GameOver(); // 游戏获胜信号 void win(); // 以下为一些槽函数public slots: // 处理手势移动信号的槽函数 void onGestureMove(GestureDirect); // 重新开始的槽函数 void restart();};#endif // GAMEWIDGET_H(4)GameWidget.cpp
#include <QDebug>#include "GameWidget.h"// 颜色数组 存储每个数字对应的背景色QColor digitBkg[11] = {QColor::fromRgb(0xEE, 0xE5, 0xDB), QColor::fromRgb(0xEC, 0xE0, 0xC8), QColor::fromRgb(0xF2, 0xAF, 0x78), QColor::fromRgb(0xEE, 0x8A, 0x54), QColor::fromRgb(0xFE, 0x76, 0x5E), QColor::fromRgb(0xE7, 0x58, 0xC), QColor::fromRgb(0xFF, 0x66, 0x66), QColor::fromRgb(0xF1, 0xCF, 0x48), QColor::fromRgb(0xCC, 0x33, 0x33), QColor::fromRgb(0xE3, 0xB9, 0x11), QColor::fromRgb(0xFF, 0x00, 0x00)};// 每个方向位置的增量QPointF dPos[5] = {QPointF(-10, 0), QPointF(10, 0), QPointF(0, -10), QPointF(0, 10), QPointF(-2, -2)};GameWidget::GameWidget(QWidget *parent) : QWidget(parent){ // 连接手势移动信号和相应的槽函数 connect(this, SIGNAL(GestureMove(GestureDirect)), SLOT(onGestureMove(GestureDirect))); // 初始化board数组 memset(board, 0, sizeof(board)); // 随机填入两个2 board[rand() % 4][rand() % 4] = 2; while(true) { int x = rand() % 4; int y = rand() % 4; if (board[x][y] != 0) { continue; } else { board[x][y] = 2; break; } } // 分数初始化为0 score = 0; // 数码个数初始化为2 digitCount = 2; isAnimating = false; cacheImg = NULL;}void GameWidget::keyPressEvent(QKeyEvent *event){ if (isAnimating) return; switch (event->key()) { case Qt::Key_Left: emit GestureMove(LEFT); break; case Qt::Key_Right: emit GestureMove(RIGHT); break; case Qt::Key_Down: emit GestureMove(DOWN); break; case Qt::Key_Up: emit GestureMove(UP); break; default: break; } QWidget::keyPressEvent(event);}void GameWidget::mousePressEvent(QMouseEvent *e){ // 获取起点坐标 startPos = e->pos();}void GameWidget::mouseReleaseEvent(QMouseEvent *e){ // 如果在播放动画效果则直接退出防止重复产生手势事件 if (isAnimating) return; // 根据终点坐标和起点坐标计算XY坐标的增量 float dX = (float)(e->pos().x() - startPos.x()); float dY = (float)(e->pos().y() - startPos.y()); // 确定手势方向 if (abs(dX) > abs(dY)) { if (dX < 0) emit GestureMove(LEFT); else emit GestureMove(RIGHT); } else { if (dY < 0) emit GestureMove(UP); else emit GestureMove(DOWN); }}void GameWidget::onGestureMove(GestureDirect direct){ int i, j, k; Animation a; // 是否合并过方格 bool combine = false; // 处理不同方向 switch (direct) { // 向左 case LEFT: // 循环每一行 for (i = 0; i < 4; i++) { /* 初始化j k为0 * 这里j表示要交换的数字列号 * k表示交换到的位置的列号 * */ j = 0, k = 0, combine = false; while (true) { // 循环找到第一个不是0的数字对应的列号 while (j < 4 && board[i][j] == 0) j++; // 如果超过了3则说明搜索完毕 推出循环 if (j > 3) break; // 交换两个数字 qSwap(board[i][k], board[i][j]); // 记录动画信息 a.type = MOVE; a.startPos = QPointF(7 + (w + 5) * j, 7 + (h + 5) * i); a.endPos = QPointF(7 + (w + 5) * k, 7 + (h + 5) * i); a.digit = a.digit2 = board[i][k]; a.direct = LEFT; //如果交换后的数字与其前一列的数字相同 if (!combine && k > 0 && board[i][k] == board[i][k - 1]) { // 前一列的数字*2 board[i][k - 1] <<= 1; // 这一列的数字置为0 board[i][k] = 0; // 记录动画信息 a.digit2 = board[i][k - 1]; a.endPos = QPointF(7 + (w + 5) * (k - 1), 7 + (h + 5) * i); // 增加分数 score += board[i][k - 1]; // 发射增加分数的信号 emit ScoreInc(score); // 数码个数-1 digitCount--; combine = true; } else k++; j++; // 添加到动画链表 animationList.append(a); } } break; // 其余三个方向与左向类似 case RIGHT: for (i = 0; i < 4; i++) { j = 3, k = 3, combine = false; while (true) { while (j > -1 && board[i][j] == 0) j--; if (j < 0) break; qSwap(board[i][k], board[i][j]); a.type = MOVE; a.startPos = QPointF(7 + (w + 5) * j, 7 + (h + 5) * i); a.endPos = QPointF(7 + (w + 5) * k, 7 + (h + 5) * i); a.digit = a.digit2 = board[i][k]; a.direct = RIGHT; if (!combine && k < 3 && board[i][k] == board[i][k + 1]) { board[i][k + 1] <<= 1; board[i][k] = 0; a.digit2 = board[i][k + 1]; a.endPos = QPointF(7 + (w + 5) * (k + 1), 7 + (h + 5) * i); score += board[i][k + 1]; emit ScoreInc(score); digitCount--; combine = true; } else k--; j--; animationList.append(a); } } break; case UP: for (i = 0; i < 4; i++) { j = 0, k = 0, combine = false; while (true) { while (j < 4 && board[j][i] == 0) j++; if (j > 3) break; qSwap(board[k][i], board[j][i]); a.type = MOVE; a.startPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * j); a.endPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * k); a.digit = a.digit2 = board[k][i]; a.direct = UP; if (!combine && k > 0 && board[k][i] == board[k - 1][i]) { board[k - 1][i] <<= 1; board[k][i] = 0; a.digit2 = board[k - 1][i]; a.endPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * (k - 1)); score += board[k - 1][i]; emit ScoreInc(score); digitCount--; combine = true; } else k++; j++; animationList.append(a); } } break; case DOWN: for (i = 0; i < 4; i++) { j = 3, k = 3, combine = false; while (true) { while (j > -1 && board[j][i] == 0) j--; if (j < 0) break; qSwap(board[k][i], board[j][i]); a.type = MOVE; a.startPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * j); a.endPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * k); a.digit = a.digit2 = board[k][i]; a.direct = DOWN; if (!combine && k < 3 && board[k][i] == board[k + 1][i]) { board[k + 1][i] <<= 1; board[k][i] = 0; a.digit2 = board[k + 1][i]; a.endPos = QPointF(7 + (w + 5) * i, 7 + (h + 5) * (k + 1)); score += board[k + 1][i]; emit ScoreInc(score); digitCount--; combine = true; } else k--; j--; animationList.append(a); } } break; } bool flag_move = false; for(int index = 0; index < animationList.size(); index++) { if (animationList.at(index).startPos != animationList.at(index).endPos) { flag_move = true; break; } } // 如果数字木有填满 if (digitCount != 16 && flag_move) { // 随机产生行号和列号 i = rand() % 4, j = rand() % 4; // 循环直到行和列对应的元素为0 while (board[i][j] != 0) i = rand() % 4, j = rand() % 4; // 填入2 //board[i][j] = (rand() % 2 + 1) * 2; board[i][j] = 2; // 记录动画信息 a.type = APPEARANCE; a.startPos = a.endPos = QPointF(7 + (w + 5) * j, 7 + (h + 5) * i); a.startPos += QPointF(w / 2, h / 2); a.digit = board[i][j]; // 数码个数加一 digitCount++; } else { // 如果数字填满了 检测游戏是否over if (checkGameOver()) emit GameOver();// 如果游戏over了则发射GameOver信号 } // 开始绘制动画效果 isAnimating = true; // 动画列表的迭代器 QList<Animation>::iterator it; // 事件循环 用于延时 QEventLoop eventLoop; // 删除之前的缓存图像 if (cacheImg) delete cacheImg; // 建立缓存图像 cacheImg = new QImage(width(), height(), QImage::Format_ARGB32); // 清空图像 cacheImg->fill(0); // 构造一个QPainter对象 QPainter painter(cacheImg); // 字体 QFont font; font.setFamily("Consolas"); font.setBold(true); font.setPixelSize(40); painter.setFont(font); // 标识所有方格动画是否都播放完毕 bool ok = false; while (true) { // 构造一个画刷 颜色为R G B分量分别为141 121 81的颜色 QBrush brush(QColor::fromRgb(141, 121, 81)); // 使painter应用这个画刷 painter.setBrush(brush); // 设置画笔为空笔 目的是使绘制的图形没有描边 painter.setPen(Qt::NoPen); // 绘制一个矩形 painter.drawRect(2, 2, width() - 4, height() - 4); // 设置画刷颜色为 RGB分量为171 165 141的颜色 brush.setColor(QColor::fromRgb(171, 165, 141)); // 应用这个画刷 painter.setBrush(brush); // 循环绘制游戏面板 for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) // 绘制小方格 painter.drawRect(QRectF(7 + (w + 5) * j, 7 + (h + 5) * i, w, h)); // 假设都播放完毕 ok = true; // 循环播放每个方格动画 for (it = animationList.begin(); it != animationList.end(); it++) if (!playAnimation(*it, painter)) ok = false; // 刷新部件 update(); // 全部播放完则退出 if (ok) break; // 延时5ms QTimer::singleShot(5, &eventLoop, SLOT(quit())); eventLoop.exec(); } // 播放方格出现的动画 while (!playAnimation(a, painter)) { update(); QTimer::singleShot(5, &eventLoop, SLOT(quit())); eventLoop.exec(); } //清除所有动画 animationList.clear(); //刷新当前部件 isAnimating = false; // 检测游戏是否获胜 if (checkWin()) emit win();// 如果获胜则发射win信号 update();}bool GameWidget::playAnimation(Animation& a, QPainter& painter){ bool rtn = false; QBrush brush(Qt::SolidPattern); // 移动方格位置 if (a.type == MOVE) { switch (a.direct) { case LEFT: if (a.startPos.x() > a.endPos.x()) a.startPos += dPos[LEFT]; else a.startPos = a.endPos, rtn = true; break; case RIGHT: if (a.startPos.x() < a.endPos.x()) a.startPos += dPos[RIGHT]; else a.startPos = a.endPos, rtn = true; break; case UP: if (a.startPos.y() > a.endPos.y()) a.startPos += dPos[UP]; else a.startPos = a.endPos, rtn = true; break; case DOWN: if (a.startPos.y() < a.endPos.y()) a.startPos += dPos[DOWN]; else a.startPos = a.endPos, rtn = true; } // 如果方格移动到终点 if (!rtn) { brush.setColor(digitBkg[getBitCount(a.digit)]); painter.setBrush(brush); painter.drawRect(QRectF(a.startPos.x(), a.startPos.y(), w, h)); painter.setPen(QColor::fromRgb(0, 0, 0)); painter.drawText(QRectF(a.startPos.x(), a.startPos.y(), w, h), Qt::AlignCenter, QString::number(a.digit)); } else { brush.setColor(digitBkg[getBitCount(a.digit2)]); painter.setBrush(brush); painter.drawRect(QRectF(a.startPos.x(), a.startPos.y(), w, h)); painter.setPen(QColor::fromRgb(0, 0, 0)); painter.drawText(QRectF(a.startPos.x(), a.startPos.y(), w, h), Qt::AlignCenter, QString::number(a.digit2)); } painter.setPen(Qt::NoPen); } else { // 方格出现的动画效果 if (a.startPos.x() > a.endPos.x()) a.startPos += dPos[4]; else a.startPos = a.endPos, rtn = true; brush.setColor(digitBkg[getBitCount(a.digit)]); painter.setBrush(brush); painter.drawRect(QRectF(a.startPos.x(), a.startPos.y(), w - 2 * (a.startPos.x() - a.endPos.x()), h - 2 * (a.startPos.y() - a.endPos.y()))); painter.setPen(QColor::fromRgb(0, 0, 0)); painter.drawText(QRectF(a.endPos.x(), a.endPos.y(), w, h), Qt::AlignCenter, QString::number(a.digit)); painter.setPen(Qt::NoPen); } return rtn;}void GameWidget::paintEvent(QPaintEvent *){ // 构造一个QPainter对象 使用它来进行绘图 QPainter painter(this); // 如果正在播放动画效果则绘制缓存位图 if (isAnimating) { painter.drawImage(0, 0, *cacheImg); return; } // 构造一个画刷 颜色为R G B分量分别为141 121 81的颜色 QBrush brush(QColor::fromRgb(141, 121, 81)); // 使painter应用这个画刷 painter.setBrush(brush); // 设置画笔为空笔 目的是使绘制的图形没有描边 painter.setPen(Qt::NoPen); // 绘制一个矩形 painter.drawRect(2, 2, width() - 4, height() - 4); // 计算每个小格子的宽度和高度 w = width() - 4, h = height() - 4; w = (w - 25) / 4, h = (h - 25) / 4; /* 构造一个字体 * 字体名字为Consolas * 字体设置为粗体 * 字体大小为40像素 * */ QFont font; font.setFamily("Consolas"); font.setBold(true); font.setPixelSize(40); // 使painter应用这个字体 painter.setFont(font); // 循环绘制游戏面板 for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { // 如果方格中有数字 if (board[i][j]) { // 设置画刷颜色为数码对应的颜色 brush.setColor(digitBkg[getBitCount(board[i][j])]); // 应用这个画刷 painter.setBrush(brush); // 绘制一个小方格 painter.drawRect(QRectF(7 + (w + 5) * j, 7 + (h + 5) * i, w, h)); // 设置画笔为黑色画笔 painter.setPen(QColor::fromRgb(0, 0, 0)); // 绘制数码 painter.drawText(QRectF(7 + (w + 5) * j, 7 + (h + 5) * i, w, h), Qt::AlignCenter, QString::number(board[i][j])); // 设置画笔为空笔 painter.setPen(Qt::NoPen); } // 如果方格中没有数字 else { // 设置画刷颜色为 RGB分量为171 165 141的颜色 brush.setColor(QColor::fromRgb(171, 165, 141)); // 应用这个画刷 painter.setBrush(brush); // 绘制小方格 painter.drawRect(QRectF(7 + (w + 5) * j, 7 + (h + 5) * i, w, h)); } }}void GameWidget::restart(){ // 初始化相关变量 同构造函数 score = 0; digitCount = 2; memset(board, 0, sizeof(board)); board[rand() % 4][rand() % 4] = 2; while(true) { int x = rand() % 4; int y = rand() % 4; if (board[x][y] != 0) { continue; } else { board[x][y] = 2; break; } } emit ScoreInc(score); update();}bool GameWidget::checkGameOver(){ // 循环检测是否含有相邻的相同数码 for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { if (j != 3 && board[i][j] == board[i][j + 1]) return false; if (i != 3 && board[i][j] == board[i + 1][j]) return false; } return true;}bool GameWidget::checkWin(){ // 循环检测是否某个方格的数字为2048 for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) if (board[i][j] == 2048) return true; return false;}int GameWidget::getBitCount(int n){ // 循环获取数字二进制位数 int c = 0; while (n >>= 1) c++; // 返回位数-1 return c - 1;}(5)main.cpp
#include "widget.h"#include <QApplication>int main(int argc, char *argv[]){ QApplication a(argc, argv); Widget w; w.show(); return a.exec();}
2、运行
四、总结
(1)代码有很些不足,比如一行中有4个相同的数只有相加前2个、开始新游戏没有动画等。(2)可以参考其他的2048的代码进行修改更新,此源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/8660527)。
(3)若有建议,请留言,在此先感谢!
0 0
- Qt浅谈之二十五2048游戏(原始代码来自网络)
- Qt浅谈之四十九俄罗斯方块(代码来自网络)
- Qt浅谈之十五:键盘控制移动
- Qt浅谈之十五:键盘控制移动
- unity3D游戏开发十五之NGUI二
- unity3D游戏开发十五之NGUI二
- unity3D游戏开发十五之NGUI二
- Qt浅谈之二十九Qt多线程
- Qt浅谈之十六:TCP和UDP(之二)
- QT分析之网络编程(二)
- QT分析之网络编程(二)
- Qt之QSS(Q_PROPERTY-原始属性)
- Qt浅谈之窗体缩放(仅增加测试代码)
- Qt浅谈之窗体缩放(仅增加测试代码)
- Qt网络编程之二
- Qt网络编程之二
- Qt浅谈之二:钟表(时分秒针)
- QT开发(二十五)——QT模板库
- Cocos2d-x 3.x利用Socket创建客户端和服务端
- Codeforce 487B Strip 动归+二分+线段树
- Java调用.NetWeb Service
- (HttpClient技术)(58同城系列)58同城登录加密的js
- test指令的测试功能
- Qt浅谈之二十五2048游戏(原始代码来自网络)
- poj1611(带权并查集)
- ios view的frame和bounds之区别(位置和大小)
- rabbitmq(一)Hello world
- Xms Xmx PermSize MaxPermSize 区别
- 面试题63:二叉搜索树的第K个结点
- Error, some other host already uses address 22.22.22.2.
- Ant: for/foreach
- 从PLSQL从导出的CVS文件如何转化成XLS文件