This series of blogs introduces the development of mini-games in the Python+pygame library. There is the wrong point of writing and hope you haihan.
Until now we have learned a lot of pygame basic knowledge, starting from this blog we will learn the Pygame in the advanced part, more and the wizard module, conflict detection related knowledge.
One, Sprite module, Sprite object
In the Pygame.sprite module contains a class called Sprite, he is the Pygame itself with an elf. But the function of this class is relatively small, so we create a new class to its inheritance, on the basis of the Sprite class to enrich, to facilitate our use.
First, let's look at how to use the Sprite class to load the animation.
1. Sprite sequence diagram
The animation frame to be loaded is placed inside a sprite sequence diagram and then called within the program. Pygame will automatically update the animation frames so that a dynamic image will be present in front of us.
The following is a typical sprite sequence diagram: The index of rows and columns starts at 0.
2. Load Sprite diagram sequence:
When loading a sequence of sprites, we need to tell the program the size of a frame (the width and height of the incoming frame, the file name).
In addition, you need to tell the Genie class how many columns there are in the sprite sequence diagram. The load function can load a sprite sequence diagram.
def load (self, filename, width, height, columns): = pygame.image.load (filename). Convert_alpha () = width = height = 0, 0, Width,height = columns
3. Update Frames
A looping animation usually works this way: from the first frame to the last frame, and then back to the first frame, and repeat the operation repeatedly.
Self.frame + = 1 if self.frame > self.last_frame := self.first_frame = Current_time
But if you just do this, the program will play the animation all over again, and we want it to be played one at a time, so add the timed code.
The time module in Pygame has a get_ticks () method to meet the needs of the timing.
Ticks = Pygame.time.get_ticks ()
The ticks variable is then passed to the sprite's update function, which makes it easy for the animation to play at the frame rate. Oh, the frame rate is not set yet, let's set the frame rate now.
Starting a timer, and then calling the Tick (num) function, allows the game to run with NUM frames.
framerate = Pygame.time.Clock () Framerate.tick (60)
4. Draw the Frame
The Sprite.draw () method is used to draw the frame, but the function is automatically called by the Genie, and we have no way to rewrite it, so we need to do some work in the update function.
You first need to calculate the x, Y position value of the upper-left corner of a single frame (x indicates the column number and Y represents the row number):
frame_x = (self.frame% self.columns) * self.frame_width
= (Self.frame//self.columns) * self.frame_height
The computed x, y value is then passed to the location Rect property.
frame_x = (self.frame% self.columns) *= (self.frame//self.columns) *== Self.master_ Image.subsurface (Rect)
5. Elf Group
When you have a large number of entities in your program, it can be quite a hassle to manipulate these entities, so is there any container to put these elves together for unified management? The answer is the ELF group.
Pygame uses the sprite group to manage the wizard's drawing and updating, and the sprite group is a simple container.
Use the Pygame.sprite.Group () function to create an elf group:
Group = Pygame.sprite.Group () group.add (Sprite_one)
The sprite group also has the update and draw functions:
Group.update () Group.draw ()
Second, the Custom wizard class
Well, through the previous study, we have learned some of the knowledge of the elves, and now we are going to wrap the previous approach to a custom class to facilitate our invocation, this class inherits from Pygame.sprite.Sprite:
1 classMySprite (pygame.sprite.Sprite):2 def __init__(self, target):3Pygame.sprite.Sprite.__init__(self)#基类的init方法4Self.target_surface =Target5Self.image =None6Self.master_image =None7Self.rect =None8Self.topleft =0,09Self.frame =0TenSelf.old_frame =-1 OneSelf.frame_width = 1 ASelf.frame_height = 1 -Self.first_frame =0 -Self.last_frame =0 theSelf.columns = 1 -Self.last_time =0 - - defload (self, filename, width, height, columns): +Self.master_image =pygame.image.load (filename). Convert_alpha () -Self.frame_width =width +Self.frame_height =Height ASelf.rect =0,0,width,height atSelf.columns =Columns -Rect =Self.master_image.get_rect () -Self.last_frame = (rect.width//width) * (rect.height//height)-1 - - defUpdate (self, current_time, rate=60): in #更新动画帧 - ifCurrent_time > Self.last_time +Rate : toSelf.frame + = 1 + ifSelf.frame >Self.last_frame: -Self.frame =Self.first_frame theSelf.last_time =Current_time * Panax Notoginseng ifSelf.frame! =Self.old_frame: -frame_x = (self.frame% self.columns) *Self.frame_width theFrame_y = (Self.frame//self.columns) *Self.frame_height +Rect =(frame_x, frame_y, Self.frame_width, Self.frame_height) ASelf.image =self.master_image.subsurface (Rect) theSelf.old_frame = Self.frame
Okay, now let's write a little program to test the performance of this class.
Here I used PS to make a simple sprite sequence diagram, we will use this Meng Meng Big meow Good:
Code:
ImportPygame fromPygame.localsImport*classMySprite (pygame.sprite.Sprite):def __init__(self, target): Pygame.sprite.Sprite.__init__(self) self.target_surface=Target Self.image=None self.master_image=None Self.rect=None Self.topleft=0,0 self.frame=0 Self.old_frame=-1Self.frame_width= 1Self.frame_height= 1Self.first_frame=0 Self.last_frame=0 Self.columns= 1Self.last_time=0defload (self, filename, width, height, columns): Self.master_image=pygame.image.load (filename). Convert_alpha () Self.frame_width=width self.frame_height=Height Self.rect=0,0,width,height self.columns=Columns Rect=self.master_image.get_rect () self.last_frame= (rect.width//width) * (rect.height//height)-1defUpdate (self, current_time, rate=60): ifCurrent_time > Self.last_time +Rate:self.frame+ = 1ifSelf.frame >Self.last_frame:self.frame=self.first_frame Self.last_time=Current_timeifSelf.frame! =self.old_frame:frame_x= (self.frame% self.columns) *self.frame_width frame_y= (Self.frame//self.columns) *self.frame_height rect=(frame_x, frame_y, Self.frame_width, self.frame_height) self.image=self.master_image.subsurface (rect) self.old_frame=self.framepygame.init () screen= Pygame.display.set_mode ((800,600), 0,32) pygame.display.set_caption ("Elf class Test") Font= Pygame.font.Font (None, 18) framerate=Pygame.time.Clock () Cat=MySprite (screen) cat.load ("Sprite.png", 100, 100, 4) Group=Pygame.sprite.Group () Group.add (cat) whileTrue:framerate.tick (30) Ticks=pygame.time.get_ticks () forEventinchpygame.event.get ():ifEvent.type = =Pygame. QUIT:pygame.quit () exit () key=pygame.key.get_pressed ()ifKey[pygame. K_escape]: Exit () Screen.fill (0,0,100) ) group.update (Ticks) group.draw (screen) pygame.display.update ()
: Meng Meng's big meow is on the screen. It seems that the function is good to say.
You can also make some of your favorite sprite sequence diagrams, and then load and view their effects.
About clash detection between elves and sprites, collision detection between sprites and groups, we will be studying together on the next blog.
"Python Game Programming Tour" chapter sixth---sprite modules and loading animations in Pygame