Qt5.10编写俄罗斯方块

news/2025/2/11 1:05:41/

一、先看效果图

在这里插入图片描述

二、主要的设计思路:

1.采用Qt的QGraphicsScene、QGraphicsScene、QGraphicsItem实现界面的绘制;
2.对每一种类型的方块单独设计一个类,所有类型的方块都是继承自同一基类;
3.采用Qt的随机数生产机制,随机的生产每一种类型的方块;
4.使用SQLite数据库记录历史的最高值;
5.使用方向按键表示变形和移动方块;
6.主绘图界面和下一个方块的提示界面,分别使用不同的类来表示。

三、主要类

1.不同类型的方块基类:

#pragma once
#include "../TetrisDef.h"
//俄罗斯方块的基类
#include "SubBlock.h"class QPoint;class BaseBlock {
public:BaseBlock(BlockType blockType);~BaseBlock();BlockType&getBlockType() {return _blockType;}virtual QColor getBlockColor() {return QColor(0, 0, 0);}virtual QPixmap getPixmap();//获取每种类型方块的初始形式virtual void getHeadFirstPattern(QPoint* currentBlock);//方块变形下一个样式virtual QPoint* getNextPattern();virtual void nextPatternEfficient(bool b);//当前生成的样式是否有效
protected:QPixmap _pixmap;BlockType _blockType = ERROR_BLOCK;//方块类型bool** _blockPattern;//方块样式 指的实际的行列位置,而不是实际的像素位置int _changeID = 0;//变化样式QPoint* _changeFormula = nullptr;//行列的变化公式
};
#include "BaseBlock.h"BaseBlock::BaseBlock(BlockType blockType) {_blockType = blockType;_blockPattern = new bool*[4];for (int i = 0;i< 4;i++){_blockPattern[i] = new bool[4];for (int j = 0; j < 4; j++) {_blockPattern[i][j] = false;}}_changeFormula = new QPoint[4];
}BaseBlock::~BaseBlock() {
}QPixmap BaseBlock::getPixmap() {QImage image(QString(":/Tetris/Res/I.png"));_pixmap = QPixmap::fromImage(image);return _pixmap;
}void BaseBlock::getHeadFirstPattern(QPoint* currentBlock) {}QPoint* BaseBlock::getNextPattern() {return _changeFormula;
}void BaseBlock::nextPatternEfficient(bool b) {if (!b){//没有生效_changeID--;}
}

2.方块工厂类:

#pragma once
#include "../TetrisDef.h"//方块的生产工厂
class BaseBlock;class BlockFactory {
public:BlockFactory();~BlockFactory();BaseBlock* createBlock(BlockType type);
};
#include "BlockFactory.h"
#include "BaseBlock.h"
#include "IBlock.h"
#include "JBlock.h"
#include "LBlock.h"
#include "OBlock.h"
#include "SBlock.h"
#include "TBlock.h"
#include "ZBlock.h"BlockFactory::BlockFactory() {
}BlockFactory::~BlockFactory() {
}BaseBlock* BlockFactory::createBlock(BlockType type) {BaseBlock* block = nullptr;switch (type){case I_BLOCK:block = new IBlock;break;case J_BLOCK:block = new JBlock;break;case L_BLOCK:block = new LBlock;break;case O_BLOCK:block = new OBlock;break;case S_BLOCK:block = new SBlock;break;case Z_BLOCK:block = new ZBlock;break;case T_BLOCK:block = new TBlock;break;default:break;}return block;
}

3.主要的类型的方块:

T行方块:

