Python game engine development: display pictures

Source: Internet
Author: User

Python game engine development: display pictures


Since our game is dynamic, the general idea is to make the interface display the changed results after we change the data every time (for example, switching the image when playing an animation: first, erase the original changes, and then draw out the changes. However, this seems simple. If you encounter overlapping objects, it will be troublesome. For example, if A is under B and we want to change A, after A is erased, B will also be erased, the reason is that our canvas is 2D and cannot be erased in the Z direction. In this way, in addition to re-painting A, we need to re-draw B. This is a complicated problem. To simplify the operation, we can directly use the full-window re-painting, that is, regular erasure and re-painting.

 

Display object

In the previous chapter, we repeatedly mentioned the Display object. What is the display object? As its name implies, it is a visual object, such as a game character or map. For examplelist,tupleThese objects cannot be displayed. They are only used for internal data storage, so they are not displayed. Similarly, the resource loader in the game is not a display object.

Program development can be seen as a classification process (classAs a major Program Statement ). If we classify and display objects by object size or color, these classes may appear:BigTree,GreenTree...... Such classification has obvious problems: the classification is not detailed enough and all effects cannot be achieved. Flash gave us a good example: to classify the content displayed. That is to say, the image is displayed as one type, the text is displayed as one type, and the vector is displayed as one type ...... In this way, the refined layer is not only high, but also everything on the interface can be combined using these classes.

Today, we will first display images. Since the above classes are related to the Display object, we first create a parent class for all the display objects.DisplayObject:

class DisplayObject(Object):    def __init__(self):        super(DisplayObject, self).__init__()        self.parent = None        self.x = 0        self.y = 0        self.alpha = 1        self.rotation = 0        self.scaleX = 1        self.scaleY = 1        self.visible = True    @property    def width(self):        return self._getOriginalWidth() * abs(self.scaleX)    @property    def height(self):        return self._getOriginalHeight() * abs(self.scaleY)    def _show(self, c):        if not self.visible:            return        c.save()        c.translate(self.x, self.y)        c.setOpacity(self.alpha * c.opacity())        c.rotate(self.rotation)        c.scale(self.scaleX, self.scaleY)        self._loopDraw(c)        c.restore()    def _loopDraw(self, c):        pass    def _getOriginalWidth(self):        return 0    def _getOriginalHeight(self):        return 0    def remove(self):        if hasattr(self, parent) and (isinstance(self.parent, DisplayObjectContainer) or isinstance(self.parent, Stage)):            self.parent.removeChild(self)

All attributes in this class are the public attributes of all displayed objects. For examplex,yThe horizontal and vertical coordinates in the Cartesian coordinate system (the origin is the top left corner of the screen );rotationIt indicates the angle from which the object rotates around the upper left corner.
As we mentioned above, we need to provide a method for self-repainting. During re-painting, different display objects display different content. For example, the image class should display the image and text. However, these classes have similarities. For example, you can set horizontal and vertical coordinates and degrees of rotation. So we create_showMethod, which is used to process rotation, scaling, and movement in a unified manner, and then call_loopDrawTo draw different content.
Because the Display object also has the function of obtaining the width, we will add_getOriginalWidth,_getOriginalHeightObtainwidth,heightCalculate the width and height of the attribute.
There is anotherremoveMethod is used to remove itself from the reality list.

The above describes the code arrangement, and then explains the code. First, let's recall the code in the previous chapter:

def _showDisplayList(self, childList):        for o in childList:            if hasattr(o, _show) and hasattr(o._show, __call__):                o._show(self.canvas)

This isStageClass. In this method, we traverse the Display object and call_showSo here is the entry to draw the Display object. We can see that when calling this function, we passed inStageClasscanvasAttribute. What is this? In the previous chapter, we introduced that this isQPainterObject. If you are a student of "I was surprised at the time" [1], you should take a look at the previous chapter of this article.

[1] from the poem Jin Se of Li Yishan, the meaning of the original poem is: "It was just a long time ago." I use it on behalf of me"

In_showIn the method, we first accept this parameter. This QPainter has many methods that can be used to set attributes of the entire paint brush, such as the transparency of the paint brush and the position of the painting.QPainterOfsaveThis method is used to record the current coordinate status for easy relative positioning.translate,scale,rotate,setOpacityIt is used to set the start position of the paint brush, pull/compress the paint brush, rotate the paint brush, and set the paint transparency. Then call_loopDrawDraw special content of different display objects. Finally, callrestoreResume the paint brush status to the record status (save).

Show Image

With the above Display object class as the basis, we can achieve the display of images.

Attach Images

First, load the image. Write countLoaderClass:

class Loader(DisplayObject):    def __init__(self):        super(Loader, self).__init__()        self.content = None    def load(self, url):        image = QtGui.QImage()        image.load(url)        self.content = image

UsedQImageThis Qt class hasloadTo load the image. Under the conditions of hosts and other files, we will imitate flash for the time being, and it will not be too late to use other files for further expansion.

Store Image Data

In flash, useBitmapDataClass, this small hoof is not a display object:

class BitmapData(Object):    def __init__(self, image = QtGui.QImage(), x = 0, y = 0, width = 0, height = 0):        super(BitmapData, self).__init__()        self.image = image        self.x = x        self.y = y        self.width = width        self.height = height        if image is not None:            if width == 0:                self.width = image.width()            if height == 0:                self.height = image.height()    @property    def x(self):        return self.__x    @x.setter    def x(self, value):        if value > self.image.width():            value = self.image.width()        self.__x = value    @property    def y(self):        return self.__y    @y.setter    def y(self, value):        if value > self.image.height():            value = self.image.height()        self.__y = value    @property    def width(self):        return self.__width    @width.setter    def width(self, value):        if (value + self.x) > self.image.width():            value = self.image.width() - self.x        self.__width = value    @property    def height(self):        return self.__height    @height.setter    def height(self, value):        if (value + self.y) > self.image.height():            value = self.image.height() - self.y        self.__height = value    def setCoordinate(self, x = 0, y = 0):        self.x = x        self.y = y    def setProperties(self, x = 0, y = 0, width = 0, height = 0):        self.x = x        self.y = y        self.width = width        self.height = height

This class only Stores image data, such as the width and height of the display range and the starting coordinate of the display range. Of course, this class also has other purposes, such as pixel processing, which will be expanded in the future. It is worth noting that the meaning of each attribute in this class is as follows:

Image Display class

The image is loaded and stored, and then the image is displayed. Display the image category numberBitmap, YesDisplayObjectSubclass:

class Bitmap(DisplayObject):    def __init__(self, bitmapData = BitmapData()):        super(Bitmap, self).__init__()        self.bitmapData = bitmapData    def _getOriginalWidth(self):        return self.bitmapData.width    def _getOriginalHeight(self):        return self.bitmapData.height    def _loopDraw(self, c):        bmpd = self.bitmapData        c.drawImage(0, 0, bmpd.image, bmpd.x, bmpd.y, bmpd.width, bmpd.height)

The_loopDrawTo complete the image painting. In this method, it is worth noting thatQPainterOfdrawImageMethods, the parameters accepted by this method are: [starting point x, starting point y, QImage object, x attribute of the image content, y attribute of the image content, width of the image content, high Image Content]
By the way, it was rewritten._getOriginalWidth,_getOriginalHeightTo obtain the image width and height.

After the preceding code is completed, perform the test:

from pylash.utils import init, addChildfrom pylash.display import Bitmap, Loader, BitmapDatadef main():    loader = Loader()    loader.load(./face.png)    bmpd = BitmapData(loader.content)    bmp = Bitmap(bmpd)    addChild(bmp)    bmp.x = 80    bmp.y = 100    bmp.rotation = -20    bmp.alpha = 0.8init(30, Display An Image, 800, 600, main)

:

All codes encapsulated in this package: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwcmUgY2xhc3M9 "brush: java;"> from PyQt4 import QtGuifrom .utils import Object, Stageclass DisplayObject(Object): def __init__(self): super(DisplayObject, self).__init__() self.parent = None self.x = 0 self.y = 0 self.alpha = 1 self.rotation = 0 self.scaleX = 1 self.scaleY = 1 self.visible = True @property def width(self): return self._getOriginalWidth() * abs(self.scaleX) @property def height(self): return self._getOriginalHeight() * abs(self.scaleY) def _show(self, c): if not self.visible: return c.save() c.translate(self.x, self.y) c.setOpacity(self.alpha * c.opacity()) c.rotate(self.rotation) c.scale(self.scaleX, self.scaleY) self._loopDraw(c) c.restore() def _loopDraw(self, c): pass def _getOriginalWidth(self): return 0 def _getOriginalHeight(self): return 0 def remove(self): if hasattr(self, parent) and (isinstance(self.parent, DisplayObjectContainer) or isinstance(self.parent, Stage)): self.parent.removeChild(self)class Loader(DisplayObject): def __init__(self): super(Loader, self).__init__() self.content = None def load(self, url): image = QtGui.QImage() image.load(url) self.content = imageclass BitmapData(Object): def __init__(self, image = QtGui.QImage(), x = 0, y = 0, width = 0, height = 0): super(BitmapData, self).__init__() self.image = image self.x = x self.y = y self.width = width self.height = height if image is not None: if width == 0: self.width = image.width() if height == 0: self.height = image.height() @property def x(self): return self.__x @x.setter def x(self, value): if value > self.image.width(): value = self.image.width() self.__x = value @property def y(self): return self.__y @y.setter def y(self, value): if value > self.image.height(): value = self.image.height() self.__y = value @property def width(self): return self.__width @width.setter def width(self, value): if (value + self.x) > self.image.width(): value = self.image.width() - self.x self.__width = value @property def height(self): return self.__height @height.setter def height(self, value): if (value + self.y) > self.image.height(): value = self.image.height() - self.y self.__height = value def setCoordinate(self, x = 0, y = 0): self.x = x self.y = y def setProperties(self, x = 0, y = 0, width = 0, height = 0): self.x = x self.y = y self.width = width self.height = heightclass Bitmap(DisplayObject): def __init__(self, bitmapData = BitmapData()): super(Bitmap, self).__init__() self.bitmapData = bitmapData def _getOriginalWidth(self): return self.bitmapData.width def _getOriginalHeight(self): return self.bitmapData.height def _loopDraw(self, c): bmpd = self.bitmapData c.drawImage(0, 0, bmpd.image, bmpd.x, bmpd.y, bmpd.width, bmpd.height)

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.