今天来完毕绘制矢量图形。

没有读过前几章的同学,请先阅读前几章:

Python游戏引擎开发(一):序

Python游戏引擎开发(二):创建窗体以及重绘界面

Python游戏引擎开发(三):显示图片

Python游戏引擎开发(四):TextField文本类

Python游戏引擎开发(五):Sprite精灵类和鼠标事件

Python游戏引擎开发(六):动画的小小研究

Graphics类

首先我们创建Graphics类用于创建矢量图形:

  1. class Graphics(DisplayObject):
  2. def __init__(self):
  3. super(Graphics, self).__init__()
  4. # 存储全部图形数据的列表
  5. self.__drawingList = []
  6. # 用于储存当前图形数据
  7. self.__currentGraphics = None

因为我们的窗体界面是在不断清除。然后重绘的,所以增加__drawingList属性来储存全部图形的数据。而__currentGraphics用于储存当前图形数据。

flash中,我们使用beginFill方法来下达開始绘制命令。增加该方法:

  1. def beginFill(self, color = "transparent", alpha = 1):
  2. if color == "transparent":
  3. alpha = 0
  4. self.__currentGraphics = {
  5. "path" : QtGui.QPainterPath(),
  6. "lineAlpha" : 255,
  7. "lineWidth" : None,
  8. "lineColor" : None,
  9. "fillColor" : color,
  10. "fillAlpha" : 255 * alpha,
  11. "joins" : None,
  12. "caps" : None,
  13. "miterLimit" : None
  14. }

開始绘制命令须要例如以下几个參数:图形填充色、填充色透明度。

在上面的代码中,我们初始化了__currentGraphics属性。能够看到,他是一个dict对象。当中的path成员是一个QPainterPath对象。这个对象来自Qt,通过调用这个类中的一些方法,能够创建一些图形,然后调用QPainterdrawPath方法就能够把这个对象里创建的全部图形画出来。

增加endFill方法。用于把当前图形保存到__drawingList中,保存到__drawingList后。就能够使其显示出来:

  1. def endFill(self):
  2. if not self.__currentGraphics:
  3. return
  4. self.__currentGraphics["path"].setFillRule(QtCore.Qt.WindingFill)
  5. self.__drawingList.append(self.__currentGraphics)

然后是_show方法,在前面的章节中介绍过,每一个显示在界面上的对象都有这种方法,用于显示自身:

  1. def _show(self, c):
  2. for item in self.__drawingList:
  3. if not isinstance(item, dict):
  4. return
  5. path = item["path"]
  6. if not path:
  7. continue
  8. lineWidth = item["lineWidth"]
  9. lineColor = item["lineColor"]
  10. fillColor = item["fillColor"]
  11. joins = item["joins"]
  12. caps = item["caps"]
  13. miterLimit = item["miterLimit"]
  14. fillAlpha = item["fillAlpha"]
  15. lineAlpha = item["lineAlpha"]
  16. brush = None
  17. pen = QtGui.QPen()
  18. c.save()
  19. if lineWidth:
  20. pen.setWidth(lineWidth)
  21. else:
  22. pen.setWidth(0)
  23. if lineColor:
  24. color = getColor(lineColor)
  25. if isinstance(color, QtGui.QColor):
  26. if lineAlpha:
  27. color.setAlpha(lineAlpha)
  28. pen.setColor(color)
  29. else:
  30. pen.setColor(getColor("transparent"))
  31. if joins:
  32. pen.setJoinStyle(joins)
  33. if caps:
  34. pen.setCapStyle(caps)
  35. if miterLimit:
  36. pen.setMiterLimit(miterLimit)
  37. if fillColor:
  38. color = getColor(fillColor)
  39. if fillAlpha and hasattr(color, "setAlpha"):
  40. color.setAlpha(fillAlpha)
  41. brush = QtGui.QBrush(color)
  42. brush.setStyle(QtCore.Qt.SolidPattern)
  43. c.setBrush(brush)
  44. c.setPen(pen)
  45. c.drawPath(path)
  46. c.restore()

