关于俄罗斯方块的嵌入式设计报告

合集下载

在Linux系统下基于ARM嵌入式的俄罗斯方块

在Linux系统下基于ARM嵌入式的俄罗斯方块

目录一、摘要 (3)二、各种问题的具体介绍(1)图形的如何存储问题 (3)(2)图形的染色问题 (3)(3)游戏的屏幕显示问题 (3)(4)方块图形的自动下移问题 (3)(5)方块图形的左右移动问题 (3)(6)方块图形的如何翻转问题 (3)(7)图形移动时的自动消行问题 (3)(8)图形移动翻转时的边界判断问题 (3)(9)如何实现一键到底的问题 (3)(10)各种移动的用键问题 (3)(11)游戏时的自动冒行问题 (3)(12)游戏时的作弊消行问题 (3)(13)游戏时作弊方块出现问题 (3)(14)游戏时的作弊炸弹使用问题 (4)三、流程图流程图 (5)四、实习总结实习总结 (6)五、附件(1)程序源代码 (6)(2)操作截图 (18)六、参考文献 (21)一、摘要在Linux系统下使用vim编辑器实现如手机上的游戏俄罗斯方块,利用所学知识实现以下的各个问题。

二、各种问题的具体介绍(1)图形的存储问题:每个方块采用一个4 * 4的小数组存储,不同的方块给对应的数组赋不同的值,从1~7,以便打印是染不同的颜色,实现每种方块都有不同的颜色。

(2)图形的染色问题:使用VT控制码对不同的图形涂不同的颜色。

(3)游戏屏幕的显示问题:采用一个20 * 12的大数组,数组元素全部赋值为0,在终端打印空格,形成一片矩形区域,每个俄罗斯方块(以下简称方块)占4 * 4个空格的区域,赋值给大数组即可在终端打印出方块。

在大数组的上方再打印一个4 * 4的小数组,以显示下一个将出现的方块,并打印出得分,等级,计时等。

(4)方块图形的自动下移问题:有一个变量记录方块下移的行数,并像左右移动一样打印向下移动的方块,设置一个信号,每一秒发送一个信号,进程每收到一次信号变量加一实现自动下移。

(5)方块图形的左右移动问题:有一个变量记录方块第一行一列的坐标,左移时变量减一,右移时变量加一,把小数组原来在大数组的位置清零,在把小数组赋值到大数组相应坐标的位置即可打印出移动后的方块的位置,实现方块的左右移动。

关于俄罗斯方块的嵌入式设计报告

关于俄罗斯方块的嵌入式设计报告

摘要Qt是一个跨平台的C++图形用户界面应用程序框架。

本程序利用Qt提供的相关类,实现了俄罗斯方块的基本功能。

关键字:QT、嵌入式、软件开发一.功能说明✧支持俄罗斯方块游戏的基本功能✧支持虚拟按键二.开发环境操作系统:ubuntu 10.04 LTS;开发工具:gnu编译工具链(gcc等)、Qt Creator、Qt 4.6.2。

2.1 Qt简介Qt是跨平台的应用程序和UI框架。

它包括跨平台类库、集成开发工具和跨平台IDE。

使用Qt,只需一次性开发应用程序,无须重新编写源代码,便可跨不同桌面和嵌入式操作系统部署这些应用程序。

2.2Qt开发基础2.2.1Qt对象与对象树QObject是所有Qt类的基类。

QObject 组织成为对象树。

当你创建QObject 时,将另外的对象作为其父对象,这个对象就被加入其父对象的children() 列表,并且当父对象销毁时,这个对象也能够被销毁。

事实证明,这种实现方法非常适合GUI 对象。

例如,一个QShortcut(键盘快捷键)对象是相关窗口的子对象,所以当用户关闭窗口时,这个对象也能够被删除。

QWidget 作为所有能够显示在屏幕上的组件的父类,扩展了这种父子关系。

一个子对象通常也成为一个子组件,就是说,它被显示在父组件的坐标系统中,受到父组件的边界影响可能会有剪切等等。

例如,当应用程序销毁掉已关闭的消息对话框时,对话框上面的按钮和标签一起被销毁,就像我们希望的那样,因为这些按钮和标签都是对话框的子对象。

2.2.2信号与槽在GUI 编程中,当我们改变了一个组件,我们经常需要通知另外的一个组件。

更一般地,我们希望任何类型的对象都能够与另外的对象通讯。

例如,如果用户点击了关闭按钮,我们希望窗口的close() 函数被调用。

早期工具库对这种通讯使用回调实现。

回调是一个指向一个函数的指针,所以如果你希望某种事件发生的时候,处理函数获得通知,你就需要将指向另外函数的指针(也就是这个回调)传递给处理函数。

俄罗斯方块实验报告

