一、游戏演示
手机上经典的1024游戏,通过Qt实现了电脑版本,先看效果:
二、说明
- 布局和配色借鉴了手机游戏;
- 通过上下左右按键的操作,控制数字的移动;
- 在移动过程中相同的数学会自动合并,变成更大的数字。
三、主要代码
界面布局:
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_DD1024.h"
class QGraphicsScene;
class QGraphicsView;
class QKeyEvent;
class RandomPos;
class AutoMoveItem;
class DD1024 : public QMainWindow {
Q_OBJECT
public:
DD1024(QWidget *parent = Q_NULLPTR);
private:
void init();
private:
void keyPressEvent(QKeyEvent *e)override;
private slots:
void slotStart();
private:
Ui::DD1024Class ui;
QGraphicsScene* _mainScene = nullptr;
QGraphicsView* _mainView = nullptr;
QColor _bkColor = QColor(187, 173, 160);
RandomPos* _randomPos = nullptr;
AutoMoveItem* _autoMoveItem = nullptr;
};
#include "DD1024.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QMessageBox>
#include <QKeyEvent>
#include "DD1024Def.h"
#include "QGraphicsRoundRectItem.h"
#include "RandomPos.h"
#include "AutoMoveItem.h"
DD1024::DD1024(QWidget *parent)
: QMainWindow(parent) {
ui.setupUi(this);
this->grabKeyboard(); //使其具有捕获键盘事件的能力
init();
}
void DD1024::init() {
if (_mainScene == nullptr) {
_mainScene = new QGraphicsScene;
_mainScene->setSceneRect(0, 0, BOX_LENGTH * 4 + BOX_INTERVAL * 5, BOX_LENGTH * 4 + BOX_INTERVAL * 5);
_randomPos = new RandomPos;
_autoMoveItem = new AutoMoveItem;
for (int row = 0;row < 4;row ++){
for (int col = 0; col < 4; col++) {
QGraphicsRoundRectItem*item = new QGraphicsRoundRectItem(row, col, 0);
_mainScene->addItem(item);
_randomPos->appendAllItem(item);
_autoMoveItem->appendAllItem(row, col, item);
}
}
}
if (_mainView == nullptr) {
_mainView = new QGraphicsView;
_mainView->setBackgroundBrush(_bkColor);
_mainView->setRenderHint(QPainter::Antialiasing);
_mainView->setScene(_mainScene);
}
ui.verticalLayoutMain->addWidget(_mainView);
connect(ui.pushButtonStart, SIGNAL(clicked()), this, SLOT(slotStart()));
}
void DD1024::keyPressEvent(QKeyEvent *e) {
if (e->key() == Qt::Key_Left) {//左
_autoMoveItem->moveLeft();
} else if (e->key() == Qt::Key_Right) {//右
_autoMoveItem->moveRight();
} else if (e->key() == Qt::Key_Up) {//上
_autoMoveItem->moveUp();
} else if (e->key() == Qt::Key_Down) {//下
_autoMoveItem->moveDown();
}
if (!_randomPos->setOnlyItemNumber()) {//数据全部填满
if (_autoMoveItem->isGameFinish()) {//游戏结束
QMessageBox::information(nullptr, QStringLiteral("提示"), QStringLiteral("游戏结束!"), QMessageBox::Yes);
}
}
_mainScene->update();
QWidget::keyPressEvent(e);
}
void DD1024::slotStart() {
_randomPos->setOnlyItemNumber();
_randomPos->setOnlyItemNumber();
_mainScene->update();
}
方块类:
#pragma once
#include <QObject>
#include <QColor>
#include <QRectF>
#include <QGraphicsItem>
class QTimer;
class QGraphicsRoundRectItem
:public QObject
, public QGraphicsItem {
Q_OBJECT
public:
QGraphicsRoundRectItem(QGraphicsItem *parent = nullptr);
QGraphicsRoundRectItem(int row, int col, int number, QGraphicsItem *parent = nullptr);
~QGraphicsRoundRectItem();
void setNumber(int num);
int&getNumber() {
return _number;
}
//动画显示出来
void animationShow();
private:
void setRowCol(int r, int c, int number);
//绘图区域
QRectF boundingRect() const;
//绘制按钮图像的函数
void paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget = 0)override;
private slots:
void slotShowRect();
protected:
QColor _rectColor = QColor(199, 189, 179);//背景颜色
int _fontAlpha = 255;
QColor _fontColor = QColor(0, 0, 0);//字体颜色
int _fontSize = 40;//字体大小
int _row = 0;
int _col = 0;
QRectF _rect;
int _number = 0;//当前值
QTimer* _timerShow = nullptr;
};
#include <QPainter>
#include <QPen>
#include <QTimer>
#include "QGraphicsRoundRectItem.h"
#include "DD1024Def.h"
QGraphicsRoundRectItem::QGraphicsRoundRectItem(QGraphicsItem *parent)
: QGraphicsItem(parent) {
_timerShow = new QTimer;
_timerShow->setInterval(50);
connect(_timerShow, SIGNAL(timeout()), this, SLOT(slotShowRect()));
}
QGraphicsRoundRectItem::QGraphicsRoundRectItem(int row, int col, int number, QGraphicsItem *parent /*= nullptr*/) {
setRowCol(row, col, number);
_timerShow = new QTimer;
_timerShow->setInterval(50);
connect(_timerShow, SIGNAL(timeout()), this, SLOT(slotShowRect()));
}
QGraphicsRoundRectItem::~QGraphicsRoundRectItem() {
}
void QGraphicsRoundRectItem::setNumber(int num) {
_number = num;
switch (_number) {
case 0:
case 2:
_rectColor = QColor(227, 219, 208);
_fontColor = QColor(0, 0, 0);
_fontSize = 40;
break;
case 4:
_rectColor = QColor(227, 216, 196);
_fontColor = QColor(0, 0, 0);
_fontSize = 40;
break;
case 8:
_rectColor = QColor(231, 180, 135);
_fontColor = QColor(255, 255, 255);
_fontSize = 40;
break;
case 16:
_rectColor = QColor(245, 149, 99);
_fontColor = QColor(255, 255, 255);
_fontSize = 40;
break;
case 32:
_rectColor = QColor(245, 124, 95);
_fontColor = QColor(255, 255, 255);
_fontSize = 40;
break;
case 64:
_rectColor = QColor(246, 93, 59);
_fontColor = QColor(255, 255, 255);
_fontSize = 40;
break;
case 128:
_rectColor = QColor(237, 206, 113);
_fontColor = QColor(255, 255, 255);
_fontSize = 36;
break;
case 256:
_rectColor = QColor(237, 204, 97);
_fontColor = QColor(255, 255, 255);
_fontSize = 36;
break;
case 512:
_rectColor = QColor(236, 200, 80);
_fontColor = QColor(255, 255, 255);
_fontSize = 36;
break;
case 1024:
_rectColor = QColor(237, 197, 63);
_fontColor = QColor(255, 255, 255);
_fontSize = 28;
break;
case 2048:
_rectColor = QColor(238, 194, 46);
_fontColor = QColor(255, 255, 255);
_fontSize = 28;
break;
case 4096:
_rectColor = QColor(237, 113, 207);
_fontColor = QColor(255, 255, 255);
_fontSize = 28;
break;
case 8192:
_rectColor = QColor(237, 97, 204);
_fontColor = QColor(255, 255, 255);
_fontSize = 28;
break;
case 16384:
_rectColor = QColor(238, 80, 201);
_fontSize = 22;
break;
case 32768:
_rectColor = QColor(237, 63, 197);
_fontColor = QColor(255, 255, 255);
_fontSize = 22;
break;
case 65536:
_rectColor = QColor(236, 46, 194);
_fontColor = QColor(255, 255, 255);
_fontSize = 22;
break;
case 131072:
_rectColor = QColor(236, 46, 194);
_fontColor = QColor(255, 255, 255);
_fontSize = 18;
break;
default:
break;
}
}
void QGraphicsRoundRectItem::animationShow() {
if (_timerShow->isActive()){
_timerShow->stop();
}
_fontAlpha = 0;
_timerShow->start();
}
void QGraphicsRoundRectItem::setRowCol(int r, int c, int number) {
_row = r;
_col = c;
_rect.setTop((_row + 1)*BOX_INTERVAL + _row * BOX_LENGTH);
_rect.setLeft((_col + 1)*BOX_INTERVAL + _col * BOX_LENGTH);
_rect.setWidth(BOX_LENGTH);
_rect.setHeight(BOX_LENGTH);
setNumber(number);
}
QRectF QGraphicsRoundRectItem::boundingRect() const {
return _rect;
}
void QGraphicsRoundRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget /*= 0*/) {
painter->setPen(Qt::NoPen);
painter->setBrush(QBrush(_rectColor));
painter->drawRoundRect(_rect, ROUND_RADIUS, ROUND_RADIUS);
if (_number != 0){
_fontColor.setAlpha(_fontAlpha);
QPen pen(_fontColor);
QFont font(QStringLiteral("宋体"), _fontSize, QFont::Bold);
QString text = QString::number(_number);
painter->setPen(pen);
painter->setFont(font);
painter->drawText(_rect, Qt::AlignCenter, text);
}
}
void QGraphicsRoundRectItem::slotShowRect() {
_fontAlpha += 20;
if (_fontAlpha > 255){
_timerShow->stop();
}
update();
}
资源下载
aaa