#pragma once
#include "BaseBlock.h"
class TBlock :public BaseBlock {
public:TBlock();~TBlock();QColor getBlockColor()override;QPixmap getPixmap()override;void getHeadFirstPattern(QPoint* currentBlock)override;QPoint* getNextPattern()override;};
#include "TBlock.h"
#include "SubBlock.h"	TBlock::TBlock() :BaseBlock(T_BLOCK) {}TBlock::~TBlock() {
}QColor TBlock::getBlockColor() {return QColor(255, 0, 255);
}QPixmap TBlock::getPixmap() {QImage image(QString(":/Tetris/Res/T.png"));_pixmap = QPixmap::fromImage(image);return _pixmap;
}void TBlock::getHeadFirstPattern(QPoint* currentBlock) {currentBlock[0] = QPoint(0, 0);currentBlock[1] = QPoint(0, 1);currentBlock[2] = QPoint(0, 2);currentBlock[3] = QPoint(1, 1);
}QPoint* TBlock::getNextPattern() {if (_changeID % 4 == 0) {_changeFormula[0] = QPoint(0, 2);_changeFormula[1] = QPoint(1, 1);_changeFormula[2] = QPoint(2, 0);_changeFormula[3] = QPoint(0, 0);} else if (_changeID % 4 == 1) {_changeFormula[0] = QPoint(2, 0);_changeFormula[1] = QPoint(1, -1);_changeFormula[2] = QPoint(0, -2);_changeFormula[3] = QPoint(0, 0);} else if (_changeID % 4 == 2) {_changeFormula[0] = QPoint(0, -2);_changeFormula[1] = QPoint(-1, -1);_changeFormula[2] = QPoint(-2, 0);_changeFormula[3] = QPoint(0, 0);} else if (_changeID % 4 == 3) {_changeFormula[0] = QPoint(-2, 0);_changeFormula[1] = QPoint(-1, 1);_changeFormula[2] = QPoint(0, 2);_changeFormula[3] = QPoint(0, 0);}_changeID++;return _changeFormula;
}

O型方块:

#pragma once
#include "BaseBlock.h"
//O 
class OBlock :public BaseBlock {
public:OBlock();~OBlock();QColor getBlockColor()override;QPixmap getPixmap()override;void getHeadFirstPattern(QPoint* currentBlock)override;QPoint* getNextPattern()override;};
#include "OBlock.h"
#include "SubBlock.h"OBlock::OBlock() :BaseBlock(O_BLOCK){}OBlock::~OBlock() {
}QColor OBlock::getBlockColor() {return  QColor(204, 11, 16);
}QPixmap OBlock::getPixmap() {QImage image(QString(":/Tetris/Res/O.png"));_pixmap = QPixmap::fromImage(image);return _pixmap;
}void OBlock::getHeadFirstPattern(QPoint* currentBlock) {currentBlock[0] = QPoint(0, 0);currentBlock[1] = QPoint(0, 1);currentBlock[2] = QPoint(1, 0);currentBlock[3] = QPoint(1, 1);
}QPoint* OBlock::getNextPattern() {_changeFormula[0] = QPoint(0, 0);_changeFormula[1] = QPoint(0, 0);_changeFormula[2] = QPoint(0, 0);_changeFormula[3] = QPoint(0, 0);return _changeFormula;
}

4.主要运行框架