俄罗斯方块实验报告

邮电大学通达学院算法与数据结构设计报告(2016/ 2017学年第二学期)专业软件工程嵌入式学号姓名学号姓名学号姓名指导教师指导单位计算机学院计算机科学与技术系日期2017-5-26目录课题容---------------------------------------1算法设计与分析---------------------------------1 算法实现---------------------------------------9测试数据及结果分析----------------------------38 调试过程中的问题------------------------------40 总结------------------------------------------41俄罗斯方块一、课题容实现俄罗斯方块游戏。

主要功能为游戏界面显示、上下左右键响应以及当前得分统计。

通过该课题全面熟悉数组、字符串等的使用。

掌握设计的基本方法及友好界面的设计。

课题要求:1、游戏界面显示:下落方块和方块堆、左右移动、旋转、删除行等特效以及得分。

2、动作选择:上下左右键对应于旋转、加速、左右移动的功能。

3、得分统计判断:判定能否消除行、并统计得分总数等。

扩展要求:1、用户数据管理。

2、游戏玩法:由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。

这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。

没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。

基本规则1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位。

2、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。

嵌入式实验报告_俄罗斯方块实验报告

嵌入式实验报告_俄罗斯方块实验报告

嵌⼊式实验报告_俄罗斯⽅块实验报告俄罗斯⽅块实验报告班级电⼦班学号******* 姓名**实验名称俄罗斯⽅块⼀、设计⽬标和要求:1、实现多个模块的驱动:液晶、按键、定时器等。

综合多个模块的协调运⾏。

2、设计游戏运⾏的⾏为仲裁引擎,合理设计前景和背景的相对关系。

3、通过ucos2操作系统,合理实现多任务的协调运⾏。

4、完成考核要求:①在液晶上画出欢迎界⾯。

②开启定时器,定时刷新页⾯。

③俄罗斯⽅块满⾏时消⾏,并计数。

④当⽅块叠加到页⾯顶时,结束游戏。

⼆、实验环境:硬件:PC机、嵌⼊式系统实验箱,串⼝线。

软件: windows,编译器三、设计思路和实现步骤、内容:1、设计思路:俄罗斯⽅块游戏软件基于ARM的Windowns CE平台进⾏写操作,利⽤PXA270RP实验箱模拟仿真器,利⽤evc编程来具体实现,在实验箱的触摸屏上进⾏游戏。

⾸先对俄罗斯⽅块的设计和功能需求进⾏详细的了解和分析,如下图1是俄罗斯⽅块总体设计功能图。

开始结束设计消⾏设计转换设计俄罗斯⽅块游戏设计游戏计积分等级设计系统帮助说明操作设计界⾯分布设计⽅块设计游戏帮助系统说明图1 俄罗斯⽅块总体设计功能图(1)游戏界⾯设计:分别是游戏显⽰界⾯,下⼀个⽅块下落界⾯,积分和等级记录界⾯,开始结束暂停按钮,⽅块形态位置变化操作按钮。

(2)操作设计:①游戏开始结束暂停操作设计:在游戏界⾯上有开始、结束、暂停按钮,⽤⿏标操作,选择是否要进⼊游戏。

②⽅块形状转换操作:良好的⽅块形状设计,绘制七种常见的基本图形(长条形、Z字形、反Z形、⽥字形、7字形、反7形、T 字型),各个⽅块要能实现它的变形,统⼀设为逆时针变形。

如下图2所⽰为俄罗斯⽅块定位点设置表。

当⽅块下落时,可通过键盘⽅向键(上、下、左、右键)对该⽅块进⾏向上(变形),向下(加速)、向左、向右移动。

俄罗斯⽅块定位点设置,以⿊⾊点为(0,0)坐标状态类型 1 2 3 44567图2 俄罗斯⽅块⽅块形状图③消⾏操作设计:当⽅块落到游戏界⾯最底部并且铺满最后⼀⾏,就能消去所在这⼀⾏,积分增加100分,⽽积分增加到⼀定数值时,玩家等级增加。

俄罗斯方块游戏设计报告

俄罗斯方块游戏设计报告

俄罗斯方块游戏设计报告【引言】【设计理念】1.目标:游戏的目标是通过操作和放置不同形状的方块,使它们在游戏区域中连成一行或多行,以获得分数。

2.简单易上手:俄罗斯方块游戏以其简单易上手的特点而受到玩家的喜爱。

设计时应注意保持游戏的简洁性,使玩家能够快速上手并迅速融入游戏。

3.挑战性:尽管游戏规则简单,但由于方块的随机性和加速度的增加,游戏也具备一定的挑战性。

设计时要注意保持游戏的平衡,使玩家能够享受游戏的挑战。

【游戏要点】1.游戏区域:游戏区域是一个矩形网格,由多个方格组成。

