[毕业设计精品]基于QT的俄罗斯方块设计.doc

上传人:文库蛋蛋多 文档编号:2392485 上传时间:2023-02-17 格式:DOC 页数:20 大小:173KB
返回 下载 相关 举报
[毕业设计精品]基于QT的俄罗斯方块设计.doc_第1页
第1页 / 共20页
[毕业设计精品]基于QT的俄罗斯方块设计.doc_第2页
第2页 / 共20页
[毕业设计精品]基于QT的俄罗斯方块设计.doc_第3页
第3页 / 共20页
[毕业设计精品]基于QT的俄罗斯方块设计.doc_第4页
第4页 / 共20页
[毕业设计精品]基于QT的俄罗斯方块设计.doc_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《[毕业设计精品]基于QT的俄罗斯方块设计.doc》由会员分享,可在线阅读,更多相关《[毕业设计精品]基于QT的俄罗斯方块设计.doc(20页珍藏版)》请在三一办公上搜索。

1、目 录摘要1关键字11 功能说明12 开发环境12.1 Qt简介12.2 Qt安装12.3 Qt开发基础12.3.1 Qt对象与对象树12.3.2 信号与槽12.3.3 事件33 系统设计33.1 需求分析33.2 框架设计33.2.1 俄罗斯方块基本规则33.2.2 系统模块43.3 系统实现44 系统测试65 课程设计总结66 附录66.1 参考资料66.2 程序源码6摘要Qt是一个跨平台的C+图形用户界面应用程序框架。本程序利用Qt提供的相关类,实现了俄罗斯方块的基本功能。关键字QT、嵌入式、软件开发1 功能说明 支持俄罗斯方块游戏的基本功能 支持虚拟按键2 开发环境操作系统:ubunt

2、u 10.04 LTS开发工具:gnu编译工具链(gcc等)、Qt Creator、Qt 4.6.22.1 Qt简介Qt是跨平台的应用程序和UI框架。它包括跨平台类库、集成开发工具和跨平台 IDE。使用Qt,只需一次性开发应用程序,无须重新编写源代码,便可跨不同桌面和嵌入式操作系统部署这些应用程序。2.2 Qt安装1. Qt官网()上有完整的SDK下载,下载开发平台的SDK,下载完成后点击即可安装2. 如果是使用Linux系统,也可能通过命令行进行安装,以ubuntu 10.04 LTS为例:sudo apt-get install qt4-dev-tools qtcreator qt4-do

3、c qt4-qtconfig qt-demos3.如果希望构建嵌入式Qt开发平台,则需要参考相关开发板的说明,一般是先制作交叉编译工具链、再交叉编译一个用于目标板的Qt库,这里不再详述2.3 Qt开发基础2.3.1 Qt对象与对象树QObject是所有Qt类的基类。QObject 组织成为对象树。当你创建 QObject 时,将另外的对象作为其父对象,这个对象就被加入其父对象的 children() 列表,并且当父对象销毁时,这个对象也能够被销毁。事实证明,这种实现方法非常适合 GUI 对象。例如,一个 QShortcut(键盘快捷键)对象是相关窗口的子对象,所以当用户关闭窗口时,这个对象也能

4、够被删除。QWidget 作为所有能够显示在屏幕上的组件的父类,扩展了这种父子关系。一个子对象通常也成为一个子组件,就是说,它被显示在父组件的坐标系统中,受到父组件的边界影响可能会有剪切等等。例如,当应用程序销毁掉已关闭的消息对话框时,对话框上面的按钮和标签一起被销毁,就像我们希望的那样,因为这些按钮和标签都是对话框的子对象。2.3.2 信号与槽在 GUI 编程中,当我们改变了一个组件,我们经常需要通知另外的一个组件。更一般地,我们希望任何类型的对象都能够与另外的对象通讯。例如,如果用户点击了关闭按钮,我们希望窗口的 close() 函数被调用。早期工具库对这种通讯使用回调实现。回调是一个指向

5、一个函数的指针,所以如果你希望某种事件发生的时候,处理函数获得通知,你就需要将指向另外函数的指针(也就是这个回调)传递给处理函数。这样,处理函数就会在合适的时候调用回调函数。回调有两个明显的缺点:第一,它们不是类型安全的。我们不能保证处理函数传递给回调函数的参数都是正确的。第二,回调函数和处理函数紧密地耦合在一起,因为处理函数必须知道哪一个函数被回调。在 Qt 中,我们有回调技术之外的选择:信号槽。当特定事件发出时,一个信号会被发出。Qt 组件有很多预定义的信号,同时,我们也可以通过继承这些组件,添加自定义的信号。槽则能够响应特定信号的函数。Qt 组件有很多预定义的槽,但是更常见的是,通过继承