#pragma once
#include <QRect>
//主界面框架布局展示
#include "MainFrameBlock.h"
#include <QObject>
#include <QTimer>
class QGraphicsScene;
class QGraphicsView;
class BaseBlock;
class QGraphicsRectItem;
class SubBlock;
class ICurrentFinsh;
class QTimer;class MainFrameLayout :public QObject{Q_OBJECT
public:MainFrameLayout(ICurrentFinsh* currentFinish);~MainFrameLayout();void initMainGame();QGraphicsView* getMainFrameView() {return _mainView;}//设置当前正在运动的方块void setCurrentBlock(BaseBlock* block);//按照时间运行游戏void runGame();void moveLeft();void moveRight();void change();void gameOverPlay();private slots:void slotGameOverPlay();
private:void init();bool firstBlockSpaceUsage();//第一个进入主界面是否被占用bool isHitDownBlock();//向下移动是否碰到其他方块bool isHitLeftBlock();//向左移动是否碰到其他方块bool isHitRightBlock();//向右移动是否碰到其他方块bool isCurrentBlock(QPoint pos);//判断某一位置的方块是当前运动方块bool isGameOver();//是否游戏结束bool isChangeHit();//方块变化之后,时候发生了碰撞//游戏结束动画,先刷一遍其他颜色,然后在刷新一点背景色void playFirstColor();void playSecondColor();bool totalScore();//统计行数和分数
private:ICurrentFinsh* _currentFinish = nullptr;QGraphicsScene* _mainScene = nullptr;QGraphicsScene* _mainView = nullptr;MainFrameBlock _mainBlock[20][10];QColor _bkColor = Qt::lightGray;QPoint _current4Block[4], _pre4Block[4];BaseBlock* _currentBlock = nullptr;bool _tinyBlock[4][4];//新生成的四个小方块bool _changePos = false;//当改变方块形状的时候,位置就不在改变QTimer* _gameOverTimer = nullptr;int _clearRow = 0;bool _palyFirst = true;//先刷新其他色QPixmap* _firstPixmap = nullptr;QPixmap* _secondPixmap = nullptr;int _totalRows = 0;//消除的总行数int _totalScore = 0;//总分数
};
#include "MainFrameLayout.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsLineItem>
#include <set>
#include "../Block/BaseBlock.h"
#include "../Block/SubBlock.h"
#include "../ICurrentFinsh.h"MainFrameLayout::MainFrameLayout(ICurrentFinsh* currentFinish) {_currentFinish = currentFinish;init();
}MainFrameLayout::~MainFrameLayout() {}void MainFrameLayout::initMainGame() {_totalRows = 0;//消除的总行数_totalScore = 0;//总分数//初始化界面for (int i=0;i< 20;i++){for (int j = 0; j < 10; j++) {_mainBlock[i][j].setUse(false);_mainBlock[i][j].setColor(_bkColor);_mainBlock[i][j].setPixmap(QPixmap());}}_mainScene->update(-4, -4, 208, 408);
}void MainFrameLayout::init() {if (_mainScene == nullptr) {_mainScene = new QGraphicsScene;_mainScene->setSceneRect(0, 0, 200, 400);}if (_mainView == nullptr) {_mainView = new QGraphicsView;_mainView->setBackgroundBrush(_bkColor);_mainView->setRenderHint(QPainter::Antialiasing);_mainView->setScene(_mainScene);}for (int i = 0; i < 20; i++) {for (int j = 0; j < 10; j++) {_mainBlock[i][j].setPos(i, j);_mainBlock[i][j].setPixelPos(QPointF(j * 20, i * 20));_mainScene->addItem(&_mainBlock[i][j]);}}QPen penLine;penLine.setStyle(Qt::SolidLine);penLine.setColor(Qt::white);penLine.setWidth(2);//绘制边界QGraphicsRectItem* rect = new QGraphicsRectItem(-4, -4, 208, 408);rect->setPen(penLine);_mainScene->addItem(rect);#if 0penLine.setStyle(Qt::DotLine);penLine.setColor(Qt::yellow);//横线for (int i = 0; i <= 20; i++) {QGraphicsLineItem* hl1 = new QGraphicsLineItem(0, 20 * i, 200, 20 * i);hl1->setPen(penLine);_mainScene->addItem(hl1);}//竖线for (int i = 0; i <= 10; i++) {QGraphicsLineItem* hl1 = new QGraphicsLineItem(20 * i, 0, 20 * i, 400);hl1->setPen(penLine);_mainScene->addItem(hl1);}
#endif_gameOverTimer = new QTimer;connect(_gameOverTimer, SIGNAL(timeout()), this, SLOT(slotGameOverPlay()));_firstPixmap = new QPixmap(20, 20);_firstPixmap->fill(Qt::transparent);QPainter painter1(_firstPixmap);painter1.setPen(QColor(255, 143, 36));painter1.setBrush(QColor(53, 39, 182));painter1.drawRect(0, 0, 20, 20);_secondPixmap = new QPixmap(20, 20);_secondPixmap->fill(Qt::transparent);QPainter painter2(_secondPixmap);painter2.setPen(Qt::NoPen);painter2.setBrush(_bkColor);painter2.drawRect(0, 0, 20, 20);
}void MainFrameLayout::setCurrentBlock(BaseBlock* block) {if (block != nullptr) {block->getHeadFirstPattern(_current4Block);//生产新的方块for (int i =0;i< 4;i++){_current4Block[i] = QPoint(_current4Block[i].x(), _current4Block[i].y() + 3);//移到中间位置}//判断当前新生成的方块是已经被占用bool onTop = false;//是否到达顶格while (firstBlockSpaceUsage()) {onTop = true;for (int i = 0; i < 4; i++) {_current4Block[i] = QPoint(_current4Block[i].x() -1, _current4Block[i].y());//向上移一格}}if (onTop){//绘制出当前使用的俄罗斯方块for (size_t i = 0; i < 4; i++) {if (_current4Block[i].x() < 0) {//超出主界面的部分直接跳过continue;}_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setUse(true);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_currentBlock->getBlockColor());}_mainScene->update();_currentFinish->gameOver();//游戏结束return;}//把新的方块保存起来for (int i = 0; i < 4; i++) {_pre4Block[i] = _current4Block[i];}_currentBlock = block;}for (size_t i = 0; i < 4; i++) {_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setUse(true);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_currentBlock->getBlockColor());_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(_currentBlock->getPixmap());}_mainScene->update(-4, -4, 208, 408);
}void MainFrameLayout::runGame() {if (_changePos ){//正在改变形状,就不在移动方块return;}int row = -1, col = -1;if (isHitDownBlock()) {//已经碰到其他方块或者底部totalScore();//统计分数_currentFinish->currentFinish();//当前已经运行完,可以继续运行下一个方块return;}//去掉上一帧的痕迹for (size_t i = 0; i < 4; i++) {_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setUse(false);_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setColor(_bkColor);_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setPixmap(QPixmap());}//绘制当前帧for (size_t i = 0; i < 4; i++) {_current4Block[i] = QPoint(_current4Block[i].x() + 1, _current4Block[i].y() );_mainBlock[_current4Block[i].x() ][_current4Block[i].y()].setUse(true);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_currentBlock->getBlockColor());_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(_currentBlock->getPixmap());//保存当前帧_pre4Block[i] = _current4Block[i];}_mainScene->update();}void MainFrameLayout::moveLeft() {if (isHitLeftBlock()) {//不能再向左侧移动return;}//去掉上一帧的痕迹for (size_t i = 0; i < 4; i++) {_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setUse(false);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_bkColor);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(QPixmap());}int row = -1, col = -1;for (size_t i = 0; i < 4; i++) {row = _current4Block[i].x();col = _current4Block[i].y();col--;_current4Block[i] = QPoint(row, col);_pre4Block[i] = _current4Block[i];_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setUse(true);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_currentBlock->getBlockColor());_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(_currentBlock->getPixmap());}_mainScene->update();
}void MainFrameLayout::moveRight() {if (isHitRightBlock()){return;}//去掉上一帧的痕迹for (size_t i = 0; i < 4; i++) {_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setUse(false);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_bkColor);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(QPixmap());}int row = -1, col = -1;for (size_t i = 0; i < 4; i++) {row = _current4Block[i].x();col = _current4Block[i].y();col++;_current4Block[i] = QPoint(row, col);_pre4Block[i] = _current4Block[i];_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setUse(true);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_currentBlock->getBlockColor());_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(_currentBlock->getPixmap());}_mainScene->update();
}void MainFrameLayout::change() {_changePos = true;//开始改变形状//1.变化之前保存原来的形状for (int i = 0; i < 4; i++) {_pre4Block[i] = _current4Block[i];}//2.清除原来的形状for (size_t i = 0; i < 4; i++) {_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setUse(false);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_bkColor);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(QPixmap());}//3.产生新的形状QPoint*change = _currentBlock->getNextPattern();for (int i = 0; i < 4;i++) {_current4Block[i] += change[i];}//4.新的形状没有使用成功if (isChangeHit()){//变化是否超过了边界bool bButton = false;//变化之后是否在最低端for (int i = 0; i < 4; i++) {if (_current4Block[i].x() > 19) {//大于第19行bButton = true;}}if (bButton){//变化之后,已经超过了最低端for (size_t i = 0; i < 4; i++) {//则恢复到原来的状态_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setUse(true);_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setColor(_currentBlock->getBlockColor());_mainBlock[_pre4Block[i].x()][_pre4Block[i].y()].setPixmap(_currentBlock->getPixmap());}}for (int i = 0; i < 4; i++) {_current4Block[i] = _pre4Block[i];}//方块变形之后没有生效_currentBlock->nextPatternEfficient(false);_changePos = false;//改变形状完成return;}//5.新的形状成功使用,绘制当前帧for (size_t i = 0; i < 4; i++) {_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setUse(true);_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setColor(_currentBlock->getBlockColor());_mainBlock[_current4Block[i].x()][_current4Block[i].y()].setPixmap(_currentBlock->getPixmap());//保存变化之后的形状_pre4Block[i] = _current4Block[i];}_mainScene->update();_changePos = false;//改变形状完成
}void MainFrameLayout::gameOverPlay() {_gameOverTimer->start(50);_clearRow = 0;_palyFirst = true;
}void MainFrameLayout::slotGameOverPlay() {if (_palyFirst) {playFirstColor();} else {playSecondColor();}_mainScene->update();
}bool MainFrameLayout::firstBlockSpaceUsage() {for (int i = 0; i < 4; i++) {if (_current4Block[i].x() < 0){//超出主界面的部分直接跳过continue;}if (_mainBlock[_current4Block[i].x()][_current4Block[i].y()].getUse()//已经被占用&& isCurrentBlock(_current4Block[i])){//不是当期运行的方块)return true;}}return false;
}bool MainFrameLayout::isHitDownBlock() {//到达最底部for (size_t i = 0; i < 4; i++) {if (_current4Block[i].x() >= 19){return true;}}//是否触碰到其他方块for (size_t i = 0; i < 4; i++) {//下一块的位置QPoint downBlock = QPoint(_current4Block[i].x() + 1, _current4Block[i].y());//下一个位置不是当前四个方块中,并且已经存在方块了if (_mainBlock[downBlock.x()][downBlock.y()].getUse()&& !isCurrentBlock(downBlock)){return true;}}return false;
}bool MainFrameLayout::isHitLeftBlock() {//是否到达左部for (size_t i = 0; i < 4; i++) {int col = _current4Block[i].y();if (col == 0) {//到达左部return true;}}for (size_t i = 0; i < 4; i++) {//下一块的位置QPoint leftBlock = QPoint(_current4Block[i].x() , _current4Block[i].y() -1);//左一个位置不是当前四个方块中,并且已经存在方块了if (_mainBlock[leftBlock.x()][leftBlock.y()].getUse() && !isCurrentBlock(leftBlock)) {return true;}}return false;
}bool MainFrameLayout::isHitRightBlock() {//是否到达右部for (size_t i = 0; i < 4; i++) {int col = _current4Block[i].y();if (col == 9) {//到达右部return true;}}for (size_t i = 0; i < 4; i++) {//下一块的位置QPoint rightBlock = QPoint(_current4Block[i].x(), _current4Block[i].y() + 1);//右一个位置不是当前四个方块中,并且已经存在方块了if (_mainBlock[rightBlock.x()][rightBlock.y()].getUse() && !isCurrentBlock(rightBlock)) {return true;}}return false;
}bool MainFrameLayout::isCurrentBlock(QPoint pos) {for (size_t i = 0; i < 4; i++) {if (_current4Block[i] == pos) {return true;}}return false;
}bool MainFrameLayout::isGameOver() {return false;
}bool MainFrameLayout::isChangeHit() {//是否超出了边界for (size_t i = 0; i < 4; i++) {if (_current4Block[i].x() < 0//小于第0行|| _current4Block[i].x() > 19//大于第19行|| _current4Block[i].y() < 0//小于第0列|| _current4Block[i].y() > 9) {//大于第9列return true;}}//变化之后,是否占用了其他已经有的方格if (_mainBlock[_current4Block[0].x()][_current4Block[0].y()].getUse()|| _mainBlock[_current4Block[1].x()][_current4Block[1].y()].getUse()|| _mainBlock[_current4Block[2].x()][_current4Block[2].y()].getUse()|| _mainBlock[_current4Block[3].x()][_current4Block[3].y()].getUse()){return true;}return false;
}void MainFrameLayout::playFirstColor() {for (int j = 0; j < 10; j++) {_mainBlock[_clearRow][j].setUse(false);_mainBlock[_clearRow][j].setColor(QColor(53, 39, 182));_mainBlock[_clearRow][j].setPixmap(*_firstPixmap);}_clearRow++;if (_clearRow > 19) {_palyFirst = false;_clearRow = 0;}
}void MainFrameLayout::playSecondColor() {for (int j = 0; j < 10; j++) {_mainBlock[_clearRow][j].setUse(false);_mainBlock[_clearRow][j].setColor(_bkColor);_mainBlock[_clearRow][j].setPixmap(*_secondPixmap);}_clearRow++;if (_clearRow > 19) {_gameOverTimer->stop();_clearRow = 0;}
}bool MainFrameLayout::totalScore() {std::set <int, std::less<int> > fullRows;//若使用less,则从小到大,若使用greater则从大到小。//1.记录填满的行的位置for (size_t i = 0; i < 4; i++) {int r = _current4Block[i].x();bool full = true;for (int j = 0; j < 10; j++) {if (!_mainBlock[r][j].getUse()){//如果有一个空格,说明整行未充满full = false;break;}}if (full){//如果一行全部充满,则保存这个行位置fullRows.insert(r);}}//2.统计行数和分数int fullR = fullRows.size();if (fullR == 0){//没有全满的行数return false;}_totalRows += fullR;if (fullR == 1){//消除1行_totalScore += 1;} else if (fullR == 2) {//消除2行_totalScore += 3;} else if (fullR == 3) {//消除3行_totalScore += 6;} else if (fullR == 4) {//消除4行_totalScore += 8;}//计算总分和总行数_currentFinish->getTotal(_totalRows, _totalScore);//3.重新调整布局,整体向下移动相应的格式for (auto iter = fullRows.begin(); iter != fullRows.end(); ++iter) {int r = *iter;for (int rr = r - 1; rr > 0; rr--) {bool fullSpace = true;for (int j = 0; j < 10; j++) {//如果整行都没有方块,则直接返回if (_mainBlock[rr][j].getUse()) {fullSpace = false;break;}}if (fullSpace){//向下移动一行空白for (int k = 0; k < 10; k++) {_mainBlock[rr + 1][k] = _mainBlock[rr][k];//上一行空白行的移动到下一行}break;}//向下移动一行for (int k = 0; k < 10; k++) {_mainBlock[rr + 1][k] = _mainBlock[rr][k];//上一行的移动到下一行}}}_mainScene->update();return true;
}

5.随机数生产类

#pragma once//随机排序类class RandomNumber {
public:RandomNumber();~RandomNumber();void setMaxNumber(int maxNum);//获取所有序列int*getAllRandNumber(int&countNumber);//获取一个随机数int getOneRandNumber();
private:int _maxNumber = -1;//最大的整数int* _orgNum = nullptr;//初始数组int* _randNum = nullptr;//随机排序后的数组
};
#include "RandomNumber.h"
#include <cstdlib>
#include<QRandomGenerator>RandomNumber::RandomNumber() {
}RandomNumber::~RandomNumber() {
}void RandomNumber::setMaxNumber(int maxNum) {_maxNumber = maxNum;if (_orgNum != nullptr || _randNum != nullptr) {delete _orgNum;_orgNum = nullptr;delete _randNum;_randNum = nullptr;}_orgNum = new int[_maxNumber];_randNum = new int[_maxNumber];for (int i = 0; i < _maxNumber; i++) {_orgNum[i] = i;_randNum[i] = i;}
}int* RandomNumber::getAllRandNumber(int&countNumber) {countNumber = _maxNumber;int temp = -1;int maxRand = _maxNumber;for (int i = 0; i < _maxNumber; i++) {//1.随机生成 0 和 maxRand-1之间的整数int randOne = rand() % maxRand;//2.把_orgNum的位置randOne的数放到需要排序的数组中_randNum[i] = _orgNum[randOne];//3.把_orgNum的位置randOne的数和maxRand-1的位置的数交换temp = _orgNum[randOne];_orgNum[randOne] = _orgNum[maxRand - 1];_orgNum[maxRand - 1] = temp;//4.缩小随机数的范围maxRand--;}return _randNum;
}int RandomNumber::getOneRandNumber() {int temp = -1;int maxRand = _maxNumber;for (int i = 0; i < _maxNumber; i++) {//1.随机生成 0 和 maxRand-1之间的整数int randNum = QRandomGenerator::global()->bounded(_maxNumber-1);//生成一个0和10之间的整数//2.把_orgNum的位置randOne的数放到需要排序的数组中_randNum[i] = _orgNum[randNum];//3.把_orgNum的位置randOne的数和maxRand-1的位置的数交换temp = _orgNum[randNum];_orgNum[randNum] = _orgNum[maxRand - 1];_orgNum[maxRand - 1] = temp;//4.缩小随机数的范围maxRand--;}return _randNum[0];
}

6.下一个方块展示界面

#pragma once//下一个方块类型
class QGraphicsScene;
class QGraphicsView;
class RandomNumber;
class BlockFactory;
class BaseBlock;
class SubBlock;class NextFrameLayout {
public:NextFrameLayout();~NextFrameLayout();void init();QGraphicsView* getNextFrameView() {return _nextView;}//生产一个新的方块BaseBlock* createNewBlock();//当前运行的方块BaseBlock* getNexBlock() {return _nextBaseBlock;}
private:QGraphicsScene* _nextScene = nullptr;QGraphicsView* _nextView = nullptr;bool _tinyBlock[4][4];//四个小方块SubBlock* _rectItem = nullptr;//根据随机数生产不同的俄罗斯方块BlockFactory* _blockFactory = nullptr;RandomNumber* _randNumber = nullptr;BaseBlock* _nextBaseBlock = nullptr;//下一个即将运行的俄罗斯方块
};
#include "NextFrameLayout.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsLineItem>
#include <QGraphicsRectItem>
#include "RandomNumber.h"
#include "../Block/BaseBlock.h"
#include "../Block/BlockFactory.h"
#include "../Block/SubBlock.h"NextFrameLayout::NextFrameLayout() {init();
}NextFrameLayout::~NextFrameLayout() {
}void NextFrameLayout::init() {_randNumber = new RandomNumber;_randNumber->setMaxNumber(7);_blockFactory = new BlockFactory;for (int i =0;i< 4;i++){for (int j = 0;j< 4;j++){_tinyBlock[i][j] = false;}}if (_nextScene == nullptr) {_nextScene = new QGraphicsScene;_nextScene->setSceneRect(0, 0, 80, 80);}_rectItem = new SubBlock[4];for (int i = 0; i < 4; i++) {_rectItem[i].setVisible(false);_nextScene->addItem(_rectItem + i);}if (_nextView == nullptr) {_nextView = new QGraphicsView;_nextView->setBackgroundBrush(Qt::darkGray);_nextView->setRenderHint(QPainter::Antialiasing);_nextView->setScene(_nextScene);}QPen penLine;penLine.setStyle(Qt::SolidLine);penLine.setColor(Qt::white);penLine.setWidth(2);//绘制边界QGraphicsRectItem* rect = new QGraphicsRectItem(-4, -4, 88, 88);rect->setPen(penLine);_nextScene->addItem(rect);penLine.setStyle(Qt::SolidLine);penLine.setColor(Qt::yellow);penLine.setWidth(1);//横线for (int i = 0; i <= 4; i++) {QGraphicsLineItem* hl1 = new QGraphicsLineItem(0, 20 * i, 80, 20 * i);hl1->setPen(penLine);_nextScene->addItem(hl1);}//竖线for (int i = 0; i <= 4; i++) {QGraphicsLineItem* hl1 = new QGraphicsLineItem(20 * i, 0, 20 * i, 80);hl1->setPen(penLine);_nextScene->addItem(hl1);}
}BaseBlock* NextFrameLayout::createNewBlock() {BaseBlock* block = _blockFactory->createBlock((BlockType)(_randNumber->getOneRandNumber()));if (block != nullptr) {QPoint currentBlock[4];block->getHeadFirstPattern(currentBlock);QColor color = block->getBlockColor();for (int i = 0; i < 4;i++) {_rectItem[i].setVisible(true);_rectItem[i].setSubColor(color);}for (int i = 0; i < 4;i++) {//根据行列位置计算出像素位置,如第三行实际是像素位置Y值_rectItem[i].setPos(20 * (currentBlock[i].y() + 1), 20 * currentBlock[i].x());_nextScene->update();}_nextView->update();}_nextBaseBlock = block;return block;
}

资源下载


http://www.ppmy.cn/news/266762.html

相关文章

python编的俄罗斯方块游戏下载_python写的俄罗斯方块游戏

python写的俄罗斯方块游戏 功能包括:记录所花费时间;消去的总行数;总分;排行榜&#xff0c;最高记录查看等。 排行榜中包含一系列的统计功能&#xff0c;如单位时间消去的行数&#xff0c;单位时间得分等。 from Tkinter import * from tkMessageBox import * import rando…

经典俄罗斯方块游戏手机版

经典俄罗斯方块手机版是一款十分经典好玩的休闲益智类消方块游戏&#xff0c;因为这个游戏玩法是由俄罗斯人阿列克谢帕基特诺夫发明的&#xff0c;因此又名俄罗斯方块游戏&#xff0c;该游戏玩法十分简单容易&#xff0c;但可玩性十足。虽然说其中的游戏规则只是需要玩家移动、…

俄罗斯方块游戏(C语言)

简介&#xff1a;俄罗斯方块&#xff08;Tetris&#xff09;是一款经典的游戏&#xff0c;下面是用C语言实现俄罗斯方块的示例代码&#xff1a; code #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <wi…

java实现俄罗斯方块项目

导读:俄罗斯方块项目,基本功能包括:游戏主界面显示模块、方块及数据显示模块、方块移动控制模块、游戏界面颜色控制模块、游戏进度、等级控制模块等。本项目结构如下: (1)游戏主界面显示模块: 显示游戏和帮助两个菜单; 游戏使用功能键盘,得分 等级; (2)画布…

PHP俄罗斯方块游戏代码,俄罗斯方块游戏,俄罗斯方块游戏编程代码

俄罗斯方块游戏&#xff0c;俄罗斯方块游戏编程代码 来源&#xff1a;互联网/编辑&#xff1a;佚名/时间&#xff1a;2020-07-29 在手机上看 扫一扫进入手机端 一个人的游戏:俄罗斯方块游戏下载 新浪游戏就有&#xff01; 俄罗斯方块是哪出的游戏呀&#xff1f; 俄罗斯! “俄罗…

c语言大作业俄罗斯方块,VC++ 6.0 C语言实现俄罗斯方块详细教程

今天把我之前写的大作业分享一下吧&#xff0c;并教你们如何实现&#xff0c;希望你们看了前面的教程也能自己写一个。 1.要先下载一个 graphics.h 的头文件来绘图。 2.初始化窗口&#xff1a;initgraph(x, y);这是先创建一个窗口的函数&#xff0c;以左上角为(0,0)&#xff0c…

Python课程设计之俄罗斯方块

Python课程设计之俄罗斯方块 演示效果下载地址运行效果基础页面界面动起来生成、移动、固定、变形消除与得分 演示效果 点击查看 下载地址 点击下载 Python课程设计之俄罗斯方块 软件需求&#xff1a;Python环境 压缩包内含&#xff1a;源代码、打包好的可执行文件、文档报告…

用linux写俄罗斯方块代码,linux下使用C写俄罗斯方块

Makefile书写请看 《教你玩Makefile(一)》 欢迎大家加我的群&#xff1a;460952208 Makefile.PHONY:clean PWD$(shell pwd) main_OBJ$(PWD)/obj/main.o print_OBJ$(PWD)/obj/print.o control_OBJ$(PWD)/obj/control.o main_SOURCE$(PWD)/src/main.c print_SOURCE$(PWD)/src/pri…