玩家需要在游戏区域内操作和放置方块。

2.方块种类:方块由四个小方块组成,每个小方块可以是不同的颜色。

常见的方块种类有:直线、方块、L形、反L形、Z形和反Z形。

3.方块操作:玩家可以通过键盘或触摸屏操作方块的移动和旋转。

方块可以向左、向右、向下移动,以及顺时针或逆时针旋转。

4.方块放置:当玩家将一个方块放置在游戏区域中时,方块将固定在该位置并不能再进行移动。

5.消除行:当一行或多行的方块完全填满时,这些方块将会被消除,玩家将得到分数。

消除多行的同时会获得更高的积分。

6.加速度:随着时间的推移,方块的下降速度将会逐渐增加,增加游戏的难度。

7.游戏结束:当游戏区域中的方块堆叠到达顶部时,游戏结束。

【游戏设计】1.游戏界面设计:a.主菜单:包含开始游戏、设置、退出等选项。

b.游戏区域:显示游戏的主要内容,包括方块、分数、下一个方块等。

c.分数和排行榜:显示玩家的最高分数和排名信息。

d.设置界面:包含音效、游戏速度等设置选项。

e.游戏结束界面:显示玩家的得分和排名,并提供重新开始和返回主菜单的选项。

2.游戏逻辑和算法设计:a.方块生成:通过随机算法生成各种类型的方块,并在游戏区域中显示当前方块和下一个方块。

b.方块移动:根据玩家的操作,判断方块能否向左、向右、向下或旋转,并更新方块的位置和状态。

c.方块回合:当方块不能再向下移动时,方块将固定在游戏区域中,并进行消行检测和分数计算。

俄罗斯方块设计报告书

俄罗斯方块设计报告书

软件体系结构设计课程设计报告课程设计题目:俄罗斯方块小游戏专业名称:软件工程2017 年6月30日一、简介1.1俄罗斯方块游戏简介《俄罗斯方块》(Tetris,俄文:Тетрис)是一款由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的休闲游戏。

由小方块组成的不同形状的板块陆续从屏幕上方落下来,玩家通过调整板块的位置和方向,使它们在屏幕底部拼出完整的一条或几条。

这些完整的横条会随即消失,给新落下来的板块腾出空间,与此同时,玩家得到分数奖励。

没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,玩家便告输,游戏结束。

1.2 俄罗斯方块游戏规则1.游戏主画面在一个用于摆放方块的面板上2.(1)一组由4个小型正方形组成的规则图形(即方块)共有7种形状,分别为一字形、田字形、7字形、反7形、Z形、反Z形、T形。

(2)一字形:一次最多消除四层田字形:消除一至二层7字形:最多消除三层,或消除二层反7形:最多消除三层,或消除二层Z形:最多二层,容易造成孔洞反Z形:最多二层,容易造成孔洞T形:最多二层3. 方块从区域上方开始下落,玩者可以按指定按钮左右移动方块、逆时针旋转方块,以及让方块加速落下。

4. 方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。

5. 当区域中某一行横向格子全部由方块填满,则该列会消失,玩家得分。

6. 当固定的方块累积堆到一定层数(设计游戏时设置)时,游戏结束。

7. 游戏会提示下一个要落下的方块形状。

二、需求分析与游戏设计2.2 需求分析2.2.1 游戏界面需求良好的用户界面设计。

本游戏主要有三个界面,一是主游戏区的面板,显示变化和下落的方块;二是用于放置按钮以及显现游戏信息的面板,三是双人对战时用以显示对方游戏信息的面板。

2.2.2 方块控制需求方块下落时,可通过特定按钮对该方块进行翻转、加速,以及向左、向右移动等操作。

2.2.3 图形显示需求随机给出不同的形状(一字形、田字形、7字形、反7形、Z形、反Z形、T形),下落填充给定的区域,填满一行则消掉记分,方块累积到一定层数无法再消去行时游戏结束。

嵌入式软件开发课程设计俄罗斯方块游戏

嵌入式软件开发课程设计俄罗斯方块游戏

嵌入式软件开发课程设计俄罗斯方块游戏淮海工学院计算机工程学院课程设计报告设计名称:嵌入式软件课程设计姓名:学号:专业班级:系(院):计算机工程学院设计时间:设计地点:硬件综合室5.设计详细说明续1(2)硬件原理图及相关说明 Android 有丰富的功能,因此很容易与桌面操作系统混淆。

Android 是一个分层的环境,构建在 Linux 内核的基础上,它包括丰富的功能。

UI 子系统包括:窗口,视图。

用于显示一些常见组件(例如编辑框、列表和下拉列表)的小部件。

Android 包括一个构建在 WebKit 基础上的可嵌入浏览器,iPhone 的 Mobile Safari 浏览器同样也是以 WebKit 为基础。

