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

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

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

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

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

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

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

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

Graphics类

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

class Graphics(DisplayObject):
    def __init__(self):
        super(Graphics, self).__init__()

        # 存储全部图形数据的列表
        self.__drawingList = []
        # 用于储存当前图形数据
        self.__currentGraphics = None

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

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

def beginFill(self, color = "transparent", alpha = 1):
    if color == "transparent":
        alpha = 0

    self.__currentGraphics = {
        "path" : QtGui.QPainterPath(),
        "lineAlpha" : 255,
        "lineWidth" : None,
        "lineColor" : None,
        "fillColor" : color,
        "fillAlpha" : 255 * alpha,
        "joins" : None,
        "caps" : None,
        "miterLimit" : None
    }

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

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

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

def endFill(self):
    if not self.__currentGraphics:
        return

    self.__currentGraphics["path"].setFillRule(QtCore.Qt.WindingFill)

    self.__drawingList.append(self.__currentGraphics)

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

def _show(self, c):
    for item in self.__drawingList:
        if not isinstance(item, dict):
            return

        path = item["path"]

        if not path:
            continue

        lineWidth = item["lineWidth"]
        lineColor = item["lineColor"]
        fillColor = item["fillColor"]
        joins = item["joins"]
        caps = item["caps"]
        miterLimit = item["miterLimit"]
        fillAlpha = item["fillAlpha"]
        lineAlpha = item["lineAlpha"]

        brush = None
        pen = QtGui.QPen()

        c.save()

        if lineWidth:
            pen.setWidth(lineWidth)
        else:
            pen.setWidth(0)

        if lineColor:
            color = getColor(lineColor)

            if isinstance(color, QtGui.QColor):
                if lineAlpha:
                    color.setAlpha(lineAlpha)

                pen.setColor(color)
        else:
            pen.setColor(getColor("transparent"))

        if joins:
            pen.setJoinStyle(joins)

        if caps:
            pen.setCapStyle(caps)

        if miterLimit:
            pen.setMiterLimit(miterLimit)

        if fillColor:
            color = getColor(fillColor)

            if fillAlpha and hasattr(color, "setAlpha"):
                color.setAlpha(fillAlpha)

            brush = QtGui.QBrush(color)

            brush.setStyle(QtCore.Qt.SolidPattern)

            c.setBrush(brush)

        c.setPen(pen)
        c.drawPath(path)

        c.restore()

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

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

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

def lineStyle(self, thickness = 1, color = "black", alpha = 1, joints = None, caps = None, miterLimit = 3):
    if not self.__currentGraphics:
        return

    if color == "transparent":
        alpha = 0

    if joints == JoinStyle.ROUND:
        joints = QtCore.Qt.RoundJoin
    elif joints == JoinStyle.MITER:
        joints = QtCore.Qt.MiterJoin
    elif joints == JoinStyle.BEVEL:
        joints = QtCore.Qt.BevelJoin

    if caps == CapsStyle.NONE:
        caps = QtCore.Qt.FlatCap
    elif caps == CapsStyle.SQUARE:
        caps = QtCore.Qt.SquareCap
    elif caps == CapsStyle.ROUND:
        caps = QtCore.Qt.RoundCap

    self.__currentGraphics["lineWidth"] = thickness
    self.__currentGraphics["lineColor"] = color
    self.__currentGraphics["lineAlpha"] = 255 * alpha
    self.__currentGraphics["joints"] = joints
    self.__currentGraphics["caps"] = caps
    self.__currentGraphics["miterLimit"] = miterLimit

def moveTo(self, x, y):
    if not self.__currentGraphics:
        return

    self.__currentGraphics["path"].moveTo(x, y)

def lineTo(self, x, y):
    if not self.__currentGraphics:
        return

    self.__currentGraphics["path"].lineTo(x, y)

def drawRect(self, x, y, width, height):
    if not self.__currentGraphics:
        return

    self.__currentGraphics["path"].addRect(x, y, width, height)

def drawCircle(self, x, y, radius):
    self.drawEllipse(x - radius, y - radius, radius * 2, radius * 2)

def drawEllipse(self, x, y, width, height):
    if not self.__currentGraphics:
        return

    self.__currentGraphics["path"].addEllipse(x, y, width, height)

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

Sprite上使用Graphics

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

layer = Sprite()
layer.graphics.beginFill("#FF0000")
layer.graphics.drawRect(0, 0, 200, 200)
layer.graphics.endFill()
addChild(layer)

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

self.graphics = new Graphics()
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. 【python】pandas & matplotlib 数据处理 绘制曲面图

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

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

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

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

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

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

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

  8. 【Android LibGDX游戏引擎开发教程】第07期:中文字体的显示和绘制(上)

    在字体的显示和绘制中,Libgdx的作者(Mario Zechner,美国人)给我们提供了一个非常好用的工具 ——Hiero,那么下面就来看看它具体的使用方法. 一.Hiero工具的使用 1.Hier ...

  9. 【Android LibGDX游戏引擎开发教程】第08期:中文字体的显示和绘制(下)

    在上一篇的文章中,我们介绍了Hiero这个非常好用工具的使用,但是LIbgdx的BitmapFont不支持多图,常用汉字 3500个,你总不能用hiero自己做吧,那怎么办呢?这其实微软早就解决这个问 ...

随机推荐

  1. gulp整理

    gulp基于node 1.全局安装gulp: $ npm install --global gulp 2.前往项目目录,然后安装作为项目的开发依赖(devDependencies): $ npm in ...

  2. 客户端用javascript获取文件大小

    客户端用javascript获取文件大小 1 ie实现代码如下: <script type="text/javascript" language="javascri ...

  3. iOS使用Zbar扫描二维码

    iOS使用Zbar扫描二维码 标签(空格分隔):二维码扫描 iOS Zbar64位 正文: 首先下载一个支持64位系统的ZbarSDK的包,保存在了我的云盘里,地址:ZbarSDK 把文件拖到工程里面 ...

  4. Android AsyncTask异步任务(二)

    之前我们讲过了AsyncTask 的生命周期(onPreExecute-->doInBackground-->onProgressUpdate-->onPostExecute),今天 ...

  5. javaEE中关于dao层和services层的理解

    javaEE中关于dao层和services层的理解 入职已经一个多月了,作为刚毕业的新人,除了熟悉公司的项目,学习公司的框架,了解项目的一些业务逻辑之外,也就在没学到什么:因为刚入职, 带我的那个师 ...

  6. php利用svn hooks将程序自动发布到测试环境

    利用svn hooks将php程序自动发布到测试环境 复制仓库hooks目录下的post-commit.tmpl为post-commit cp post-commit.tmpl post-commit ...

  7. 解读SQL 内存数据库的细节

    相信大家对内存数据库的 概念并不陌生,之前园子里也有多位大牛介绍过SQL内存数据库的创建方法,我曾仔细 拜读过,有了大致了解,不过仍有很多细节不清晰,比如: (1)内存数据库是把整个数据库放到内存中的 ...

  8. WCF帮助类

    using BJSW.ZTFX.Client.Silverlight.MapBusinessService; using System.ServiceModel; using System.SL.Ap ...

  9. Part 100 Func delegate in c#

    What is Func<T,TResult> in C#? In simple terms,Func<T,TResult> is just generic delegate. ...

  10. linux修改文件权限和用户组管理小结

    如何在linux下修改组权限 chmod g+r path/file 加读权限 当前目录 chmod -R g+r path/file 加读权限 当前目录以及子目录 g-r 减读权限g+w 加写权限g ...