[毕业设计精品] 基于QT的俄罗斯方块设计.doc_第1页
[毕业设计精品] 基于QT的俄罗斯方块设计.doc_第2页
[毕业设计精品] 基于QT的俄罗斯方块设计.doc_第3页
[毕业设计精品] 基于QT的俄罗斯方块设计.doc_第4页
[毕业设计精品] 基于QT的俄罗斯方块设计.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

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

文档简介

目 录摘要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 程序源码620摘要qt是一个跨平台的c+图形用户界面应用程序框架。本程序利用qt提供的相关类,实现了俄罗斯方块的基本功能。关键字qt、嵌入式、软件开发1 功能说明 支持俄罗斯方块游戏的基本功能 支持虚拟按键2 开发环境操作系统:ubuntu 10.04 lts开发工具:gnu编译工具链(gcc等)、qt creator、qt 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-doc qt4-qtconfig qt-demos3.如果希望构建嵌入式qt开发平台,则需要参考相关开发板的说明,一般是先制作交叉编译工具链、再交叉编译一个用于目标板的qt库,这里不再详述2.3 qt开发基础2.3.1 qt对象与对象树qobject是所有qt类的基类。qobject 组织成为对象树。当你创建 qobject 时,将另外的对象作为其父对象,这个对象就被加入其父对象的 children() 列表,并且当父对象销毁时,这个对象也能够被销毁。事实证明,这种实现方法非常适合 gui 对象。例如,一个 qshortcut(键盘快捷键)对象是相关窗口的子对象,所以当用户关闭窗口时,这个对象也能够被删除。qwidget 作为所有能够显示在屏幕上的组件的父类,扩展了这种父子关系。一个子对象通常也成为一个子组件,就是说,它被显示在父组件的坐标系统中,受到父组件的边界影响可能会有剪切等等。例如,当应用程序销毁掉已关闭的消息对话框时,对话框上面的按钮和标签一起被销毁,就像我们希望的那样,因为这些按钮和标签都是对话框的子对象。2.3.2 信号与槽在 gui 编程中,当我们改变了一个组件,我们经常需要通知另外的一个组件。更一般地,我们希望任何类型的对象都能够与另外的对象通讯。例如,如果用户点击了关闭按钮,我们希望窗口的 close() 函数被调用。早期工具库对这种通讯使用回调实现。回调是一个指向一个函数的指针,所以如果你希望某种事件发生的时候,处理函数获得通知,你就需要将指向另外函数的指针(也就是这个回调)传递给处理函数。这样,处理函数就会在合适的时候调用回调函数。回调有两个明显的缺点:第一,它们不是类型安全的。我们不能保证处理函数传递给回调函数的参数都是正确的。第二,回调函数和处理函数紧密地耦合在一起,因为处理函数必须知道哪一个函数被回调。在 qt 中,我们有回调技术之外的选择:信号槽。当特定事件发出时,一个信号会被发出。qt 组件有很多预定义的信号,同时,我们也可以通过继承这些组件,添加自定义的信号。槽则能够响应特定信号的函数。qt 组件有很多预定义的槽,但是更常见的是,通过继承组件添加你自己的槽,以便你能够按照自己的方式处理信号。信号槽机制是类型安全的:信号的签名必须同接受该信号的槽的签名一致(实际上,槽的参数个数可以比信号少,因为槽能够忽略信号定义的多出来的参数)。既然签名都是兼容的,那么编译器就可以帮助我们找出不匹配的地方。信号和槽是松耦合的:发出信号的类不知道也不关心哪些槽连接到它的信号。qt 的信号槽机制保证了,如果你把一个信号同一个槽连接,那么在正确的时间,槽能够接收到信号的参数并且被调用。信号和槽都可以有任意类型的任意个数的参数。它们全部都是类型安全的。所有继承自 qobject 或者它的一个子类(例如 qwidget) 都可以包含信号槽。信号在对象改变其状态,并且这个状态可能有别的对象关心时被发出。这就是这个对象为和别的对象交互所做的所有工作。它并不知道也不关心有没有别的对象正在接收它发出的信号。这是真正的信息封装,保证了这个对象能够成为一个组件。槽能够被用于接收信号,也能够像普通函数一样使用。正如一个对象并不知道究竟有没有别的对象正在接收它的信号一样,一个槽也不知道有没有信号与它相连。这保证了使用 qt 可以创建真正相互独立的组件。你可以将任意多个信号连接到同一个槽上,也可能将一个信号连接任意多个槽。同时,也能够直接将一个信号与另一个信号相连(这会使第一个信号发出时,马上发出第二个信号)。总之,信号槽建立起一种非常强大的组件编程机制。2.3.3 事件在qt中,事件是作为对象处理的,所有事件对象继承自抽象类qevent。此类用来表示程序内部发生或者来自于外部但应用程序应该知道的动作。事件能够能过被 qobject 的子类接受或者处理,但是通常用在与组件有关的应用中。本文档主要阐述了在一个典型应用中的事件接收与处理。当一个事件产生时,qt 通过实例化一个 qevent 的合适的子类来表示它,然后通过调用 event() 函数发送给 qobject 的实例(或者它的子类)。event() 函数本身并不会处理事件,根据事件类型,它将调用相应的事件处理函数,并且返回事件被接受还是被忽略。一些事件,比如 qmouseevent 和 qkeyevent,来自窗口系统;有的,比如 qtimerevent,来自于其他事件源;另外一些则来自应用程序本身。通常事件的处理需要调用一个虚函数。比如,qpaintevent 事件的处理需要调用 qwidget:paintevent() 函数。这个虚函数负责做出适当的响应,通常是用来重绘组件。如果你在自己的函数中并不打算实现所有的处理,你可以调用基类的实现。3 系统设计3.1 需求分析v 可随机生成7种基本方块单元v 不同的方块单元具备不同的颜色v 基本方块单元在移动时支持两种操作:旋转、移动v 具备计分及升级系统v 支持虚拟按键3.2 框架设计3.2.1 俄罗斯方块基本规则一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位一组由4个小型正方形组成的规则图形,英文称为tetromino,中文通称为方块共有7种,分别以s、z、l、j、i、o、t这7个字母的形状来命名随机发生器不断地输出单个方块到场地顶部,以一定的规则进行移动、旋转、下落和摆放,锁定并填充到场地中。每次摆放如果将场地的一行或多行完全填满,则组成这些行的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响如果未被消除的方块堆放的高度超过场地所规定的最大高度(并不一定是20或者玩家所能见到的高度),则游戏结束3.2.2 系统模块如上图所示,系统可由以下几个模块组成:v 虚拟显示屏:为系统核心模块,负责游戏元素的显示、游戏逻辑的执行、以及游戏状态的维护、接收操作模块的操作信息、为辅助显示模块提供必要的信息v 辅助显示模块:显示下一个方块单元的类型、当前分数、当前等级v 操作区模块:为用户提供操作按键3.3 系统实现系统源文件布局如下: ht:系统工程文件 htetriswindow.h:htetriswindow类声明头文件 htetrispiece.h:htetrispiece类声明头文件 htetrisboard.h:htetrisboard类声明头文件 tetris.qrc:系统资源文件,存放了表示方向的图像数据 htetriswindow.cpp:htetriswindow类的实现 htetrispiece.cpp:htetrispiece类的实现 htetrisboard.cpp:htetrisboard类的实现 main.cpp:程序入口main.cpp中初始化一个htetriswindow实例,并使其显示。htetriswindow对应程序窗口,它包含一个游戏显示区(htetrisboard)、辅助显示区、及一些按键,htetriswindow在自身的构造函数中完成对这些界面元素的初始化及布局工作,同时建立起必要的信号-槽连接。htetrispiece类表示基本方块单元,总共有7种,即i、t、j、l、o、z、s,用htetrispieceshape来标识方块类型。htetrispiece提供了设置方块形状、设置旋转、获取方块信息的一些公共成员函数。htetrispiece使用coords42这个二维数组来存储方块的形状信息,这个数组的每行表示一个点的坐标。htetrisboard是整个程序的核心,相对前两个类,这个类要复杂很多。它提供了如下几个槽:start()、pause()、moveright()、moveleft()、movedown()、rotateright()、rotateleft()。提供了scorechanged与levelchanged两个信号。paintevent负责整个htetrisboard的重绘。removefulllines负责判断是否某行全部为方块,如果是,则把该行消除,同时添加一定分数及经验。4 系统测试程序的运行界面如上图所示,经测试,该程序具备了俄罗斯方块游戏的基本功能。5 课程设计总结通过这次嵌入式实验,我对嵌入式技术有了更加深入的了解,在老师悉心帮助下,和其他同学的共同努力下,我们最终圆满地完成了这次课程设计。但是实验中,也暴露了自己在软件运用方面的不足和缺点,以后在这方面上认真学习和研究,争取在毕业之前能更上一层楼。6 附录6.1 参考资料1/4.6/ 2c plus plus gui programming 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();/* *filename: 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 &text); 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: 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(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); levellcd = 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(:/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-setfixedwidth(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(), board, 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, 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:alignhcenter | 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(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-setrowminimumheight(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: hale chan *date: 2011-11-24 */#ifndef htetrispiece_h#define htetrispiece_htypedef enum htetrispieceshapenone, htetrispieceshapei, htetrispieceshapet, htetrispieceshapej, htetrispieceshapel, htetrispieceshapeo, htetrispieceshapez, htetrispieceshapeshtetrispieceshape;typedef enum htetrispiecerotatezero, htetrispiecerotate90, htetrispiecerotate180, htetrispiecerotate270htetrispiecerotate;class htetrispiecepublic: htetrispiece()setshape(htetrispieceshapenone); void setrandomshape(); void setshape(htetrispieceshape shape); htetrispieceshape 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; void setrotate(htetrispiecerotate rotate); htetrispiece piecefromrotatedleft() const; htetrispiece piecefromrotatedright() const;private: void setx(int index, int x) coordsindex0 = 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, 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) for (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(max, 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 rotate) 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); break; 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:piecefromrotatedright()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 htetrisboard_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 minimumsizehint() 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); void 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() / htetrisboardheight; 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; htetrispiece nextpiece; int curx; int cury; int score; int level; int exp; htetrispieceshape boardhtetrisboardwidth * htetrisboardheight;#endif / htetrisboard_h/* *filename: htetrisboard.cpp *author: hale chan *date: 2011-11-24 */#include #include htetrisboard.hstatic const qrgb colortable8 = 0x000000, 0x00f0f0, 0xa000f0, 0x0000f0, 0xf0a000, 0xf0f000, 0xf00000, 0x00f000;htetrisboard:htetrisboard(qwidget *parent) : qframe(parent) setframestyle(qframe:panel | qframe:sunken); setfocuspolicy(qt:strongfocus); isstarted = false; ispaused = false; gameover = false; clearboard(); nextpiece.setrandomshape(); nextpiece.setrotate(htetrispiecerotate)(qrand()%4);void htetrisboard:setnextpiecelabel(qlabel *label) nextpiecelabel = label;qsize htetrisboard:sizehint() const return qsize(htetrisboardwidth * 15 + framewidth() * 2, htetrisboardheight * 15 + framewidth() * 2);qsize htetrisboard:minimumsizehint() const return qsize(htetrisboardwidth * 5 + framewidth() * 2, htetrisboardheight * 5 + framewidth() * 2);void htetrisboard:start() if (ispaused) return; isstarted = true; gameover = false; iswaitingafterline = false; score = 0; level = 1; clearboard(); emit scorechanged(score); emit levelchanged(level); newpiece(); timer.start(timeouttime(), this);void htetrisboard:pause() if (!isstarted) start(); return; ispaused = !ispaused; if (ispaused) timer.stop(); else timer.start(timeouttime(), this); update();void hte

温馨提示

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

最新文档

评论

0/150

提交评论