Android 提供多种连接选项,包括 WiFi、蓝牙和通过蜂窝(cellular)连接的无线数据传输(例如 GPRS、EDGE 和 3G)。

Android 应用程序中一项流行的技术是链接到 Google 地图,以便在应用程序中显示地址。

Android 软件栈还提供对基于位置的服务(例如 GPS)和加速计的支持,不过并不是所有的 Android 设备都配备了必需的硬件。

另外还有摄像支持。

过去,移动应用程序努力向桌面应用程序看齐的两个领域分别是图形/媒体和数据存储方法。

Android 通过提供对2D 和 3D 图形的内置支持,包括 OpenGL 库,解决了图形方面的挑战。

由于 Android 平台包括流行的开源 SQLite 数据库,因此缓解了数据存储的负担。

应用程序架构。

如前所述,Android 运行在 Linux 内核上。

Android 应用程序是用Java 编程语言编写的,它们在一个虚拟机(VM)中运行。

需要注意的是,这个 VM 并非您想象中的 JVM,而是 Dalvik Virtual Machine,这是一种开源技术。

每个 Android 应用程序都在Dalvik VM 的一个实例中运行,这个实例驻留在一个由 Linux 内核管理的进程中。

毕业设计(论文)-基于niosii的俄罗斯方块游戏设计与实现[管理资料]

毕业设计(论文)-基于niosii的俄罗斯方块游戏设计与实现[管理资料]

论文编码(原论文分类号):TP39首都师范大学本科学生毕业论文基于NIOS II的俄罗斯方块设计与实现The Design and Implementation of Russian boxBased on NIOS II论文作者院系信息工程学院专业计算机科学与技术学号指导老师完成日期2010年5月10日提要俄罗新方块游戏是一种古老而又有趣的游戏,游戏软件不计其数,本设计的实现是基于NIOS II的俄罗斯方块设计与实现,采用SOPC技术方案和基于NIOS II处理器开发游戏,尝试着把NIOS II软核处理器系统应用到俄罗斯方块游戏中,实现对游戏的控制功能。

SOPC即可编程片上系统,是一种特殊的嵌入式系统,它结合了SOC和PLD、FPGA各自的优点,具有多方面的特点,譬如,至少包含一个嵌入式处理器内核、丰富的IP Core资源可供选择、有足够的片上可编程逻辑资源、低功耗、微封装等优点,提高了应用上的灵活性。

同时,在开发周期个价格上具有极大的优势。

在构造基于NIOS II嵌入式处理器的俄罗斯方块游戏系统中,通过软核中的VGA显示与DE2-70开发板的硬件连接,成功的在显示器上进行游戏运行。

NIOS IDE中并采用C语言设计了运行于该系统上的俄罗斯方块游戏。

通过DE2-70开发板上的按钮输入,实现了俄罗斯方块的移动、旋转、消除满行、计分和加速等功能。

经过实验和测试结果的验证,证明本系统设计的正确性和基于NIOS II处理器开发游戏的可行性,为NIOS II处理器开发游戏奠定了技术基础。

关键词:SOPC NIOS II VGA俄罗斯方块游戏DE2-70AbstractRussia is an ancient puzzle game new and fun games, games software countless realization of this design is based on the Russian box NIOS II design and implementation of programs using SOPC technology and develop games based on the Nios Ⅱ processor, try with the Nios Ⅱ soft core processor system applied to the Tetris game, to achieve control of the game. SOPC can be programmed on-chip system, is a special embedded system, which combines the SOC and the PLD, FPGA respective advantages, they had many characteristics, for example, contains at least one embedded processor core, rich IP Core Resources to choose from, there are enough resources for programmable logic chip, low power, the advantages of micro-encapsulation to improve the application flexibility. Meanwhile, prices in the development cycle a great advantage.In the structure embedded processor-based Nios Ⅱ Tetris game system, through the soft core of the VGA display and DE2-70 development board's hardware connection, the success of the game running on the display. NIOS IDE and use in the C language designed to run on the system on the Tetris game. DE2-70 development board through the button input, to achieve the movement of the Russian box, rotate, eliminate full-line, scoring and accelerated functions.Through experiments and test results have proved the correctness of the system design and develop games based on the Nios Ⅱ processor feasibility of developing games for the Nios Ⅱprocessor technical basis.Keywords:SOPC NIOS II VGA Tetris Games DE2-70目录第一章引言 (1)第二章绪论 (2)研究的目的和意义 (2)研究的基础、背景和现状 (3)应用的相关技术 (5)SOPC技术 (5)开发环境 (6)硬件描述语言——Verilog HDL (7)第三章 VGA显示的实现 (8)VGA显示原理 (8)VGA色彩显示 (10)VGA时序分析 (11)VGA时序实现 (12)用V ERILOG HDL描述VGA (12)第四章俄罗斯方块硬件设计 (14)系统需求和设计思路 (14)硬件系统结构 (14)基于N IOS II的硬件开发设计 (15)Quartus II软件设计 (15)SOPC Builder组件添加 (19)第五章 NIOS II软件设计 (30)功能描述 (31)功能模块设计 (33)游戏执行的主要流程 (33)游戏方块功能 (35)数据结构设计 (36)函数功能描述 (38)程序实现 (39)第六章俄罗斯方块结果演示及分析 (42)收获、体验和致谢 (44)参考文献 (45)第一章引言由莫斯科数学家亚历克西·帕杰诺夫(Alexey pajitnov)所设计的“俄罗斯方块”被公认为有史以来最畅销的游戏,至今魅力不减。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