当中,我们遍历了__drawingList,从中读取每一个图形数据,然后依据数据进行一些图形样式设置。最后drawPath画出图形。

上面的代码主要完毕了基础的一些部分,眼下我们仅仅有開始画图和结束画图命令。

还差设置样式以及增加图形的命令,通过下面代码增加:

  1. def lineStyle(self, thickness = 1, color = "black", alpha = 1, joints = None, caps = None, miterLimit = 3):
  2. if not self.__currentGraphics:
  3. return
  4. if color == "transparent":
  5. alpha = 0
  6. if joints == JoinStyle.ROUND:
  7. joints = QtCore.Qt.RoundJoin
  8. elif joints == JoinStyle.MITER:
  9. joints = QtCore.Qt.MiterJoin
  10. elif joints == JoinStyle.BEVEL:
  11. joints = QtCore.Qt.BevelJoin
  12. if caps == CapsStyle.NONE:
  13. caps = QtCore.Qt.FlatCap
  14. elif caps == CapsStyle.SQUARE:
  15. caps = QtCore.Qt.SquareCap
  16. elif caps == CapsStyle.ROUND:
  17. caps = QtCore.Qt.RoundCap
  18. self.__currentGraphics["lineWidth"] = thickness
  19. self.__currentGraphics["lineColor"] = color
  20. self.__currentGraphics["lineAlpha"] = 255 * alpha
  21. self.__currentGraphics["joints"] = joints
  22. self.__currentGraphics["caps"] = caps
  23. self.__currentGraphics["miterLimit"] = miterLimit
  24. def moveTo(self, x, y):
  25. if not self.__currentGraphics:
  26. return
  27. self.__currentGraphics["path"].moveTo(x, y)
  28. def lineTo(self, x, y):
  29. if not self.__currentGraphics:
  30. return
  31. self.__currentGraphics["path"].lineTo(x, y)
  32. def drawRect(self, x, y, width, height):
  33. if not self.__currentGraphics:
  34. return
  35. self.__currentGraphics["path"].addRect(x, y, width, height)
  36. def drawCircle(self, x, y, radius):
  37. self.drawEllipse(x - radius, y - radius, radius * 2, radius * 2)
  38. def drawEllipse(self, x, y, width, height):
  39. if not self.__currentGraphics:
  40. return
  41. self.__currentGraphics["path"].addEllipse(x, y, width, height)

有了这些命令,就能够进行画图操作了。

Sprite上使用Graphics

Graphics主要是在Sprite上使用,例如以下代码所看到的:

  1. layer = Sprite()
  2. layer.graphics.beginFill("#FF0000")
  3. layer.graphics.drawRect(0, 0, 200, 200)
  4. layer.graphics.endFill()
  5. addChild(layer)

可见我们须要为Sprite增加一个graphics属性,用于操作矢量图形,所以在Sprite构造器中增加例如以下代码:

  1. self.graphics = new Graphics()
  2. self.graphics.parent = self

通过上面的这些命令,我们就能够创建出很多不同的矢量图形:

绘制矢量图的功能就搞定了~如有不懂之处,欢迎留言。


至此,引擎基本功能就实现了

Github地址:https://github.com/yuehaowang/pylash_engine


欢迎大家继续关注我的博客

转载请注明出处:Yorhom’s Game Box

http://blog.csdn.net/yorhomwang

