Python Game engine Development (VI): A small study of animation

Source: Internet
Author: User

Today we will study the animation, in fact, this animation is a Sprite + Bitmap of the combination of the body. What is not to be made Sprite and Bitmap ? =__= #看来你是半路杀进来的, go and see the first few chapters:

Python Game engine Development (i): Preface

Python Game Engine Development (II): Creating a window and redrawing the interface

Python Game engine Development (iii): Show pictures

Python Game engine Development (iv): TextField text class

Python Game Engine Development (v): Sprite Elf class and mouse events

The principle of animation

In general, our animations are used in such a picture:

When playing an animation, like playing a movie, this picture is film. We can get a projector, the size of the projector is the size of each action small map. If our film keeps moving, it will be animated, such as:

How do you achieve this effect? We learned in chapter three how to display pictures, which refer to the BitmapData class (do not understand?). You are advised to read the first few chapters), there are two methods in this class: setCoordinate and setProperty for setting the position and size of the picture display:

bmpd.setCoordinate(x, y)bmpd.setProperty(x, y, width, height)

The parameters are illustrated as follows:

When playing the animation, our "film" is a Bitmap picture display object, which contains an BitmapData object, we can call this object by the above two methods, we will be able to achieve animation playback.

But there seems to be something missing. Perhaps you will ask, animation is a continuous process, and each frame will need a little time between animation, is not a timer? Yes, yes, yes, the important thing to say three times, we did have a timer analogue missing. But don't worry. Do you remember the method of displaying objects mentioned in the third chapter _show ? This method is called in the window paintEvent , and is paintEvent also called in a timer (involving the second chapter of the content). Wait a minute...... Timers ... So we've actually got a timer, and we're getting an interface to the timer.

Time Axis Events

Since there is a lack of interface, then the addition of a will be finished. DisplayObjectHow to change _show :

def _show(self, c):    ifnot self.visible:        return    # 加入时间轴事件入口    self._loopFrame()    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()

Added a line of code for the Timeline event entry. This method is Sprite specifically implemented in subclasses:

def _loopFrame(self):    e = object()    e.currentTarget = self    s.__enterFrameListener(e)

__enterFrameListenerThis is the newly added Sprite property, which is the listener for the timeline event. As with mouse events, we pass a parameter to the listener to get the event information.

Changed Sprite to addEventListener allow it to join a timeline event:

def addEventListener(self, eventType, listener):    if eventType == Event.ENTER_FRAME:        self.__enterFrameListener = listener    else:        self.mouseList.append({            "eventType" : eventType,            "listener" : listener        })

Then Event define the timeline event in the class ENTER_FRAME :

class Event(Object):    "enter_frame"    # more code    ...

When used, it is OK to write this:

layer = Sprite()layer.addEventListener(Event.ENTER_FRAME, onframe)def onframe(e):    print("enter frame")
A simple animation class

Animation class:

class Animation(Sprite):    def __init__(self, bitmapData = BitmapData(), frameList = [[AnimationFrame()]]):        super(Animation, self).__init__()

This class requires an object BitmapData as a parameter, and an list object, which list is the list of frames used to mount the AnimationFrame object, as the AnimationFrame name implies, a class that holds the data for each frame. The code is implemented as follows:

class AnimationFrame(object):    def __init__(self, x = 0, y = 0, width = 0, height = 0):        super(AnimationFrame, self).__init__()        self.x = x        self.y = y        self.width = width        self.height = height

where x the y attribute stores the position of each frame on the picture, width and height stores the width height of each frame.

For the general animated picture (the example picture above), each frame is evenly distributed on the picture, so we can add a function to the uniform clipping of the frame, so we get the frame list is much more convenient. AnimationAdd the following code for the class:

def divideUniformSizeFrames(width = 0, height = 0, col = 1, row = 1):    result = []    frameWidth = width / col    frameHeight = height / row    forin range(row):        rowList = []        forin range(col):            frame = AnimationFrame(j * frameWidth, i * frameHeight, frameWidth, frameHeight)            rowList.append(frame)        result.append(rowList)    return result

Next, we call this function, passing in the corresponding parameters can be cut out of the frame list. As follows:

L = animation.divideuniformsizeframes ( the, the,4,4)# Get the following list:[[Animationframe (0,0, +, +), Animationframe ( +,0, +, +), Animationframe ( the,0, +, +), Animationframe ( -,0, +, +)],[animationframe (0, +, +, +), Animationframe ( +, +, +, +), Animationframe ( the, +, +, +), Animationframe ( -, +, +, +)],[animationframe (0, the, +, +), Animationframe ( +, the, +, +), Animationframe ( the, the, +, +), Animationframe ( -, the, +, +)],[animationframe (0, -, +, +), Animationframe ( +, -, +, +), Animationframe ( the, -, +, +), Animationframe ( -, -, +, +)]]

The next step is to implement the play animation, modify the Animation class:

 class Animation(Sprite):     def __init__(self, bitmapData = BitmapData(), framelist = [[Animationframe()] ]]):Super (Animation, self). __init__ () Self.bitmapdata = BitmapData Self.framelist = framelist Self.bitmap = Bitmap (bitmapData) Self.currentrow =0Self.currentcolumn =0Self.addeventlistener (Event.enter_frame, Self.__onframe) def __onframe(self, e):Currentframe = Self.framelist[self.currentrow][self.currentcolumn] Self.bitmap.bitmapData.setProperty ( Currentframe.x, Currentframe.y, Currentframe.width, currentframe.height) Self.currentcolumn + =1        ifSelf.currentcolumn >= Len (Self.framelist[self.currentrow]): Self.currentcolumn =0

Because this class inherits from it Sprite , it inherits the method of joining the event addEventListener . The above code is to play a row of animation, you can expand to play a column of animation or play a whole group of animation.

In this way, the following code is written to play the animation:

# 加载图片loader = Loader()loader.load("./player.png")# 动画数据bmpd = BitmapData(loader.content)l = Animation.divideUniformSizeFrames(16016044)# 加入动画anim = Animation(bmpd, l)addChild(anim)

Trailer: Next we'll draw a vector graphic.

You are welcome to follow my blog

Reprint Please specify source: Yorhom's Game box

Http://blog.csdn.net/yorhomwang

Python Game engine Development (VI): A small study of animation

Related Article

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.