摘要Qt是一个跨平台的C++图形用户界面应用程序框架。

本程序利用Qt提供的相关类,实现了俄罗斯方块的基本功能。

关键字:QT、嵌入式、软件开发一.功能说明✧支持俄罗斯方块游戏的基本功能✧支持虚拟按键二.开发环境操作系统:ubuntu 10.04 LTS;开发工具:gnu编译工具链(gcc等)、Qt Creator、Qt 4.6.2。

2.1 Qt简介Qt是跨平台的应用程序和UI框架。

它包括跨平台类库、集成开发工具和跨平台IDE。

使用Qt,只需一次性开发应用程序,无须重新编写源代码,便可跨不同桌面和嵌入式操作系统部署这些应用程序。

2.2Qt开发基础2.2.1Qt对象与对象树QObject是所有Qt类的基类。

QObject 组织成为对象树。

当你创建QObject 时,将另外的对象作为其父对象,这个对象就被加入其父对象的children() 列表,并且当父对象销毁时,这个对象也能够被销毁。

事实证明,这种实现方法非常适合GUI 对象。

例如,一个QShortcut(键盘快捷键)对象是相关窗口的子对象,所以当用户关闭窗口时,这个对象也能够被删除。

QWidget 作为所有能够显示在屏幕上的组件的父类,扩展了这种父子关系。

一个子对象通常也成为一个子组件,就是说,它被显示在父组件的坐标系统中,受到父组件的边界影响可能会有剪切等等。

例如,当应用程序销毁掉已关闭的消息对话框时,对话框上面的按钮和标签一起被销毁,就像我们希望的那样,因为这些按钮和标签都是对话框的子对象。

2.2.2信号与槽在GUI 编程中,当我们改变了一个组件,我们经常需要通知另外的一个组件。

更一般地,我们希望任何类型的对象都能够与另外的对象通讯。

例如,如果用户点击了关闭按钮,我们希望窗口的close() 函数被调用。

早期工具库对这种通讯使用回调实现。

回调是一个指向一个函数的指针,所以如果你希望某种事件发生的时候,处理函数获得通知,你就需要将指向另外函数的指针(也就是这个回调)传递给处理函数。

这样,处理函数就会在合适的时候调用回调函数。

回调有两个明显的缺点:第一,它们不是类型安全的。

我们不能保证处理函数传递给回调函数的参数都是正确的。

第二,回调函数和处理函数紧密地耦合在一起,因为处理函数必须知道哪一个函数被回调。

在Qt 中,我们有回调技术之外的选择:信号槽。

当特定事件发出时,一个信号会被发出。

Qt 组件有很多预定义的信号,同时,我们也可以通过继承这些组件,添加自定义的信号。

槽则能够响应特定信号的函数。

Qt 组件有很多预定义的槽,但是更常见的是,通过继承组件添加你自己的槽,以便你能够按照自己的方式处理信号。

信号槽机制是类型安全的:信号的签名必须同接受该信号的槽的签名一致(实际上,槽的参数个数可以比信号少,因为槽能够忽略信号定义的多出来的参数)。

既然签名都是兼容的,那么编译器就可以帮助我们找出不匹配的地方。

信号和槽是松耦合的:发出信号的类不知道也不关心哪些槽连接到它的信号。

Qt 的信号槽机制保证了,如果你把一个信号同一个槽连接,那么在正确的时间,槽能够接收到信号的参数并且被调用。

信号和槽都可以有任意类型的任意个数的参数。

它们全部都是类型安全的。

所有继承自QObject 或者它的一个子类(例如QWidget)都可以包含信号槽。

信号在对象改变其状态,并且这个状态可能有别的对象关心时被发出。

这就是这个对象为和别的对象交互所做的所有工作。

它并不知道也不关心有没有别的对象正在接收它发出的信号。

这是真正的信息封装,保证了这个对象能够成为一个组件。