6、组件添加你自己的槽,以便你能够按照自己的方式处理信号。信号槽机制是类型安全的:信号的签名必须同接受该信号的槽的签名一致(实际上,槽的参数个数可以比信号少,因为槽能够忽略信号定义的多出来的参数)。既然签名都是兼容的,那么编译器就可以帮助我们找出不匹配的地方。信号和槽是松耦合的:发出信号的类不知道也不关心哪些槽连接到它的信号。Qt 的信号槽机制保证了,如果你把一个信号同一个槽连接,那么在正确的时间,槽能够接收到信号的参数并且被调用。信号和槽都可以有任意类型的任意个数的参数。它们全部都是类型安全的。所有继承自 QObject 或者它的一个子类(例如 QWidget) 都可以包含信号槽。信号在对象改变

7、其状态,并且这个状态可能有别的对象关心时被发出。这就是这个对象为和别的对象交互所做的所有工作。它并不知道也不关心有没有别的对象正在接收它发出的信号。这是真正的信息封装,保证了这个对象能够成为一个组件。槽能够被用于接收信号,也能够像普通函数一样使用。正如一个对象并不知道究竟有没有别的对象正在接收它的信号一样,一个槽也不知道有没有信号与它相连。这保证了使用 Qt 可以创建真正相互独立的组件。你可以将任意多个信号连接到同一个槽上,也可能将一个信号连接任意多个槽。同时,也能够直接将一个信号与另一个信号相连(这会使第一个信号发出时,马上发出第二个信号)。总之,信号槽建立起一种非常强大的组件编程机制。2.

8、3.3 事件在Qt中,事件是作为对象处理的,所有事件对象继承自抽象类QEvent。此类用来表示程序内部发生或者来自于外部但应用程序应该知道的动作。事件能够能过被 QObject 的子类接受或者处理,但是通常用在与组件有关的应用中。本文档主要阐述了在一个典型应用中的事件接收与处理。当一个事件产生时,Qt 通过实例化一个 QEvent 的合适的子类来表示它,然后通过调用 event() 函数发送给 QObject 的实例(或者它的子类)。event() 函数本身并不会处理事件,根据事件类型,它将调用相应的事件处理函数,并且返回事件被接受还是被忽略。一些事件,比如 QMouseEvent 和 QKe

9、yEvent,来自窗口系统;有的,比如 QTimerEvent,来自于其他事件源;另外一些则来自应用程序本身。通常事件的处理需要调用一个虚函数。比如,QPaintEvent 事件的处理需要调用 QWidget:paintEvent() 函数。这个虚函数负责做出适当的响应,通常是用来重绘组件。如果你在自己的函数中并不打算实现所有的处理,你可以调用基类的实现。3 系统设计3.1 需求分析v 可随机生成7种基本方块单元v 不同的方块单元具备不同的颜色v 基本方块单元在移动时支持两种操作:旋转、移动v 具备计分及升级系统v 支持虚拟按键3.2 框架设计3.2.1 俄罗斯方块基本规则一个用于摆放小型正方

10、形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名随机发生器不断地输出单个方块到场地顶部,以一定的规则进行移动、旋转、下落和摆放,锁定并填充到场地中。每次摆放如果将场地的一行或多行完全填满,则组成这些行的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响如果未被消除的方块堆放的高度超过场地所规定的最大高度(并不一定是20或者玩家所能见到的高度),则游戏结束3

11、.2.2 系统模块如上图所示,系统可由以下几个模块组成:v 虚拟显示屏:为系统核心模块,负责游戏元素的显示、游戏逻辑的执行、以及游戏状态的维护、接收操作模块的操作信息、为辅助显示模块提供必要的信息v 辅助显示模块:显示下一个方块单元的类型、当前分数、当前等级v 操作区模块:为用户提供操作按键3.3 系统实现系统源文件布局如下: HTetris.pro:系统工程文件 HTetrisWindow.h:HTetrisWindow类声明头文件 HTetrisPiece.h:HTetrisPiece类声明头文件 HTetrisBoard.h:HTetrisBoard类声明头文件 tetris.qrc:系

