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

下载本文档

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

文档简介

1、-. z.俄罗斯方块游戏Main.cpp主程序代码:#include #include #include tetri*window.hint main(int argc, char *argv) / 为了能够正常显示中文,设置Tr编码环境为GB2312 (详见wiki) QTe*tCodec:setCodecForTr(QTe*tCodec:codecForName(GB2312); / app这个对象用于管理应用级别的资源 QApplication app(argc, argv); app.setStyleSheet(Tetri*Board background-color:lightGra

2、y); Tetri*Window window; window.setWindowIcon(QIcon(:/Chrome.ico); window.show(); / 当前时间作为随机种子 qsrand(QTime(0,0,0).secsTo(QTime:currentTime(); return app.e*ec(); / 程序的事件循环Tetri*board.h头文件代码:/ 主游戏区类#ifndef TETRI*BOARD_H#define TETRI*BOARD_H#include tetri*piece.h#include #include #include #include / 前

3、向声明class QLabel;class Tetri*Board : public QFrame Q_OBJECTpublic: Tetri*Board(QWidget *parent = 0); void setNe*tPieceLabel(QLabel *label); QSize sizeHint() const;/最适合大小 QSize minimumSizeHint() const; / 最小限制public slots: / 公有槽 void start(); void pause();signals: / 信号:只需声明,根据参数变化来判断 void scoreChanged(

4、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等

5、份,高分成22等份,也就是说每行有10小矩形,总共有22行 Tetri*Shape &shapeAt(int *, int y) return board(y * BoardWidth) + *; int timeoutTime() return 1000 / (1 + level); / contentsRect():返回当前布局(QLayout)的矩形,可访问其长、宽 (详见API) / conntentsRect().width()/BoardWidth 把游戏区矩形的宽分成了BoardWidth份 int squareWidth() return contentsRect().widt

6、h() / BoardWidth; / 同上,把高分成了BoardHeight份 int squareHeight() return contentsRect().height() / BoardHeight; / 此时squareWidth(),squareHeight()分别是分割后的小矩形宽和高 void clearBoard(); / 清屏 void dropDown(); / 下落事件 void oneLineDown();/ 下落一行 void pieceDropped(int dropHeight); void removeFullLines(); / 移除填满的行 void n

7、ewPiece(); / 新方块 void showNe*tPiece(); / 显示下一个方块 bool tryMove(const Tetri*Piece &newPiece, int new*, int newY); / 判断方块是否可以移动 void drawSquare(QPainter &painter, int *, int y, Tetri*Shape shape); / 着色 QBasicTimer timer; / 相当于QLabel *ne*tPieceLabel(QPointer详见API) QPointer ne*tPieceLabel; bool isStarted

8、; bool isPaused; bool isWaitingAfterLine; Tetri*Piece curPiece; / 当前方块 Tetri*Piece ne*tPiece; / 下一个方块 int cur*; int curY; int numLinesRemoved; int numPiecesDropped; int score; int level; Tetri*Shape boardBoardWidth * BoardHeight;#endif / TETRI*BOARD_HTetri*board.cpp程序代码:#include #include tetri*board

9、.hTetri*Board:Tetri*Board(QWidget *parent) : QFrame(parent) / 设置游戏区框架风格:浮雕 setFrameStyle(QFrame:Panel | QFrame:Sunken); / 增加游戏区键盘鼠标等事件的焦点集中 setFocusPolicy(Qt:StrongFocus); isStarted = false; / 初始化:未开场状态 isPaused = false; clearBoard(); / 初始清屏 ne*tPiece.setRandomShape(); / 下一方块获得一个随机形状/ tetri*piece.h

10、: tetri*piece.cpp中使用void Tetri*Board:setNe*tPieceLabel(QLabel *label) ne*tPieceLabel = label;/ 游戏区适宜大小QSize Tetri*Board:sizeHint() const return QSize(BoardWidth*15 + frameWidth()*2, BoardHeight*15 + frameWidth()*2);/ 游戏区最小大小QSize Tetri*Board:minimumSizeHint() const return QSize(BoardWidth*5 + frameW

11、idth()*2, BoardHeight*5 + frameWidth()*2);/ 开场事件:slotsvoid Tetri*Board:start() / 如果已暂停,则启动无效 if (isPaused) return; isStarted = true; / 标记已开场 isWaitingAfterLine = false; / 此参数为判断是否有方块正在下落,false为有方块正在下落中 / 初始各参数 numLinesRemoved = 0; numPiecesDropped = 0; score = 0; level = 1; clearBoard(); / 清屏 / emit

12、 信号发射:触发对应信号槽的函数(相关connect()在tetri*window.cpp中) emit linesRemovedChanged(numLinesRemoved); emit scoreChanged(score); emit levelChanged(level); newPiece(); / 调用新方块 timer.start(timeoutTime(), this);/ 游戏开场计时/ 暂停事件:slotsvoid Tetri*Board:pause() / 如果未开场,则暂停无效 if (!isStarted) return; / 否则,假设未暂停,则赋值为暂停,反之,

13、取消暂停,继续游戏 isPaused = !isPaused; if (isPaused) timer.stop(); / 游戏计时停顿 else timer.start(timeoutTime(), this); / 否则继续计时 update(); / 刷新窗口:动态显示画面/ 游戏区方块着色/ 重定义绘图事件,当调用update()时进展重绘void Tetri*Board:paintEvent(QPaintEvent *event) QFrame:paintEvent(event); QPainter painter(this); QRect rect = contentsRect()

14、; / QRect定义了平面上的矩形 (详见API),是主游戏区 / 暂停的时候显示的信息 if (isPaused) painter.drawTe*t(rect, Qt:AlignCenter, tr(游戏暂停); return; / BoardHeight*squareHeight() 相当于 contentsRect().Height(),是小网格的高 / 因为squareHeight() return contentsRect().Width()/BoardWidth(); / 见tetri*board.h中的定义 int boardTop = rect.bottom() - Boar

15、dHeight*squareHeight(); for (int i=0; iBoardHeight; +i) for (int j=0; jBoardWidth; +j) / Tetri*Shape &shapeAt(int *, int y) return board(y * BoardWidth) + *; Tetri*Shape shape = shapeAt(j, BoardHeight-i-1); if (shape != NoShape) / rect.left() 返回游戏区矩形左边的*坐标,squareWidth()为小网格的宽度 drawSquare(painter, re

16、ct.left() + j*squareWidth(), boardTop + i*squareHeight(), shape); / 绘图 if (curPiece.shape() != NoShape) for (int i=0; ikey() case Qt:Key_Left: tryMove(curPiece, cur*-1, curY); / 左移 break; case Qt:Key_Right: tryMove(curPiece, cur*+1, curY); / 右移 break; case Qt:Key_Up: tryMove(curPiece.rotatedLeft(),c

17、ur*,curY); / 方块左转 break; case Qt:Key_Down: dropDown(); / 快速下落 break; default: QFrame:keyPressEvent(event); / 计时时间void Tetri*Board:timerEvent(QTimerEvent *event) if (event-timerId() = timer.timerId() / 如果还有方块已下落完毕 if (isWaitingAfterLine) isWaitingAfterLine = false; / 重标记为有方块正在下落 newPiece(); / 添加新方块 (

18、timeoutTime(), this); else oneLineDown(); /否则进展下落动作 else QFrame:timerEvent(event); / 清空游戏区所有绘图void Tetri*Board:clearBoard() for (int i=0; i 0) if (!tryMove(curPiece,cur*,newY-1) break; -newY; +dropHeight; / 把下落高度传递给此函数 pieceDropped(dropHeight);/ 正常下落操作void Tetri*Board:oneLineDown() if (!tryMove(curP

19、iece, cur*,curY-1) / 如果能移动,则下落一行 pieceDropped(0);/ 正常下落不几分/ 进展方块下落后的行为,如绘图,加分等 参数:下落方块的高度void Tetri*Board: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 (lineIsF

20、ull) +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,t

21、his); isWaitingAfterLine = true; curPiece.setShape(NoShape); update(); / 新方块void Tetri*Board:newPiece() curPiece = ne*tPiece; / 预先随机设置好一下块方块 ne*tPiece.setRandomShape(); showNe*tPiece(); / 设置其初始下落的位置,在游戏区顶部中央 cur* = BoardWidth / 2 + 1; curY = BoardHeight-1 + curPiece.minY(); / 判断其是否还能移动,如果不能,则停顿游戏 if

22、 (!tryMove(curPiece, cur*, curY) curPiece.setShape(NoShape);/ painter.drawTe*t(rect,tr(游戏完毕); timer.stop(); isStarted = false; / 展示下一个方块void Tetri*Board:showNe*tPiece() if (!ne*tPieceLabel) return; int d* = ne*tPiece.ma*() - ne*tPiece.min*() + 1; int dy = ne*tPiece.ma*Y() - ne*tPiece.minY() + 1; QPi

23、*map pi*map(d* *squareWidth(), dy*squareHeight(); /映射要显示方块像素 QPainter painter(&pi*map); / 开场绘制该方块 painter.fillRect(pi*map.rect(), ne*tPieceLabel-palette().background(); / 先绘制要显示方块的背风光 / 再开场绘制方块本身 for (int i = 0; i setPi*map(pi*map);/ 最后加载它/ 判断是否还能移动bool Tetri*Board:tryMove(const Tetri*Piece &newPiec

24、e, int new*, int newY) for (int i = 0; i 4; +i) int * = new* + newPiece.*(i); int y = newY - newPiece.y(i); if (* = BoardWidth | y = BoardHeight) return false; if (shapeAt(*,y) != NoShape) / 判断当前位置是否有其他方块 return false; curPiece = newPiece; cur* = new*; curY = newY; update(); return true;/ int square

25、Width() return contentsRect().width() / BoardWidth; / int squareHeight() return contentsRect().height() / BoardHeight; void Tetri*Board:drawSquare(QPainter &painter, int *,int y,Tetri*Shape shape) / google色彩 static const QRgb colorTable8 = 0*000000, 0*1851ce, 0*c61800, 0*efba00, 0*1851ce, 0*1ba823,

26、0*c61800, 0*606060 ; QColor color = colorTableint(shape); / 填充单元网格的颜色 / void fillRect(int *, int y, int width, int height, const QColor & color) painter.fillRect(* + 1, y + 1, squareWidth() - 2, squareHeight() - 2, color); painter.setPen(color.light(); / 左上角边框颜色 / void drawLine(int *1, int y1, int *

27、2, int y2) painter.drawLine(*, y + squareHeight() - 1, *, y); painter.drawLine(*, y, * + squareWidth() - 1, y); painter.setPen(color.dark(); / 右下角边框颜色 painter.drawLine(* + 1, y + squareHeight() - 1, * + squareWidth() - 1, y + squareHeight() - 1); painter.drawLine(* + squareWidth() - 1, y + squareHei

28、ght() - 1, * + squareWidth() - 1, y + 1);Tetri*piece.h头文件代码:/ 俄罗斯方块类:方块形状/旋转情况#ifndef TETRI*PIECE_H#define TETRI*PIECE_H/ 定义一个枚举类型(0-7):无形状、Z字形、S字形、直线形,T字形,田字形形、L字形,翻转L字形enum Tetri*Shape NoShape, ZShape,SShape,LineShape,TShape,SquareShape, LShape,MirroredLShape ;class Tetri*Piecepublic: Tetri*Piece(

29、) setShape(NoShape); / inline构造函数:初始设置成NoShape void setRandomShape(); / 设置随机规则 void setShape(Tetri*Shape shape); / 构造方块形状的数据构造 / 通过inline公有函数成员shape()访问私有数据成员pieceShape Tetri*Shape shape() const return pieceShape; int *(int inde*) const return coordsinde*0; int y(int inde*) const return coordsinde*1

30、; int min*() const; int ma*() const; int minY() const; int ma*Y() const; Tetri*Piece rotatedLeft() const; / 左转private: void set*(int inde*, int *) coordsinde*0 = *; void setY(int inde*, int y) coordsinde*1 = y; Tetri*Shape pieceShape; / 枚举类型创立一个该枚举类型对象 int coords42;#endif / TETRI*PIECE_HTetri*piece.

31、cpp程序代码:#include #include tetri*piece.h#include #include #include / 伪随机函数:利用当前系统时间增加随机性void Tetri*Piece:setRandomShape() /QTime time = QTime:currentTime(); /qsrand( time.msec() + time.second()*1000 );/ 重设随机种子:当前时间为随机变量 setShape(Tetri*Shape(qrand()%7 + 1); / 共六种方块形状void Tetri*Piece:setShape(Tetri*Sha

32、pe shape) / 按Tetri*Shape枚举顺序构建: / 除NoShape外,每个形状由4个小方块组成,这里每行的四个坐标即4个小方块的坐标,其中横向为*,纵向为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

33、 * 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,

34、 -1 , 0, 0 , 0, 1 ; for (int i=0; i4; i+) for (int j=0; j2; +j) coordsij = coordsTableshapeij; pieceShape = shape;/ 获取最小*坐标值,QtGlobal:qMinint Tetri*Piece:min*() const int min = coords00; for (int i = 1; i 4; +i) min = qMin(min, coordsi0); return min;/ 获取最大*坐标值,QtGlobal:qMa*int Tetri*Piece:ma*() cons

35、t int ma* = coords00; for (int i = 1; i 4; +i) ma* = qMa*(ma*, coordsi0); return ma*;/ 获取最小Y坐标值int Tetri*Piece:minY() const int min = coords01; for (int i = 1; i 4; +i) min = qMin(min, coordsi1); return min;/ 获取最大Y坐标值int Tetri*Piece:ma*Y() const int ma* = coords01; for (int i = 0; i 4; +i) ma* = qMa

36、*(ma*, coordsi1); return ma*;/ 按顺时针方向左转90度:/ * = -y;/ y = *;Tetri*Piece Tetri*Piece:rotatedLeft() const if (pieceShape = SquareShape) return *this; Tetri*Piece result; result.pieceShape = pieceShape; for (int i = 0; i 4; +i) result.set*(i,-y(i); result.setY(i,*(i); return result;Tetri*window.h头文件代码:

37、/ 主窗口类:控制区/游戏区#ifndef TETRI*WINDOW_H#define TETRI*WINDOW_H#include #include /* 前向声明: 因为此处只使用这些类的指针,没有涉及相关函数, 并不需要include它们的头文件,那样会减慢编译速度 */QT_BEGIN_NAMESPACEclass QLCDNumber;class QLabel;class QPushButton;QT_END_NAMESPACEclass Tetri*Board;class Tetri*Window : public QWidget / 这个宏定义涉及到Qt高级局部,我们现在只需知道

38、 / tr()connecet()slotssignals与之有关 Q_OBJECTpublic: Tetri*Window();public slots: void About();private: /* 声明需要用到的一些部件的指针,包括:开场、暂停、退出按钮, 分数、等级、消去行数、下一个方块显示区等*/ QLabel *createLabel(const QString &te*t); Tetri*Board *board; / 自定义游戏逻辑类对象指针 QLabel *ne*tPieceLabel; QLCDNumber *scoreLcd; QLCDNumber *levelLcd

39、; QLCDNumber *linesLcd; QPushButton *startButton; QPushButton *quitButton; QPushButton *pauseButton; QPushButton *aboutButton;#endif /TETRI*WINDOW_HTetri*window.cpp程序代码:#include #include tetri*board.h#include tetri*window.h/ 构造函数:将声明的抽象部件实例化Tetri*Window:Tetri*Window() board = new Tetri*Board; / boar

40、d为主游戏区 ne*tPieceLabel = new QLabel; / Raised:浮雕 Bo*:draw a bo* around its contents /ne*tPieceLabel-setFrameStyle(QFrame:Bo* | QFrame:Raised); ne*tPieceLabel-setAlignment(Qt:AlignCenter); / 居中显示 / 通过该函数将ne*tPieceLabel赋值给board对象私有变量ne*tPieceLabel: / 不是友元或继承关系无法直接调用其私有成员 board-setNe*tPieceLabel(ne*tPie

41、ceLabel); / 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,防止与游戏按键冲突

42、 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(); conne

温馨提示

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

评论

0/150

提交评论