zoukankan      html  css  js  c++  java
  • Python游戏引擎开发(七):绘制矢量图

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

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

    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

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

    Image 1

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


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

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


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

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

    http://blog.csdn.net/yorhomwang

  • 相关阅读:
    c# 6.0, 7.0, 8.0, 9.0 总结
    Angular 学习笔记 (Angular 12 get started)
    Asp.net core 学习笔记之 globalization & localization 复习篇
    Angular 学习笔记 (Typescript 版本更新)
    Google Analytics & Ads 学习笔记 2 (GA4 版本)
    Google Analytics & Ads 学习笔记 2 (gtag 版本)
    Email 关于 POP3 IMAP SMTP office365 Outlook Gmail G-Suit shared mailbox小小理解
    摹客预言:设计工具的免费时代来了!
    低保真原型vs高保真原型,哪一种更适合你的设计?
    Instagram的UX和UI的演变史
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7285091.html
Copyright © 2011-2022 走看看