12、统资源文件,存放了表示方向的图像数据 HTetrisWindow.cpp:HTetrisWindow类的实现 HTetrisPiece.cpp:HTetrisPiece类的实现 HTetrisBoard.cpp:HTetrisBoard类的实现 main.cpp:程序入口main.cpp中初始化一个HTetrisWindow实例,并使其显示。HTetrisWindow对应程序窗口,它包含一个游戏显示区(HTetrisBoard)、辅助显示区、及一些按键,HTetrisWindow在自身的构造函数中完成对这些界面元素的初始化及布局工作,同时建立起必要的信号-槽连接。HTetrisPiece类表示

13、基本方块单元,总共有7种,即I、T、J、L、O、Z、S,用HTetrisPieceShape来标识方块类型。HTetrisPiece提供了设置方块形状、设置旋转、获取方块信息的一些公共成员函数。HTetrisPiece使用coords42这个二维数组来存储方块的形状信息,这个数组的每行表示一个点的坐标。HTetrisBoard是整个程序的核心,相对前两个类,这个类要复杂很多。它提供了如下几个槽:start()、pause()、moveRight()、moveLeft()、moveDown()、rotateRight()、rotateLeft()。提供了scoreChanged与levelCha

14、nged两个信号。paintEvent负责整个HTetrisBoard的重绘。removeFullLines负责判断是否某行全部为方块,如果是,则把该行消除,同时添加一定分数及经验。4 系统测试程序的运行界面如上图所示,经测试,该程序具备了俄罗斯方块游戏的基本功能。5 课程设计总结通过这次嵌入式实验,我对嵌入式技术有了更加深入的了解,在老师悉心帮助下,和其他同学的共同努力下,我们最终圆满地完成了这次课程设计。但是实验中,也暴露了自己在软件运用方面的不足和缺点,以后在这方面上认真学习和研究,争取在毕业之前能更上一层楼。6 附录6.1 参考资料1 2C plus plus GUI Programm

15、ing with Qt 4 2nd Edition3 6.2 程序源码/* *Filename: main.cpp *Author: Hale Chan *Date: 2011-11-24 */#include #include HTetrisWindow.hint main(int argc, char *argv) QApplication app(argc, argv); HTetrisWindow window; window.show(); qsrand(QTime(0,0,0).secsTo(QTime:currentTime(); return app.exec();/* *Fi

16、lename: HTetrisWindow.h *Author: Hale Chan *Date: 2011-11-24 */#ifndef HTetrisWINDOW_H#define HTetrisWINDOW_H#include class HTetrisBoard;class QLabel;class QLCDNumber;class QPushButton;class HTetrisWindow : public QWidgetQ_OBJECTpublic: HTetrisWindow();private: QLabel *createLabel(const QString &tex

17、t); HTetrisBoard *board; QLabel *nextPieceLabel; QLCDNumber *scoreLcd; QLCDNumber *levelLcd; QPushButton *leftButton; QPushButton *rightButton; QPushButton *upButton; QPushButton *downButton; QPushButton *aButton; QPushButton *bButton;#endif / HTetrisWINDOW_H/* *Filename: HTetrisWindow.cpp *Author:

18、Hale Chan *Date: 2011-11-24 */#include HTetrisWindow.h#include HTetrisBoard.h#include HTetrisWindow:HTetrisWindow() board = new HTetrisBoard; nextPieceLabel = new QLabel; nextPieceLabel-setFrameStyle(QFrame:Box | QFrame:Raised); nextPieceLabel-setAlignment(Qt:AlignCenter); nextPieceLabel-setBaseSize

19、(60, 60); nextPieceLabel-setMinimumSize(60, 60); nextPieceLabel-setMaximumSize(60,60); nextPieceLabel-setSizePolicy(QSizePolicy:Fixed, QSizePolicy:Fixed); board-setNextPieceLabel(nextPieceLabel); scoreLcd = new QLCDNumber(6); scoreLcd-setSegmentStyle(QLCDNumber:Filled); scoreLcd-setFixedWidth(70); l