槽能够被用于接收信号,也能够像普通函数一样使用。

正如一个对象并不知道究竟有没有别的对象正在接收它的信号一样,一个槽也不知道有没有信号与它相连。

这保证了使用Qt 可以创建真正相互独立的组件。

你可以将任意多个信号连接到同一个槽上,也可能将一个信号连接任意多个槽。

同时,也能够直接将一个信号与另一个信号相连(这会使第一个信号发出时,马上发出第二个信号)。

总之,信号槽建立起一种非常强大的组件编程机制。

2.2.3事件在Qt中,事件是作为对象处理的,所有事件对象继承自抽象类QEvent。

此类用来表示程序内部发生或者来自于外部但应用程序应该知道的动作。

事件能够能过被QObject 的子类接受或者处理,但是通常用在与组件有关的应用中。

本文档主要阐述了在一个典型应用中的事件接收与处理。

当一个事件产生时,Qt 通过实例化一个QEvent 的合适的子类来表示它,然后通过调用event() 函数发送给QObject 的实例(或者它的子类)。

event() 函数本身并不会处理事件,根据事件类型,它将调用相应的事件处理函数,并且返回事件被接受还是被忽略。

一些事件,比如QMouseEvent 和QKeyEvent,来自窗口系统;有的,比如QTimerEvent,来自于其他事件源;另外一些则来自应用程序本身。

通常事件的处理需要调用一个虚函数。

比如,QPaintEvent 事件的处理需要调用QWidget::paintEvent() 函数。

这个虚函数负责做出适当的响应,通常是用来重绘组件。

如果你在自己的函数中并不打算实现所有的处理,你可以调用基类的实现。

三.系统设计3.1需求分析⏹可随机生成7种基本方块单元⏹不同的方块单元具备不同的颜色⏹基本方块单元在移动时支持两种操作:旋转、移动⏹具备计分及升级系统⏹支持虚拟按键3.2框架设计3.2.1俄罗斯方块基本规则一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位。

一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。

随机发生器不断地输出单个方块到场地顶部,以一定的规则进行移动、旋转、下落和摆放,锁定并填充到场地中。

每次摆放如果将场地的一行或多行完全填满,则组成这些行的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。

而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响。

如果未被消除的方块堆放的高度超过场地所规定的最大高度(并不一定是20或者玩家所能见到的高度),则游戏结束。

3.2.2系统模块如上图所示,系统可由以下几个模块组成:虚拟显示屏:为系统核心模块,负责游戏元素的显示、游戏逻辑的执行、以及游戏状态的维护、接收操作模块的操作信息、为辅助显示模块提供必要的信息辅助显示模块:显示下一个方块单元的类型、当前分数、当前等级操作区模块:为用户提供操作按键四.系统实现系统源文件布局如下:✧HTetris.pro:系统工程文件✧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使用coords[4][2]这个二维数组来存储方块的形状信息,这个数组的每行表示一个点的坐标。

HTetrisBoard是整个程序的核心,相对前两个类,这个类要复杂很多。

它提供了如下几个槽:start()、pause()、moveRight()、moveLeft()、moveDown()、rotateRight()、rotateLeft()。

提供了scoreChanged与levelChanged两个信号。

paintEvent负责整个HTetrisBoard的重绘。

removeFullLines负责判断是否某行全部为方块,如果是,则把该行消除,同时添加一定分数及经验。

五.系统测试程序的运行界面如上图所示,经测试,该程序具备了俄罗斯方块游戏的基本功能。

五.小结通过这次嵌入式实验,我对嵌入式技术有了更加深入的了解,在老师悉心帮助下,和其他同学的共同努力下,我们最终圆满地完成了这次课程设计。

但是实验中,也暴露了自己在软件运用方面的不足和缺点,以后在这方面上认真学习和研究,争取在毕业之前能更上一层楼。

