Python game engine development (7): drawing vector Graphs
Today, we will draw a vector image.
Graphics class
First, createGraphics
Class is used to create vector graphics:
Class Graphics (DisplayObject): def _ init _ (self): super (Graphics, self ). _ init _ () # self. _ drawingList = [] # used to store the current graphic data self. _ currentGraphics = None
Since our window interface is constantly being cleared and re-painted, add__drawingList
Attribute to store the data of all images. While__currentGraphics
Stores the current graphic data.
Inflash
, We usebeginFill
Method. Add this method:
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 }
The following parameters are required to start drawing: fill color and fill transparency.
In the above Code, we initialized__currentGraphics
Attribute, you can see that it isdict
Object, wherepath
The Member isQPainterPath
Object. This object comes fromQt
By calling some methods in this class, you can create some images and then callQPainter
OfdrawPath
Method to draw all the images created in this object.
AddendFill
Method To save the current image__drawingList
, Save__drawingList
Then you can display it:
def endFill(self): if not self.__currentGraphics: return self.__currentGraphics["path"].setFillRule(QtCore.Qt.WindingFill) self.__drawingList.append(self.__currentGraphics)
Then_show
Methods, as described in the previous section, each object displayed on the interface has this method for displaying itself:
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()
Here, we have traversed__drawingList
To read each graph data, and then set some graph styles based on the data. FinallydrawPath
Draw a graph.
The above code mainly completes some basic parts. Currently, we only need to start and end the drawing command. Run the following code to set the style and add a graphic:
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"] = miterLimitdef 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)
With these commands, you can perform the Drawing operation.
Use Graphics on Sprite
Graphics
Mainly inSprite
As shown in the following code:
layer = Sprite()layer.graphics.beginFill("#FF0000")layer.graphics.drawRect(0, 0, 200, 200)layer.graphics.endFill()addChild(layer)
We needSprite
Addgraphics
Attribute, used to operate vector graphics, so inSprite
Add the following code to the constructor:
self.graphics = new Graphics()self.graphics.parent = self
With the above commands, we can create many different vector images:
The vector plot function is ready ~ If you have any questions, please leave a message.
Notice:Engine example.