资源预览内容
第1页 / 共25页
第2页 / 共25页
第3页 / 共25页
第4页 / 共25页
第5页 / 共25页
第6页 / 共25页
第7页 / 共25页
第8页 / 共25页
第9页 / 共25页
第10页 / 共25页
亲,该文档总共25页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
嵌入式系统开发设计嵌入式系统开发设计 课程设计课程设计 设设计计题题目目 软软件件中中的的典典型型算算法法分分析析 学学院院名名称称 信信息息科科学学与与技技术术学学院院 专专业业名名称称 学学生生姓姓名名 学学生生学学号号 任任课课教教师师 设设计计成成绩绩 教务处教务处 制制 2015 年 3 月 24 日 软件中的典型算法分析软件中的典型算法分析 摘摘 要要 此次课程设计为加农炮游戏,这是一款基于 Linux 平台,运用 Qt Creater 软件开发的一款小游戏。本文将从加农炮的设计及实现出 发,分析在实现过程中的一些典型算法。其中包括坐标转换算法、 碰撞检测算法、边界检测算法、定时器驱动等。 关键词:关键词:坐标转换算法;碰撞检测算法;边界检测算法;定时器驱 动;Qt Creater 1 1、 加农炮整体实现流程加农炮整体实现流程 1.11.1 加农炮设计与实现简述加农炮设计与实现简述 这是一款基于 Linux 平台,运用 Qt Creater 软件开发的一款加 农炮小游戏。游戏的界面为一个窗口,在窗口的右边从上到下以此 是:quit 按钮,该按钮的作用是用于关闭游戏与窗口中的作用相 同;Angel LED 显示屏,屏上显示的数据就是炮台当前的角度,下 边是一个滚动滑条用于控制炮台的角度,炮台角度的范围是 0 度 70 度,当滑条向左边滑动,炮台的角度变小,当滑条向右边滑动, 炮台的角度变大;Force LED 显示屏,屏上显示的数据是炮台射出 的炮弹的力度,下边的滑条用于控制炮台射出炮弹的速度,炮弹的 速度范围是 050,当滑条向右边滑动,炮弹的力度变大,当向左边 滑动,炮弹的力度变小。窗口的上边一栏从左到右分别是:Shoot 按钮,当用户按下这个按钮后炮台会发射一个炮弹,炮弹的轨迹遵 循物理定理,将成一个抛物线运动;Hits LED 显示屏,屏上的数据 显示的是炮台发出的炮弹击中木块的次数,最多显示为 15;Shoots Left LED 显示屏,屏上的数据显示的是炮台还可以发出的炮弹数, 默认的初始值为 15,最小为 0;New Game 按钮,当用户按下这个 按钮时,其将进入一个新游戏,所有的值都变为初始值。窗口的右 下方的大屏幕即为游戏显示界面,炮台位于游戏显示界面的左下角, 在游戏显示界面的任意位置处有一个小木条。当用户打开游戏界面 后按下 Shoot 按钮时,炮台自动发射一个炮弹,如果炮弹击打到小 木块,炮弹和小木块会同时消失,同时会在游戏显示界面的另外一 个任意位置显示出另外一个小木块,如果用户发射出的炮弹没有击 打到小木块,用户可以通过调整炮台的角度,发射炮弹的力度来调 整炮弹的运动轨迹以此来使炮弹能够击打到小木块,当用户发射够 15 枚炮弹是,游戏显示界面会显示 Game Over 同时游戏显示界面 的炮台和炮弹会消失,当没有发射完后,用户继续发射。如果用户 没有发射完炮弹就想进行新游戏,这个操作也是被允许的。 自定义窗口部件: lcdrange.h 包含 LCDRange 类定义。 lcdrange.cpp 包含 LCDRange 类实现。 cannon.h 包含 CannonField 类定义。 cannonfield.cpp 包含 CannonField 类实现。 main.cpp 包含 MyWidget 和 main。 1.21.2 流程图流程图 1.31.3 加农炮模块分析及整体界面加农炮模块分析及整体界面 1.3.11.3.1 按钮按钮 按钮是执行游戏界面的退出功能; 是执行炮弹的发射功能; 按钮式执行新游戏的功能。 1.3.21.3.2 LEDLED 显示显示 击中木块数显示屏; 可发送炮弹数显示屏; 炮台角度显示屏及滑动条; 力度显示屏及滑动条。其中,Angel 和 Force 滚动条,两个 作用分别用于控制炮台的角度与力度。 1.3.31.3.3 加农炮界面加农炮界面 2 2、 坐标转换算法坐标转换算法 2.12.1 坐标转换原理坐标转换原理 我们已经能够使用 QPainter 的相关函数画出一些东西了。接下来, 我们要看的是 QPainter 的坐标系统。 同很多坐标系统一样,QPainter 的默认坐标的原点(0, 0)位于屏 幕的左上角,X 轴正方向是水平向右,Y 轴正方向是竖直向下。在这 个坐标系统中,每个像素占据 1 x 1 的空间。你可以把它想象成是 一张坐标值,其中的每个小格都是 1 个像素。这么说来,一个像素 的中心实际上是一个“半像素坐标系” ,也就是说,像素(x, y)的中 心位置其实是在(x + 0.5, y + 0.5)的位置上。因此,如果我们使 用 QPainter 在(100, 100)处绘制一个像素,那么,这个像素的中心 坐标是(100.5, 100.5)。 这种细微的差别在实际应用中,特别是对坐标要求精确的系统中 是很重要的。首先,只有在禁止反走样,也就是默认状态下,才会 有这 0.5 像素的偏移;如果使用了反走样,那么,我们画(100, 100)位 置的像素时,QPainter 会在(99.5, 99.5),(99.5, 100.5), (100.5, 99.5)和(100.5, 100.5)四个位置绘制一个亮色的像素,这 么产生的效果就是在这四个像素的焦点处(100, 100)产生了一个像 素。如果不需要这个特性,就需要将 QPainter 的坐标系平移(0.5, 0.5)。 这一特性在绘制直线、矩形等图形的时候都会用到。下图给出了 在没有反走样技术时,使用 drawRect(2, 2, 6, 5)绘制一个矩形的 示例。在 No Pen 的情况下,请注意矩形左上角的像素是在(2, 2), 其中心位置是在(2.5, 2.5)的位置。然后注意下有不同的 Pen 的值 的绘制样式,在 Pen 宽为 1 时,实际画出的矩形的面积是 7 x 6 的 (图出自 C+ GUI Programming with Qt4, 2nd Edition): 在具有反走样时,使用 drawRect(2, 2, 6, 5)的效果如下(图出自 C+ GUI Programming with Qt4, 2nd Edition): 注意我们前面说过,通过平移 QPainter 的坐标系来消除着 0.5 像素 的差异。下面给出了使用 drawRect(2.5, 2.5, 6, 5)在反走样情况 下绘制的矩形(图出自 C+ GUI Programming with Qt4, 2nd Edition): 请对比与上图的区别。 在上述的 QPainter 的默认坐标系下,QPainter 提供了视口 (viewport)窗口(window)机制,用于绘制与绘制设备的大小和分辨 率无关的图形。视口和窗口是紧密的联系在一起的,它们一般都是 矩形。视口是由物理坐标确定其大小,而窗口则是由逻辑坐标决定。 我们在使用 QPainter 进行绘制时,传给 QPainter 的是逻辑坐标, 然后,Qt 的绘图机制会使用坐标变换将逻辑坐标转换成物理坐标后 进行绘制。 通常,视口和窗口的坐标是一致的。比如一个 600 x 800 的 widget(这是一个 widget,或许是一个对话框,或许是一个面板等 等),默认情况下,视口和窗口都是一个 320 x 200 的矩形,原点都 在(0, 0),此时,视口和窗口的坐标是相同的。 注意到 QPainter 提供了 setWindow()和 setViewport()函数,用 来设置视口和窗口的矩形大小。比如,在上面所述的 320 x 200 的 widget 中,我们要设置一个从(-50, -50)到(+50, +50),原点在中 心的矩形窗口,就可以使用 painter.setWindow(-50, -50, 100, 100); 其中,(-50, -50)指明了原点,100, 100 指明了窗口的长和宽。 这里的“指明原点”意思是,逻辑坐标的(-50, -50)对应着物理坐 标的(0, 0);“长和宽”说明,逻辑坐标系下的长 100,宽 100 实 际上对应物理坐标系的长 320,宽 200。 或许你已经发现这么一个好处,我们可以随时改变 window 的范围, 而不改变底层物理坐标系。这就是前面所说的,视口与窗口的作用: “绘制与绘制设备的大小和分辨率无关的图形” ,如下图所示: 除了视口与窗口的变化,QPainter 还提供了一个“世界坐标系” , 同样也可以变换图形。所不同的是,视口与窗口实际上是统一图形 在两个坐标系下的表达,而世界坐标系的变换是通过改变坐标系来 平移、缩放、旋转、剪切图形。为了清楚起见,我们来看下面一个 例子: void PaintedWidget:paintEvent(QPaintEvent *event) QPainter painter(this); QFont font(“Courier“, 24); painter.setFont(font); painter.drawText(50, 50, “Hello, world!“); QTransform transform; transform.rotate(+45.0); painter.setWorldTransform(transform); painter.drawText(60, 60, “Hello, world!“); 为了显示方便,我在这里使用了 QFont 改变了字体。QPainter 的 drawText()函数提供了绘制文本的功能。它有几种重载形式,我们 使用了其中的一种,即制定文本的坐标然后绘制。需要注意的是, 这里的坐标是文字左下角左下角的坐标(特别提醒这一点,因为很多绘图系 统,比如 Java2D 都是把左上角作为坐标点的)!下面是运行结果: 我们使用 QTransform 做了一个 rotate 变换。这个变换就是旋转, 而且是顺时针旋转 45 度。然后我们使用这个变换设置了 QPainter 的世界坐标系,注意到 QPainter 是一个状态机,所以这种变换并不 会改变之前的状态,因此只有第二个 Hello, world!被旋转了。确 切的说,被旋转的是坐标系而不是这个文字! 2.22.2 坐标变换在加农炮中的实现坐标变换在加农炮中的实现 CannonField:CannonField(QWidget *parent) : QWidget(parent) r=QRect(0,0,0,0); target=QRect(0,0,0,0); timerCount=0; currentAngle = 45; currentForce=45; setPalette(QPalette(QColor(250, 250, 200); setAutoFillBackground(true); void CannonField:paintEvent(QPaintEvent */*event*/) QPainter painter(this); painter.drawText(200, 200,tr(“Angle = “) + QString:number(currentAngle)+“t“+tr(“Force = “) + QString:number(currentForce); painter.setPen( Qt:NoPen ); painter.setBrush(Q
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号