六.附录6.1参考资料[1]/4.6/[2]C plus plus GUI Programming with Qt 4 2nd Edition[3]6.2程序源码/**Filename: main.cpp*Author: Hale Chan <halechan@>*Date: 2011-11-24*/#include <QtGui>#include "HTetrisWindow.h"int 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 <halechan@>*Date: 2011-11-24*/#ifndef HTetrisWINDOW_H#define HTetrisWINDOW_H#include <QWidget>class HTetrisBoard;class QLabel;class QLCDNumber;class QPushButton;class HTetrisWindow : public QWidget{Q_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 <halechan@>*Date: 2011-11-24*/#include "HTetrisWindow.h"#include "HTetrisBoard.h"#include <QtGui>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 <halechan@>*Date: 2011-11-24*/#ifndef HTetrisPIECE_H#define HTetrisPIECE_Htypedef enum{HTetrisPieceShapeNone,HTetrisPieceShapeI,HTetrisPieceShapeT,HTetrisPieceShapeJ,HTetrisPieceShapeL,HTetrisPieceShapeO,HTetrisPieceShapeZ,HTetrisPieceShapeS}HTetrisPieceShape;typedef enum{HTetrisPieceRotateZero,HTetrisPieceRotate90,HTetrisPieceRotate180,HTetrisPieceRotate270}HTetrisPieceRotate;class HTetrisPiece{public:HTetrisPiece(){setShape(HTetrisPieceShapeNone);}void setRandomShape();void setShape(HTetrisPieceShape shape);HTetrisPieceShape shape() const { return pieceShape; } int x(int index) const { return coords[index][0]; }int y(int index) const { return coords[index][1]; }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) { coords[index][0] = x; } void setY(int index, int y) { coords[index][1] = y; }HTetrisPieceShape pieceShape;int coords[4][2];};#endif // HTetrisPIECE_H/**Filename: HTetrispiece.cpp*Author: Hale Chan <halechan@>*Date: 2011-11-24*/#include "HTetrisPiece.h"#include <QtCore>static const int coordsTable[8][4][2] = {{{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; i<4; i++){coords[i][0] = coordsTable[shape][i][0];coords[i][1] = coordsTable[shape][i][1];}pieceShape = shape;}int HTetrisPiece::minX()const{int min = coords[0][0];for (int i = 1; i < 4; ++i)min = qMin(min, coords[i][0]);return min;}int HTetrisPiece::maxX()const{int max = coords[0][0];for (int i = 1; i < 4; ++i)max = qMax(max, coords[i][0]);return max;}int HTetrisPiece::minY()const{int min = coords[0][1];for (int i = 1; i < 4; ++i)min = qMin(min, coords[i][1]);return min;}int HTetrisPiece::maxY()const{int max = coords[0][1];for (int i = 1; i < 4; ++i)max = qMax(max, coords[i][1]);return max;}void HTetrisPiece::setRotate(HTetrisPieceRotate rotate) {switch(rotate){case HTetrisPieceRotate90:for(int i=0; i<4; i++){int tmp = x(i);setX(i,-y(i));setY(i, tmp);}break;case HTetrisPieceRotate180:for(int i=0; i<4; i++){setX(i,-x(i));setY(i, -y(i));}break;case HTetrisPieceRotate270:for(int i=0; i<4; 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 <halechan@>*Date: 2011-11-24*/#ifndef HTetrisBOARD_H#define HTetrisBOARD_H#include <QBasicTimer>#include <QFrame>#include <QPointer>#include "HTetrisPiece.h"class 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<QLabel> nextPieceLabel;bool isStarted;bool isPaused;bool isWaitingAfterLine;bool gameOver;HTetrisPiece curPiece;HTetrisPiece nextPiece;int curX;int curY;int score;int level;int exp;HTetrisPieceShape board[HTetrisBoardWidth * HTetrisBoardHeight]; };#endif // HTetrisBOARD_H/**Filename: HTetrisBoard.cpp*Author: Hale Chan <halechan@>*Date: 2011-11-24*/#include <QtGui>#include "HTetrisBoard.h"static const QRgb colorTable[8] = {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 HTetrisBoard::paintEvent(QPaintEvent *event){QFrame::paintEvent(event);QPainter painter(this);QRect rect = contentsRect();int boardTop = rect.bottom() - HTetrisBoardHeight*squareHeight();for (int i = 0; i < HTetrisBoardHeight; ++i) {for (int j = 0; j < HTetrisBoardWidth; ++j) {HTetrisPieceShape shape = shapeAt(j, HTetrisBoardHeight - i - 1); if (shape != HTetrisPieceShapeNone)drawSquare(painter, rect.left() + j * squareWidth(),boardTop + i * squareHeight(), shape);}}if (curPiece.shape() != HTetrisPieceShapeNone) {for (int i = 0; i < 4; ++i) {int x = curX + curPiece.x(i);int y = curY - curPiece.y(i);drawSquare(painter, rect.left() + x * squareWidth(),boardTop + (HTetrisBoardHeight - y - 1) * squareHeight(), curPiece.shape());}}painter.setPen(QColor(255, 0, 0));if (isPaused) {painter.drawText(rect, Qt::AlignCenter, tr("Paused"));}if (gameOver){painter.drawText(rect, Qt::AlignCenter, tr("Game Over"));}}void HTetrisBoard::keyPressEvent(QKeyEvent *event){if (!isStarted || isPaused || curPiece.shape() == HTetrisPieceShapeNone) { if(isPaused && event->key() == Qt::Key_Up){pause();}QFrame::keyPressEvent(event);return;}switch (event->key()) {case Qt::Key_Left:tryMove(curPiece, curX - 1, curY);break;case Qt::Key_Right:tryMove(curPiece, curX + 1, curY);break;case Qt::Key_Down:oneLineDown();break;case Qt::Key_Up:pause();break;case Qt::Key_A:tryMove(curPiece.pieceFromRotatedLeft(), curX, curY);break;case Qt::Key_B:tryMove(curPiece.pieceFromRotatedRight(), curX, curY);break;default:QFrame::keyPressEvent(event);}}void HTetrisBoard::timerEvent(QTimerEvent *event){if (event->timerId() == timer.timerId()) {if (isWaitingAfterLine) {isWaitingAfterLine = false;newPiece();timer.start(timeoutTime(), this);} else {oneLineDown();}} else {QFrame::timerEvent(event);}}void HTetrisBoard::clearBoard(){for (int i = 0; i < HTetrisBoardHeight * HTetrisBoardWidth; ++i) board[i] = HTetrisPieceShapeNone;}void HTetrisBoard::dropDown(){int dropHeight = 0;int newY = curY;while (newY > 0) {if (!tryMove(curPiece, curX, newY - 1))break;--newY;++dropHeight;}pieceDropped(dropHeight);}void HTetrisBoard::oneLineDown(){if (!tryMove(curPiece, curX, curY - 1))pieceDropped(0);}void HTetrisBoard::pieceDropped(int dropHeight){for (int i = 0; i < 4; ++i) {int x = curX + curPiece.x(i);int y = curY - curPiece.y(i);shapeAt(x, y) = curPiece.shape();}exp += 1;score += dropHeight+1;emit scoreChanged(score);removeFullLines();if(exp%50 == 0){level++;timer.start(timeoutTime(), this);emit levelChanged(level);}if (!isWaitingAfterLine)newPiece();}void HTetrisBoard::removeFullLines(){int numFullLines = 0;for (int i = HTetrisBoardHeight - 1; i >= 0; --i) {bool lineIsFull = true;for (int j = 0; j < HTetrisBoardWidth; ++j) {if (shapeAt(j, i) == HTetrisPieceShapeNone) {lineIsFull = false;break;}}if (lineIsFull) {++numFullLines;for (int k = i; k < HTetrisBoardHeight - 1; ++k) {for (int j = 0; j < HTetrisBoardWidth; ++j)shapeAt(j, k) = shapeAt(j, k + 1);}for (int j = 0; j < HTetrisBoardWidth; ++j)shapeAt(j, HTetrisBoardHeight - 1) = HTetrisPieceShapeNone; }}if (numFullLines > 0) {switch(numFullLines){case 1:exp += 1;score += 10;break;case 2:exp += 2;score += 20;break;case 3:exp += 3;score += 30;break;case 4:exp += 5;score += 50;break;}emit scoreChanged(score);timer.start(500, this);isWaitingAfterLine = true;curPiece.setShape(HTetrisPieceShapeNone);update();}}void HTetrisBoard::newPiece(){curPiece = nextPiece;nextPiece.setRandomShape();nextPiece.setRotate((HTetrisPieceRotate)(qrand()%4));showNextPiece();curX = HTetrisBoardWidth / 2;curY = HTetrisBoardHeight - 1 + curPiece.minY();if (!tryMove(curPiece, curX, curY)) {curPiece.setShape(HTetrisPieceShapeNone);timer.stop();isStarted = false;gameOver = true;update();}}void HTetrisBoard::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 < 4; ++i) {int x = nextPiece.x(i) - nextPiece.minX();int y = nextPiece.y(i) - nextPiece.minY();drawSquare(painter, x * squareWidth(), y * squareHeight(),nextPiece.shape());}nextPieceLabel->setPixmap(pixmap);}bool HTetrisBoard::tryMove(const HTetrisPiece &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 < 0 || x >= HTetrisBoardWidth || y < 0 || y >= HTetrisBoardHeight)return false;if (shapeAt(x, y) != HTetrisPieceShapeNone)return false;}curPiece = newPiece;curX = newX;curY = newY;update();return true;}void HTetrisBoard::drawSquare(QPainter &painter, int x, int y, HTetrisPieceShape shape) {QColor color = colorTable[(int)(shape)];painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2, color);painter.setPen(color.light());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);}void HTetrisBoard::moveLeft(){tryMove(curPiece, curX - 1, curY);}void HTetrisBoard::moveRight(){tryMove(curPiece, curX + 1, curY);}void HTetrisBoard::moveDown(){oneLineDown();}void HTetrisBoard::rotateLeft(){tryMove(curPiece.pieceFromRotatedLeft(), curX, curY);}void HTetrisBoard::rotateRight(){tryMove(curPiece.pieceFromRotatedRight(), curX, curY);}。

相关文档
最新文档