Python游戏引擎开发(七):绘制矢量图
今天来完毕绘制矢量图形。
没有读过前几章的同学,请先阅读前几章:
Python游戏引擎开发(五):Sprite精灵类和鼠标事件
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,通过调用这个类中的一些方法,能够创建一些图形,然后调用QPainter的drawPath方法就能够把这个对象里创建的全部图形画出来。
增加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
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号