Python game engine development (7): drawing vector Graphs
Today, we will draw a vector image.
Graphics class
First, createGraphicsClass 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__drawingListAttribute to store the data of all images. While__currentGraphicsStores the current graphic data.
Inflash, We usebeginFillMethod. 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__currentGraphicsAttribute, you can see that it isdictObject, wherepathThe Member isQPainterPathObject. This object comes fromQtBy calling some methods in this class, you can create some images and then callQPainterOfdrawPathMethod to draw all the images created in this object.
AddendFillMethod To save the current image__drawingList, Save__drawingListThen 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_showMethods, 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__drawingListTo read each graph data, and then set some graph styles based on the data. FinallydrawPathDraw 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
GraphicsMainly inSpriteAs shown in the following code:
layer = Sprite()layer.graphics.beginFill("#FF0000")layer.graphics.drawRect(0, 0, 200, 200)layer.graphics.endFill()addChild(layer)
We needSpriteAddgraphicsAttribute, used to operate vector graphics, so inSpriteAdd 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.