20、evelLcd = new QLCDNumber(1); levelLcd-setSegmentStyle(QLCDNumber:Filled); levelLcd-setFixedWidth(70); leftButton = new QPushButton; leftButton-setAutoRepeat(true); leftButton-setIcon(QIcon(:/images/left.png); rightButton = new QPushButton; rightButton-setAutoRepeat(true); rightButton-setIcon(QIcon(:

21、/images/right.png); upButton = new QPushButton; upButton-setIcon(QIcon(:/images/up.png); downButton = new QPushButton; downButton-setAutoRepeat(true); downButton-setIcon(QIcon(:/images/down.png); aButton = new QPushButton(tr(A); aButton-setFixedWidth(50); bButton = new QPushButton(tr(B); bButton-set

22、FixedWidth(50); connect(leftButton, SIGNAL(clicked(), board, SLOT(moveLeft(); connect(rightButton, SIGNAL(clicked(), board, SLOT(moveRight(); connect(upButton, SIGNAL(clicked(), board, SLOT(pause(); connect(downButton, SIGNAL(clicked(), board, SLOT(moveDown(); connect(aButton, SIGNAL(clicked(), boar

23、d, SLOT(rotateLeft(); connect(bButton, SIGNAL(clicked(), board, SLOT(rotateRight(); connect(board, SIGNAL(levelChanged(int), levelLcd, SLOT(display(int); connect(board, SIGNAL(scoreChanged(int), scoreLcd, SLOT(display(int); QGridLayout *mainLayout = new QGridLayout; mainLayout-addWidget(board, 0, 0,

24、 7, 3, Qt:AlignCenter); mainLayout-addWidget(createLabel(tr(Next), 0, 3, Qt:AlignCenter); mainLayout-addWidget(nextPieceLabel, 1, 3, Qt:AlignCenter); mainLayout-setRowStretch(2, 9); mainLayout-addWidget(createLabel(tr(Score), 3, 3, Qt:AlignCenter); mainLayout-addWidget(scoreLcd, 4, 3, Qt:AlignHCente

25、r | Qt:AlignTop); mainLayout-addWidget(createLabel(tr(Level), 5, 3, Qt:AlignCenter); mainLayout-addWidget(levelLcd, 6, 3, Qt:AlignHCenter | Qt:AlignTop); mainLayout-addWidget(upButton, 7, 1, Qt:AlignBottom); mainLayout-addWidget(aButton, 7, 3, Qt:AlignBottom | Qt:AlignHCenter); mainLayout-addWidget(

26、leftButton, 8, 0, Qt:AlignTop | Qt:AlignLeft); mainLayout-addWidget(downButton, 8, 1, Qt:AlignBottom); mainLayout-addWidget(rightButton, 8, 2, Qt:AlignRight | Qt:AlignTop); mainLayout-addWidget(bButton, 8, 3, Qt:AlignBottom | Qt:AlignHCenter); mainLayout-setRowMinimumHeight(7, 30); mainLayout-setRow

27、MinimumHeight(8, 50); this-setLayout(mainLayout); this-setWindowTitle(tr(Tetris); this-setFixedSize(240, 400);QLabel *HTetrisWindow:createLabel(const QString &text) QLabel *lbl = new QLabel(text); lbl-setAlignment(Qt:AlignHCenter | Qt:AlignBottom); return lbl;/* *Filename: HTetrisPiece.h *Author: Ha

28、le Chan *Date: 2011-11-24 */#ifndef HTetrisPIECE_H#define HTetrisPIECE_Htypedef enum HTetrisPieceShapeNone, HTetrisPieceShapeI, HTetrisPieceShapeT, HTetrisPieceShapeJ, HTetrisPieceShapeL, HTetrisPieceShapeO, HTetrisPieceShapeZ, HTetrisPieceShapeSHTetrisPieceShape;typedef enum HTetrisPieceRotateZero,

29、 HTetrisPieceRotate90, HTetrisPieceRotate180, HTetrisPieceRotate270HTetrisPieceRotate;class HTetrisPiecepublic: HTetrisPiece()setShape(HTetrisPieceShapeNone); void setRandomShape(); void setShape(HTetrisPieceShape shape); HTetrisPieceShape shape() const return pieceShape; int x(int index) const retu

30、rn coordsindex0; int y(int index) const return coordsindex1; int minX() const; int maxX() const; int minY() const; int maxY() const; void setRotate(HTetrisPieceRotate rotate); HTetrisPiece pieceFromRotatedLeft() const; HTetrisPiece pieceFromRotatedRight() const;private: void setX(int index, int x) c

31、oordsindex0 = x; void setY(int index, int y) coordsindex1 = y; HTetrisPieceShape pieceShape; int coords42;#endif / HTetrisPIECE_H/* *Filename: HTetrispiece.cpp *Author: Hale Chan *Date: 2011-11-24 */#include HTetrisPiece.h#include static const int coordsTable842 = 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0

32、, 0, 1, 0, 2, -1, 0, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, 0, 1, -1, 1, 0, -1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, -1, -1, 0, -1, 0, 0, 1, 0, 1, -1, 0, -1, 0, 0, -1, 0;void HTetrisPiece:setRandomShape() setShape(HTetrisPieceShape)(qrand() % 7 + 1);void HTetrisPiece:setShape(HTetrisPieceShape shape) f

33、or (int i=0; i4; i+) coordsi0 = coordsTableshapei0; coordsi1 = coordsTableshapei1; pieceShape = shape;int HTetrisPiece:minX()const int min = coords00; for (int i = 1; i 4; +i) min = qMin(min, coordsi0); return min;int HTetrisPiece:maxX()const int max = coords00; for (int i = 1; i 4; +i) max = qMax(m

34、ax, coordsi0); return max;int HTetrisPiece:minY()const int min = coords01; for (int i = 1; i 4; +i) min = qMin(min, coordsi1); return min;int HTetrisPiece:maxY()const int max = coords01; for (int i = 1; i 4; +i) max = qMax(max, coordsi1); return max;void HTetrisPiece:setRotate(HTetrisPieceRotate rot

35、ate) switch(rotate) case HTetrisPieceRotate90: for(int i=0; i4; i+) int tmp = x(i); setX(i,-y(i); setY(i, tmp); break; case HTetrisPieceRotate180: for(int i=0; i4; i+) setX(i,-x(i); setY(i, -y(i); break; case HTetrisPieceRotate270: for(int i=0; i4; i+) int tmp = x(i); setX(i,y(i); setY(i, -tmp); bre

36、ak; default: break; HTetrisPiece HTetrisPiece:pieceFromRotatedLeft()const if (pieceShape = HTetrisPieceShapeO) return *this; HTetrisPiece result; result.pieceShape = pieceShape; for (int i = 0; i 4; +i) result.setX(i, y(i); result.setY(i, -x(i); return result;HTetrisPiece HTetrisPiece:pieceFromRotat

37、edRight()const if (pieceShape = HTetrisPieceShapeO) return *this; HTetrisPiece result; result.pieceShape = pieceShape; for (int i = 0; i 4; +i) result.setX(i, -y(i); result.setY(i, x(i); return result;/* *Filename: HTetrisBoard.h *Author: Hale Chan *Date: 2011-11-24 */#ifndef HTetrisBOARD_H#define H

38、TetrisBOARD_H#include #include #include #include HTetrisPiece.hclass QLabel;#define HTetrisBoardWidth 10#define HTetrisBoardHeight 20class HTetrisBoard : public QFrame Q_OBJECTpublic: HTetrisBoard(QWidget *parent = 0); void setNextPieceLabel(QLabel *label); QSize sizeHint() const; QSize minimumSizeH

39、int() const;public slots: void start(); void pause(); void moveRight(); void moveLeft(); void moveDown(); void rotateRight(); void rotateLeft();signals: void scoreChanged(int score); void levelChanged(int level);protected: void paintEvent(QPaintEvent *event); void keyPressEvent(QKeyEvent *event); vo

40、id timerEvent(QTimerEvent *event);private: HTetrisPieceShape &shapeAt(int x, int y) return board(y * HTetrisBoardWidth) + x; int timeoutTime() return 1000 / level; int squareWidth() return contentsRect().width() / HTetrisBoardWidth; int squareHeight() return contentsRect().height() / HTetrisBoardHei

41、ght; void clearBoard(); void dropDown(); void oneLineDown(); void pieceDropped(int dropHeight); void removeFullLines(); void newPiece(); void showNextPiece(); bool tryMove(const HTetrisPiece &newPiece, int newX, int newY); void drawSquare(QPainter &painter, int x, int y, HTetrisPieceShape shape); QBasicTimer timer; QPointer nextPieceLabel; bool isStarted; bool isPaused; bool isWaitingAfterLine; bool gameOver; HTetrisPiece curPiece; H

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号