Python pyGame to realize aircraft War 1:https://blog.csdn.net/weixin_38778769/article/details/117329303
Continue the previous one. The previous one talked about adding game frames, game backgrounds, and the movement of players' planes
The purpose of this tutorial is to generate enemy aircraft, the movement of enemy aircraft, the destruction and rebirth of enemy aircraft and players after their collision
As follows:
First prepare the resources, which can also be downloaded from the network. Why do I use the tutorial resources directly here (it's really good-looking, and it's terrible to find it myself). I've put up the package of the whole project, including the source code and resources. I've basically added all the comments, which can be downloaded and viewed by myself: https://download.csdn.net/download/weixin_38778769/19126067 . Or directly download the picture below (to be used in this step) to undertake the resources of the previous one:
Then I won't say much. I'll go straight to the code. Basically, the comments that can be made on each line and the end of the method are written in detail. If there is something that is not described correctly, I can comment (I'm a chicken, please spray it gently)
enemy.py (enemy aircraft class, including the attributes, operation, reset, etc. of enemy aircraft)
The knowledge point is 1. " Initialization of base class“
import pygame from random import * # Small aircraft # pygame.sprite.Sprite is a class used to implement sprites in Pygame. When using it, you don't need to instantiate it. You just need to inherit it and write your own class as needed. Therefore, it is very simple and practical # All sprites are created from pyGame sprite. Inherited from Sprite class SmallEnemy(pygame.sprite.Sprite): def __init__(self, bg_size): # This involves the construction of "initialization of base class", which is well understood by Baidu. # Generally speaking, the SmallEnemy class inherits the parent class pyGame sprite. Sprite, child class and parent class__ init__ () this function. If the subclass does not implement this init() function, # Then, the initialization function of the parent class is called directly during initialization. If the child class implements this init() function, it will override the function of the parent class. Since it inherits the parent class, it is necessary to explicitly call the initialization function of the parent class in this function__ init__ () pygame.sprite.Sprite.__init__(self) # Pictures of enemy aircraft self.image = pygame.image.load('images/enemy1.png').convert_alpha() # Picture of enemy aircraft destroyed self.destory_images = [] self.destory_images.extend([ pygame.image.load('images/enemy1_down1.png').convert_alpha(), pygame.image.load('images/enemy1_down2.png').convert_alpha(), pygame.image.load('images/enemy1_down3.png').convert_alpha(), pygame.image.load('images/enemy1_down4.png').convert_alpha() ]) # Define screen width and height self.width = bg_size[0] self.height = bg_size[1] # get_rect() is a method for processing rectangular images. The return value contains the attributes of the rectangle. Here, the position of the enemy plane picture is returned, and the width and height attributes of the picture can be obtained self.rect = self.image.get_rect() # Randomly generate the position of the aircraft. randint(a,b) generates a < = n < = B, which is randomly generated under the screen width and minus 5 times the height self.rect.left = randint(0, self.width - self.rect.width) self.rect.top = randint(-5 * self.height, 0) # Small enemy aircraft speed self.speed = 2 # Is the enemy plane alive self.active = True # Aircraft collision detection will ignore the white background in the picture self.mask = pygame.mask.from_surface(self.image) # The small enemy plane moved downward def samll_enemy_move(self): # For example, the plane can fly down randomly without waiting for the x-axis to move out of the screen if self.rect.top < self.height: self.rect.top += self.speed else: self.reset() # After the plane flies out of the screen, don't waste it, reset its position (or destroy it, you have to deal with it anyway, otherwise the memory will explode) def reset(self): # It's OK to write it here or not, because it's in a state of survival, so it's safer to write it self.active = True # Randomly reset the position of the aircraft, as generated above self.rect.left = randint(0, self.width - self.rect.width) self.rect.top = randint(-5 * self.height, 0)
The mian here is added on the basis of the previous one, that is, call the enemy aircraft class to generate a small enemy aircraft, and then the enemy aircraft moves. If it collides with the player's aircraft, both will be destroyed and the player's life will be reduced by one
main.py
Main knowledge points involved:
1.pygame. sprite. The Group () function can create a sprite Group for unified management and the corresponding methods of the Group
2.pygame.USEREVENT stands for event 1, pyGame time. set_ Timer: every once in a while (here is 3MS * 1000 = 3s), execute some actions, and then pass event type == invincible_ Event to capture the occurrence of the event
3. Collision detection, pyGame sprite. Sprite collapse (Sprite, sprite_group, bool): all sprites in a group will perform conflict detection on another single sprite one by one
import pygame import sys import traceback from pygame.locals import * from random import * import myplane import enemy # initialization pygame.init() # Set window size bg_size = width, height = 400, 700 # It's actually a tuple screen = pygame.display.set_mode(bg_size) # Setup window pygame.display.set_caption("Aircraft war") # Window title # When loading the background picture, the display effect of ordinary images is the same whether there is convert or not, but using Convert can convert the format and improve the speed of blit background = pygame.image.load("images/background.png").convert() # Set the corresponding values of black, green, red and hundreds of colors, which will be used later BLACK = (0, 0, 0) GREEN = (0, 255, 0) RED = (255, 0, 0) WHITE = (255, 255, 255) # Generate enemy small aircraft def add_small_enemy(small_enemies, enemiesGroup, num): for i in range(num): smallenemy = enemy.SmallEnemy(bg_size) # Sprite group to realize multiple images, which is very suitable for processing sprite list. There are methods of adding, removing, drawing, updating and so on # Group.sprites sprite group # Group.copy copy # Group.add add # Group.remove remove # Group.has determine the members of the wizard group # Group.update update # Group.draw bit block display # Group.clear - draw background # Group.empty empty # Adding this group of enemy aircraft to the attribute of small aircraft is equivalent to unified processing and unified assignment small_enemies.add(smallenemy) enemiesGroup.add(smallenemy) def main(): # Create a clock object (you can control the frequency of game cycles) clock = pygame.time.Clock() # Generate player aircraft me = myplane.MyPlane(bg_size) # Store all enemy aircraft. This aircraft group contains various attributes of small aircraft, medium aircraft and large aircraft, as long as it is used to deal with collision # When there are a large number of entities in the program, operating these entities will be quite troublesome # Use pyGame sprite. The group() function can create a wizard group for unified management. Here, an enemy group is created enemiesGroup = pygame.sprite.Group() # Generate local small aircraft, and the enemy small aircraft is also a group for unified processing small_enemies = pygame.sprite.Group() add_small_enemy(small_enemies, enemiesGroup, 15) # Players have three lives life_num = 3 # Set the invincible time event, pyGame Userevent stands for event 1, pyGame Userevent + 1 represents event 2, and so on, which is equivalent to defining an event invincible_event = pygame.USEREVENT # The game is suspended. The default is non suspended paused = False # Control the player's aircraft picture switching to show the sudden effect switch_image = True # Handover Delay delay = 100 # Game score score = 0 # The subscript of the picture of aircraft explosion is the subscript of the explosion picture of small enemy aircraft, medium enemy aircraft, large enemy aircraft and player aircraft in turn. Switch the subscript to change the explosion picture e1_destory_index = 0 e2_destory_index = 0 e3_destory_index = 0 me_destory_index = 0 running = True while running: # Get event for event in pygame.event.get(): # The end event triggers the end operation if event.type == QUIT: pygame.quit() sys.exit() # When the collision was triggered, pyGame was written time. set_ timer(invincible_event, 3*1000) # It means that invincible will be executed in 3 seconds_ Event event, which captures invincible_ After the event event is executed, the timer will be canceled to prevent the loop from executing repeatedly and wait for the next trigger if event.type == invincible_event: # Disarm invincible state me.invincible = False pygame.time.set_timer(invincible_event, 0) # Detect the user's keyboard operation, up, down, left and right respectively key_pressed = pygame.key.get_pressed() if key_pressed[K_w] or key_pressed[K_UP]: me.moveUp() if key_pressed[K_s] or key_pressed[K_DOWN]: me.moveDown() if key_pressed[K_a] or key_pressed[K_LEFT]: me.moveLeft() if key_pressed[K_d] or key_pressed[K_RIGHT]: me.moveRight() # Draw a background image on the screen and specify the location screen.blit(background, (0, 0)) # Draw bullet supply, bomb supply and other elements # Not paused and life greater than 0 if paused == False and life_num > 0: # Draw small enemy aircraft because the small aircraft group is defined above. The aircraft group add s the attributes of small aircraft (speed, position, etc.), and then the aircraft is generated on the map # If these aircraft belong to the category of small enemy aircraft, they will be handled together for ei in small_enemies: # The enemy plane was alive and undamaged if ei.active == True: # Draw a small enemy plane and the enemy plane begins to move screen.blit(ei.image, ei.rect) ei.samll_enemy_move() # Small enemy aircraft are destroyed (destroyed by players or collided with players) else: # Delay% 4 here means that the explosion picture is 4 frames (personal guess), which is understood as the explosion residence time, which can be set by yourself if not (delay % 4): # It is used to play the sound of explosion. Each enemy aircraft has only one time if e1_destory_index == 0: print("Play the explosion sound of enemy aircraft") # Draw the picture of enemy aircraft impact and explosion screen.blit(ei.destory_images[e1_destory_index], ei.rect) # Switch the subscript of the explosion picture, so as to switch the explosion picture e1_destory_index = (e1_destory_index + 1) % 4 # After a round of explosion, the enemy aircraft can be destroyed or reborn. We have to deal with them, otherwise they will explode and explode all the time # Here choose to rebirth it if e1_destory_index == 0: ei.reset() score += 1000 print("score:", score) # Do collision detection, pyGame sprite. Sprite collapse (Sprite, sprite_group, bool): all sprites in a group will perform conflict detection on another single sprite one by one, and the conflicting sprites will be returned as a list. # The first parameter is a single Sprite, the second parameter is a sprite group, and the third parameter is a bool value. Finally, this parameter plays a great role. When True, all conflicting sprites in the group will be deleted. When False, conflicting sprites will not be deleted # The fourth parameter is pixel mask detection between two sprites enemy_collide = pygame.sprite.spritecollide(me, enemiesGroup, False, pygame.sprite.collide_mask) # Collision processing, if the collision occurs in the invincible state if enemy_collide and not me.invincible: # Player aircraft trigger destroy status me.active = False # enemy_ Collapse is a list that stores all enemy aircraft that collide with the player's aircraft, and then sets the status of the collided enemy aircraft to destroy status for ei in enemy_collide: ei.active = False # Draw the player's plane if it is active if me.active: # Draw the player's plane on the screen, switch_image is whether to switch pictures if switch_image: screen.blit(me.image1, me.rect) # Switch the flight picture else: screen.blit(me.image2, me.rect) # It means that the aircraft was collided and the explosion was activated else: if not (delay % 4): # It is used to play the sound of explosion. Each enemy aircraft has only one time if me_destory_index == 0: print("Player plane explosion sound") # Draw player impact explosion screen screen.blit(me.destory_image[me_destory_index], me.rect) # Switch the subscript of the explosion picture, so as to switch the explosion picture me_destory_index = (me_destory_index + 1) % 4 # After the explosion, the plane was reborn if me_destory_index == 0: # Life is reduced by one. If you see 0, you will automatically skip the previous cycle life_num -= 1 # reset state me.reset() # Invincible time is set to 3 seconds. After 3 seconds, the invincible time event, pyGame, will be triggered time. set_ Timer: every once in a while (here is 3MS * 1000 = 3s) to perform some actions pygame.time.set_timer(invincible_event, 3 * 1000) delay -= 1 if delay == 0: delay = 100 # Switch the flight picture style every 5 frames if delay % 5 == 0: switch_image = not switch_image # Update the whole Surface object to be displayed to the screen, and display the contents in memory to the screen pygame.display.flip() # Specify the cycle frequency through the clock object, and cycle 60 times per second # The frame rate is the rate at which the program draws graphics on the screen per second clock.tick(60) if __name__ == "__main__": try: main() # Normal service exit except SystemExit: print("The game exits normally!") # pass ignores the error and continues to run. In fact, it exits here pass # Other exceptions occurred in the service except: # Print the error directly traceback.print_exc() pygame.quit()
Myplane from the previous one Py, there are no additional things added here, and they are also pasted here:
import pygame # Player aircraft, pygame Sprite module contains a class named Sprite, which is a wizard of pygame itself. class MyPlane(pygame.sprite.Sprite): def __init__(self, bg_size): # convert_alpha() changes the pixel format of the image, including the alpha of each pixel, which is equivalent to that the picture background becomes transparent self.image1 = pygame.image.load('images/me1.png').convert_alpha() self.image2 = pygame.image.load('images/me2.png').convert_alpha() # Pictures of aircraft destruction are saved in digital form self.destory_image = [] self.destory_image.extend([ pygame.image.load('images/me_destroy_1.png').convert_alpha(), pygame.image.load('images/me_destroy_2.png').convert_alpha(), pygame.image.load('images/me_destroy_3.png').convert_alpha(), pygame.image.load('images/me_destroy_4.png').convert_alpha() ]) # Define screen width and height self.width = bg_size[0] self.height = bg_size[1] # get_rect() is a method for processing rectangular images. The return value contains the attributes of the rectangle. Here, the position of aircraft picture 1 is returned to obtain the width and height attributes of the picture self.rect = self.image1.get_rect() # The initialization position of the aircraft, / / is the division, the position is centered and the height is 60 from the bottom of the screen self.rect.left = (self.width - self.rect.width)//2 self.rect.top = self.height - self.rect.height - 60 # Set the speed of the aircraft self.myPlaneSpeed = 10 self.active = True # Set whether the aircraft is invincible (invincible within 3 seconds of rebirth) self.invincible = False # Aircraft collision detection will ignore the white background in the picture and return a Mask from the specified Surface object # For fast and perfect collision detection, Mask can judge accurately to 1 pixel level. # The transparent part of the Surface object is set to 1 and the opaque part is set to 0. self.mask = pygame.mask.from_surface(self.image1) # Player plane moves up def moveUp(self): # The description has not been fixed, that is, it has not reached the boundary on the game interface if self.rect.top > 0: self.rect.top -= self.myPlaneSpeed # Indicates that the movement has reached the upper boundary else: self.rect.top = 0 # Player plane moves down def moveDown(self): # A height of 60 needs to be marked at the bottom to display other data (number of bombs, number of lives, etc.) if self.rect.bottom < self.height - 60: # self.rect.bottom refers to the lower boundary of the aircraft picture self.rect.bottom += self.myPlaneSpeed else: self.rect.bottom = self.height - 60 # Player plane moves left def moveLeft(self): if self.rect.left > 0: self.rect.left -= self.myPlaneSpeed else: self.rect.left = 0 # The player's plane moves to the right def moveRight(self): if self.rect.right < self.width: self.rect.right += self.myPlaneSpeed else: self.rect.right = self.width # Player plane rebirth def reset(self): self.active = True # Be invincible when reborn self.invincible = True # The initialization position of the reborn aircraft, / / is the division, the position is centered and the height is 60 from the bottom of the screen self.rect.left = (self.width - self.rect.width) // 2 self.rect.top = self.height - self.rect.height - 60