您的位置:首页 > 编程语言 > Python开发

Python游戏引擎开发(七):绘制矢量图

2016-03-06 19:48 946 查看
今天来完成绘制矢量图形。

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

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

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

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

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

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

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

Graphics类

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

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

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


由于我们的窗口界面是在不断清除,然后重绘的,所以加入
__drawingList
属性来储存所有图形的数据。而
__currentGraphics
用于储存当前图形数据。

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

[code]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
后,就可以使其显示出来:

[code]def endFill(self):
    if not self.__currentGraphics:
        return

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

    self.__drawingList.append(self.__currentGraphics)


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

[code]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
画出图形。

上面的代码主要完成了基础的一些部分,目前我们只有开始绘图和结束绘图命令。还差设置样式以及添加图形的命令,通过以下代码加入:

[code]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
上使用,如下代码所示:

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


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

[code]self.graphics = new Graphics()
self.graphics.parent = self


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



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

预告:引擎使用举例。

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


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


http://blog.csdn.net/yorhomwang
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: