Qt开发源码(俄罗斯方块)_第1页
Qt开发源码(俄罗斯方块)_第2页
Qt开发源码(俄罗斯方块)_第3页
Qt开发源码(俄罗斯方块)_第4页
Qt开发源码(俄罗斯方块)_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

-俄罗斯方块游戏Main.cpp主程序代码:#include #include #include tetrixwindow.hint main(int argc, char *argv) / 为了能够正常显示中文,设置Tr编码环境为GB2312 (详见wiki) QTextCodec:setCodecForTr(QTextCodec:codecForName(GB2312); / app这个对象用于管理应用级别的资源 QApplication app(argc, argv); app.setStyleSheet(TetrixBoard background-color:lightGray); TetrixWindow window; window.setWindowIcon(QIcon(:/Chrome.ico); window.show(); / 当前时间作为随机种子 qsrand(QTime(0,0,0).secsTo(QTime:currentTime(); return app.exec(); / 程序的事件循环Tetrixboard.h头文件代码:/ 主游戏区类#ifndef TETRIXBOARD_H#define TETRIXBOARD_H#include tetrixpiece.h#include #include #include #include / 前向声明class QLabel;class TetrixBoard : public QFrame Q_OBJECTpublic: TetrixBoard(QWidget *parent = 0); void setNextPieceLabel(QLabel *label); QSize sizeHint() const;/最适合大小 QSize minimumSizeHint() const; / 最小限制public slots: / 公有槽 void start(); void pause();signals: / 信号:只需声明,根据参数变化来判断 void scoreChanged(int score); void levelChanged(int level); void linesRemovedChanged(int numLines);protected: / 着色、键盘、计时事件:其中着色事件随着update()不断触发 void paintEvent(QPaintEvent *event); void keyPressEvent(QKeyEvent *event); void timerEvent(QTimerEvent *event);private: enum BoardWidth = 10, BoardHeight = 22 ; / 把主游戏区宽分成10等份,高分成22等份,也就是说每行有10小矩形,总共有22行 TetrixShape &shapeAt(int x, int y) return board(y * BoardWidth) + x; int timeoutTime() return 1000 / (1 + level); / contentsRect():返回当前布局(QLayout)的矩形,可访问其长、宽 (详见API) / conntentsRect().width()/BoardWidth 把游戏区矩形的宽分成了BoardWidth份 int squareWidth() return contentsRect().width() / BoardWidth; / 同上,把高分成了BoardHeight份 int squareHeight() return contentsRect().height() / BoardHeight; / 此时squareWidth(),squareHeight()分别是分割后的小矩形宽和高 void clearBoard(); / 清屏 void dropDown(); / 下落事件 void oneLineDown();/ 下落一行 void pieceDropped(int dropHeight); void removeFullLines(); / 移除填满的行 void newPiece(); / 新方块 void showNextPiece(); / 显示下一个方块 bool tryMove(const TetrixPiece &newPiece, int newX, int newY); / 判断方块是否可以移动 void drawSquare(QPainter &painter, int x, int y, TetrixShape shape); / 着色 QBasicTimer timer; / 相当于QLabel *nextPieceLabel(QPointer详见API) QPointer nextPieceLabel; bool isStarted; bool isPaused; bool isWaitingAfterLine; TetrixPiece curPiece; / 当前方块 TetrixPiece nextPiece; / 下一个方块 int curX; int curY; int numLinesRemoved; int numPiecesDropped; int score; int level; TetrixShape boardBoardWidth * BoardHeight;#endif / TETRIXBOARD_HTetrixboard.cpp程序代码:#include #include tetrixboard.hTetrixBoard:TetrixBoard(QWidget *parent) : QFrame(parent) / 设置游戏区框架风格:内浮雕 setFrameStyle(QFrame:Panel | QFrame:Sunken); / 增加游戏区键盘鼠标等事件的焦点集中 setFocusPolicy(Qt:StrongFocus); isStarted = false; / 初始化:未开始状态 isPaused = false; clearBoard(); / 初始清屏 nextPiece.setRandomShape(); / 下一方块获得一个随机形状/ tetrixpiece.h : tetrixpiece.cpp中使用void TetrixBoard:setNextPieceLabel(QLabel *label) nextPieceLabel = label;/ 游戏区合适大小QSize TetrixBoard:sizeHint() const return QSize(BoardWidth*15 + frameWidth()*2, BoardHeight*15 + frameWidth()*2);/ 游戏区最小大小QSize TetrixBoard:minimumSizeHint() const return QSize(BoardWidth*5 + frameWidth()*2, BoardHeight*5 + frameWidth()*2);/ 开始事件:slotsvoid TetrixBoard:start() / 如果已暂停,则启动无效 if (isPaused) return; isStarted = true; / 标记已开始 isWaitingAfterLine = false; / 此参数为判断是否有方块正在下落,false为有方块正在下落中 / 初始各参数 numLinesRemoved = 0; numPiecesDropped = 0; score = 0; level = 1; clearBoard(); / 清屏 / emit 信号发射:触发对应信号槽内的函数(相关connect()在tetrixwindow.cpp中) emit linesRemovedChanged(numLinesRemoved); emit scoreChanged(score); emit levelChanged(level); newPiece(); / 调用新方块 timer.start(timeoutTime(), this);/ 游戏开始计时/ 暂停事件:slotsvoid TetrixBoard:pause() / 如果未开始,则暂停无效 if (!isStarted) return; / 否则,若未暂停,则赋值为暂停,反之,取消暂停,继续游戏 isPaused = !isPaused; if (isPaused) timer.stop(); / 游戏计时停止 else timer.start(timeoutTime(), this); / 否则继续计时 update(); / 刷新窗口:动态显示画面/ 游戏区方块着色/ 重定义绘图事件,当调用update()时进行重绘void TetrixBoard:paintEvent(QPaintEvent *event) QFrame:paintEvent(event); QPainter painter(this); QRect rect = contentsRect(); / QRect定义了平面上的矩形 (详见API),是主游戏区 / 暂停的时候显示的信息 if (isPaused) painter.drawText(rect, Qt:AlignCenter, tr(游戏暂停); return; / BoardHeight*squareHeight() 相当于 contentsRect().Height(),是小网格的高 / 因为squareHeight() return contentsRect().Width()/BoardWidth(); / 见tetrixboard.h中的定义 int boardTop = rect.bottom() - BoardHeight*squareHeight(); for (int i=0; iBoardHeight; +i) for (int j=0; jBoardWidth; +j) / TetrixShape &shapeAt(int x, int y) return board(y * BoardWidth) + x; TetrixShape shape = shapeAt(j, BoardHeight-i-1); if (shape != NoShape) / rect.left() 返回游戏区矩形左边的x坐标,squareWidth()为小网格的宽度 drawSquare(painter, rect.left() + j*squareWidth(), boardTop + i*squareHeight(), shape); / 绘图 if (curPiece.shape() != NoShape) for (int i=0; ikey() case Qt:Key_Left: tryMove(curPiece, curX-1, curY); / 左移 break; case Qt:Key_Right: tryMove(curPiece, curX+1, curY); / 右移 break; case Qt:Key_Up: tryMove(curPiece.rotatedLeft(),curX,curY); / 方块左转 break; case Qt:Key_Down: dropDown(); / 快速下落 break; default: QFrame:keyPressEvent(event); / 计时时间void TetrixBoard:timerEvent(QTimerEvent *event) if (event-timerId() = timer.timerId() / 如果还有方块已下落完毕 if (isWaitingAfterLine) isWaitingAfterLine = false; / 重标记为有方块正在下落 newPiece(); / 添加新方块 (timeoutTime(), this); else oneLineDown(); /否则进行下落动作 else QFrame:timerEvent(event); / 清空游戏区所有绘图void TetrixBoard:clearBoard() for (int i=0; i 0) if (!tryMove(curPiece,curX,newY-1) break; -newY; +dropHeight; / 把下落高度传递给此函数 pieceDropped(dropHeight);/ 正常下落操作void TetrixBoard:oneLineDown() if (!tryMove(curPiece, curX,curY-1) / 如果能移动,则下落一行 pieceDropped(0);/ 正常下落不几分/ 进行方块下落后的行为,如绘图,加分等 参数:下落方块的高度void TetrixBoard:pieceDropped(int dropHeight) for (int i=0; i= 0; -i) bool lineIsFull = true; / 判断是否已满一行 for (int j=0; j BoardWidth; +j) if (shapeAt(j,i)=NoShape) lineIsFull = false; break; / 上面所有行下移 if (lineIsFull) +numFullLines; for(int k = i; k BoardHeight-1; +k) for (int j = 0; j BoardWidth; +j) shapeAt(j,k) = shapeAt(j, k+1); / 整行清零 for (int j = 0; j 0) numLinesRemoved += numFullLines; score += 10 * numFullLines; / 同时发送信号至相应的槽 emit linesRemovedChanged(numLinesRemoved); emit scoreChanged(score); (500,this); isWaitingAfterLine = true; curPiece.setShape(NoShape); update(); / 新方块void TetrixBoard:newPiece() curPiece = nextPiece; / 预先随机设置好一下块方块 nextPiece.setRandomShape(); showNextPiece(); / 设置其初始下落的位置,在游戏区顶部中央 curX = BoardWidth / 2 + 1; curY = BoardHeight-1 + curPiece.minY(); / 判断其是否还能移动,如果不能,则停止游戏 if (!tryMove(curPiece, curX, curY) curPiece.setShape(NoShape);/ painter.drawText(rect,tr(游戏结束); timer.stop(); isStarted = false; / 展示下一个方块void TetrixBoard:showNextPiece() if (!nextPieceLabel) return; int dx = nextPiece.maxX() - nextPiece.minX() + 1; int dy = nextPiece.maxY() - nextPiece.minY() + 1; QPixmap pixmap(dx *squareWidth(), dy*squareHeight(); /映射要显示方块像素 QPainter painter(&pixmap); / 开始绘制该方块 painter.fillRect(pixmap.rect(), nextPieceLabel-palette().background(); / 先绘制要显示方块的背景色 / 再开始绘制方块本身 for (int i = 0; i setPixmap(pixmap);/ 最后加载它/ 判断是否还能移动bool TetrixBoard:tryMove(const TetrixPiece &newPiece, int newX, int newY) for (int i = 0; i 4; +i) int x = newX + newPiece.x(i); int y = newY - newPiece.y(i); if (x = BoardWidth | y = BoardHeight) return false; if (shapeAt(x,y) != NoShape) / 判断当前位置是否有其他方块 return false; curPiece = newPiece; curX = newX; curY = newY; update(); return true;/ int squareWidth() return contentsRect().width() / BoardWidth; / int squareHeight() return contentsRect().height() / BoardHeight; void TetrixBoard:drawSquare(QPainter &painter, int x,int y,TetrixShape shape) / google色彩 static const QRgb colorTable8 = 0x000000, 0x1851ce, 0xc61800, 0xefba00, 0x1851ce, 0x1ba823, 0xc61800, 0x606060 ; QColor color = colorTableint(shape); / 填充单元网格的颜色 / void fillRect(int x, int y, int width, int height, const QColor & color) painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2, color); painter.setPen(color.light(); / 左上角边框颜色 / void drawLine(int x1, int y1, int x2, int y2) painter.drawLine(x, y + squareHeight() - 1, x, y); painter.drawLine(x, y, x + squareWidth() - 1, y); painter.setPen(color.dark(); / 右下角边框颜色 painter.drawLine(x + 1, y + squareHeight() - 1, x + squareWidth() - 1, y + squareHeight() - 1); painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1, x + squareWidth() - 1, y + 1);Tetrixpiece.h头文件代码:/ 俄罗斯方块类:方块形状/旋转情况#ifndef TETRIXPIECE_H#define TETRIXPIECE_H/ 定义一个枚举类型(0-7):无形状、Z字形、S字形、直线形,T字形,田字形形、L字形,翻转L字形enum TetrixShape NoShape, ZShape,SShape,LineShape,TShape,SquareShape, LShape,MirroredLShape ;class TetrixPiecepublic: TetrixPiece() setShape(NoShape); / inline构造函数:初始设置成NoShape void setRandomShape(); / 设置随机规则 void setShape(TetrixShape shape); / 构造方块形状的数据结构 / 通过inline公有函数成员shape()访问私有数据成员pieceShape TetrixShape shape() const return pieceShape; int x(int index) const return coordsindex0; int y(int index) const return coordsindex1; int minX() const; int maxX() const; int minY() const; int maxY() const; TetrixPiece rotatedLeft() const; / 左转private: void setX(int index, int x) coordsindex0 = x; void setY(int index, int y) coordsindex1 = y; TetrixShape pieceShape; / 枚举类型创建一个该枚举类型对象 int coords42;#endif / TETRIXPIECE_HTetrixpiece.cpp程序代码:#include #include tetrixpiece.h#include #include #include / 伪随机函数:利用当前系统时间增加随机性void TetrixPiece:setRandomShape() /QTime time = QTime:currentTime(); /qsrand( time.msec() + time.second()*1000 );/ 重设随机种子:当前时间为随机变量 setShape(TetrixShape(qrand()%7 + 1); / 共六种方块形状void TetrixPiece:setShape(TetrixShape shape) / 按TetrixShape枚举顺序构建: / 除NoShape外,每个形状由4个小方块组成,这里每行的四个坐标即4个小方块的坐标,其中横向为X,纵向为Y / ZShape SShape LineShape TShape SquareShape LShape MirroredLShape/ -1 0 1 2 -1 0 1 2 -1 0 1 2 -1 0 1 2 -1 0 1 2 -1 0 1 2 -1 0 1 2/ -1 * -1 * -1 * -1 -1 -1 * * -1 * */ 0 * * 0 * * 0 * 0 * * * 0 * * 0 * 0 */ 1 * 1 * 1 * 1 * 1 * * 1 * 1 */ 2 2 2 * 2 2 2 2 static const int coordsTable842 = 0, 0 , 0, 0 , 0, 0 , 0, 0 ,/ NoShape 0, -1 , 0, 0 , -1, 0 , -1, 1 , 0, -1 , 0, 0 , 1, 0 , 1, 1 , 0, -1 , 0, 0 , 0, 1 , 0, 2 , -1, 0 , 0, 0 , 1, 0 , 0, 1 , 0, 0 , 1, 0 , 0, 1 , 1, 1 , -1, -1 , 0, -1 , 0, 0 , 0, 1 , 1, -1 , 0, -1 , 0, 0 , 0, 1 ; for (int i=0; i4; i+) for (int j=0; j2; +j) coordsij = coordsTableshapeij; pieceShape = shape;/ 获取最小X坐标值,QtGlobal:qMinint TetrixPiece:minX() const int min = coords00; for (int i = 1; i 4; +i) min = qMin(min, coordsi0); return min;/ 获取最大X坐标值,QtGlobal:qMaxint TetrixPiece:maxX() const int max = coords00; for (int i = 1; i 4; +i) max = qMax(max, coordsi0); return max;/ 获取最小Y坐标值int TetrixPiece:minY() const int min = coords01; for (int i = 1; i 4; +i) min = qMin(min, coordsi1); return min;/ 获取最大Y坐标值int TetrixPiece:maxY() const int max = coords01; for (int i = 0; i 4; +i) max = qMax(max, coordsi1); return max;/ 按顺时针方向左转90度:/ x = -y;/ y = x;TetrixPiece TetrixPiece:rotatedLeft() const if (pieceShape = SquareShape) return *this; TetrixPiece result; result.pieceShape = pieceShape; for (int i = 0; i 4; +i) result.setX(i,-y(i); result.setY(i,x(i); return result;Tetrixwindow.h头文件代码:/ 主窗口类:控制区/游戏区#ifndef TETRIXWINDOW_H#define TETRIXWINDOW_H#include #include /* 前向声明: 因为此处只使用这些类的指针,没有涉及相关函数, 并不需要include它们的头文件,那样会减慢编译速度 */QT_BEGIN_NAMESPACEclass QLCDNumber;class QLabel;class QPushButton;QT_END_NAMESPACEclass TetrixBoard;class TetrixWindow : public QWidget / 这个宏定义涉及到Qt高级部分,我们现在只需知道 / tr()connecet()slotssignals与之有关 Q_OBJECTpublic: TetrixWindow();public slots: void About();private: /* 声明需要用到的一些部件的指针,包括:开始、暂停、退出按钮, 分数、等级、消去行数、下一个方块显示区等*/ QLabel *createLabel(const QString &text); TetrixBoard *board; / 自定义游戏逻辑类对象指针 QLabel *nextPieceLabel; QLCDNumber *scoreLcd; QLCDNumber *levelLcd; QLCDNumber *linesLcd; QPushButton *startButton; QPushButton *quitButton; QPushButton *pauseButton; QPushButton *aboutButton;#endif /TETRIXWINDOW_HTetrixwindow.cpp程序代码:#include #include tetrixboard.h#include tetrixwindow.h/ 构造函数:将声明的抽象部件实例化TetrixWindow:TetrixWindow() board = new TetrixBoard; / board为主游戏区 nextPieceLabel = new QLabel; / Raised:浮雕 Box:draw a box around its contents /nextPieceLabel-setFrameStyle(QFrame:Box | QFrame:Raised); nextPieceLabel-setAlignment(Qt:AlignCenter); / 居中显示 / 通过该函数将nextPieceLabel赋值给board对象私有变量nextPieceLabel: / 不是友元或继承关系无法直接调用其私有成员 board-setNextPieceLabel(nextPieceLabel); / Lcd数字显示器 scoreLcd = new QLCDNumber(5); / 最大为5位数 scoreLcd-setSegmentStyle(QLCDNumber:Filled); / 浮雕显示数字 (详见API) levelLcd = new QLCDNumber(5); levelLcd-setSegmentStyle(QLCDNumber:Filled); linesLcd = new QLCDNumber(5); linesLcd-setSegmentStyle(QLCDNumber:Filled); / 按钮实例化:设置为NoFocus,避免与游戏按键冲突 startButton = new QPushButton(tr(&开始); startButton-setFocusPolicy(Qt:NoFocus); quitButton = new QPushButton(tr(&退出); quitButton-setFocusPolicy(Qt:NoFocus); pauseButton = new QPushButton(tr(&暂停); pauseButton-setFocusPolicy(Qt:NoFocus); aboutButton = new QPushButton(tr(&关于); aboutButton-setFocusPolicy(Qt:NoFocus); / 相应信号槽连接Qt核心:QObject:connect(信号发射对象,SIGNAL(信号),接收对象,SLOT(触发槽) / 信号(signals):可以只声明不定义; 触发槽(slots):信号响应函数 connect(startButton, SIGNAL(clicked(), board, SLOT(start(); connect(quitButton, SIGN

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论