Python游戏引擎开发(七):绘制矢量图的更多相关文章

  1. Python游戏引擎开发(五):Sprite精灵类和鼠标事件

    本次来实现Sprite类和鼠标事件. 说起这个Sprite啊,涉及过2D游戏研究领域的看官应该都听说过它. 它中文原意是"精灵",只是在不同人的眼中,它所表示的意义不同. 比方说在 ...

  2. 【Cocos2d-x游戏引擎开发笔记(25)】XML解析

    原创文章,转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/9128819 XML是一种非常重要的文件格式,由于C++对XML的支持非常完善 ...

  3. 【译】在Asp.Net中操作PDF - iTextSharp - 绘制矢量图

    原文 [译]在Asp.Net中操作PDF - iTextSharp - 绘制矢量图 在上一篇iTextSharp文章中讲述了如何将现有的图片插入PDF中并对其进行操作.但有时,你需要在PDF中绘制不依 ...

  4. 推荐一些好用的 HTML5 & JavaScript 游戏引擎开发库

    推荐一些好用的 HTML5 & JavaScript 游戏引擎开发库 0. 引言 如果你是一个游戏开发者,并且正在寻找一个可以与 JavaScript 和 HTML5 无缝工作的游戏引擎.那么 ...

  5. 【python】pandas & matplotlib 数据处理 绘制曲面图

    Python matplotlib模块,是扩展的MATLAB的一个绘图工具库,它可以绘制各种图形 建议安装 Anaconda后使用 ,集成了很多第三库,基本满足大家的需求,下载地址,对应选择pytho ...

  6. 25 个超棒的 HTML5 & JavaScript 游戏引擎开发库

    就像在汽车中,引擎完成主要的工作,使汽车看起来不可思议.游戏引擎同理,游戏开发者完成细节的工作,使游戏看起来真实.吸引人眼球.游戏引擎负责其余的事情.早期,游戏开发者通常从草图做起,花费高昂,且不容易 ...

  7. Photoshop 基础七 位图 矢量图 栅格化

    矢量图(CorelDraw)不是像素组成的,放大不会失真,体积小,颜色比较单一.由直线.曲线构成,画一些直线.曲线.多边形.图标. 位图(Photoshop画的就是位图),又像素组成,放大失真,放的越 ...

  8. Qt使用QPainter绘制矢量图并保存为svg文件

    位图和矢量图: Bitmap: Usually a larger file size Cannot be enlarged into a higher resolution as the image ...

  9. 【Android LibGDX游戏引擎开发教程】第06期:图形图像的绘制(下)图片整合工具的使用

    在上一篇文章中,我们提到了图片必须是2的n次方的问题.但是随着Libgdx的不断完善和发展,使用一些工具就 可以很好的解决了这样一个问题,但是它的功能又不仅仅只限于此,那么下面就来让我们看看Textu ...

随机推荐

  1. canvas时钟效果

    话不多说,直接上代码 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/x ...

  2. 原本就有mysql,安装phpstudy使用里面自带的mysql导致原来的没服务

    电脑中之前安装了mysql,正常服务中,但做项目的需要,安装了phpStudy,它里面自带了mysql,启动phpstudy里面的mysql后在用原来的就没服务了, 到电脑管理服务中也没有发现mysq ...

  3. 114. Flatten Binary Tree to Linked List【Medium】【将给定的二叉树转化为“只有右孩子节点”的链表(树)】

    Given a binary tree, flatten it to a linked list in-place. For example, given the following tree: 1 ...

  4. CF1027C Minimum Value Rectangle【贪心/公式化简】

    https://www.luogu.org/problemnew/show/CF1027C #include<cstdio> #include<string> #include ...

  5. Section One

    1.1.1 #include <iostream> using namespace std; int main() { int a,b,N; cin >> N; while ( ...

  6. AvalonJS学习笔记(一)

    一.关于AvalonJS avalon是国内的一个MVVM框架,是从knockout发展起来的 分为两个版本 avalon.js版本,支持IE6及非常老的标准浏览器.这里的标准浏览器特指W3C阵营中的 ...

  7. 【BZOJ 1027】 (凸包+floyd求最小环)

    [题意] 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金 ...

  8. 数据库SQL归纳(三)

    数据查询功能 单表查询 选择若干列 1. 指定列 SELECT 列名称 FROM 表名称 2. 全部列 SELECT * FROM 表名称 3. 经过计算的列 SELECT Sname, 2019-S ...

  9. 初见Python<4>:字典

    序列是python中的一种数据结构,映射是另一种.映射(mapping)通过名字来引用值.python内建的唯一一种映射结构是字典.字典中的值没有特殊的顺序,但都存储在一个特定的键中.键可以是数字.字 ...

  10. (转)同步IO 异步IO 阻塞IO 非阻塞IO

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...