2015/11/6 use Python to write a game. Getting started with pygame (6): controls a large number of objects, pythonpygame
Yesterday we have implemented three basic classes for this game.
But now it still cannot make a suitable game. After all, a game with only one enemy server is boring. Therefore, we need a lot of bullets and many enemy planes.
Therefore, we need to create a list, which stores Bullet or Enemy instances.
Take Bullet as an example:
Bullet = [] # create a bullet for I in range (6): bullet. append (Bullet ())... for B in bullet: # Move the bullet B. move (time_passed_second )... for B in bullet: # display bullet screen. BITs (B. image, (B. x, B. y ))
We can use this code to replace the original bullets, move the bullets, and display the bullets. However, the actual running results have not changed. Why?
Because all the bullets in a list are created and fired in the same way, all the bullets are fired at the same time, at the same time they reach the top of the screen, and then fired at the same time. This effect is no different from the one shot. So we need to let it launch one by one at a certain interval.
In addition, if we get to the top of the screen, we will go back. The re-launch bullets and the bullets launched on time will be mixed together, which will disrupt the pace of the launch, so we need to change the method for recycling the bullets. We can choose to write only its launch for each bullet instead of its recycle, but this creates a space for each bullet to be fired and read the image once, which consumes memory resources, generally, this should be avoided.
Therefore, we must solve two problems: one is scheduled launch and the other is to recycle bullets.
Python has a dedicated time module. However, in the game, we already have a fixed frame rate loop. We only need to use a counter to count the number of loops at intervals, you can achieve the scheduled effect.
For example, we define the interval_bullet interval for a bullet to be fired, so that it increases or decreases progressively. After arriving at a certain number, we reset the interval and run a specific program so that the bullet can be periodically fired.
To reuse a bullet, we can add an attribute to it to indicate whether the bullet should be activated. Only when it is activated, we can process its motion and display.
The bullet itself can be reused. We use a loop queue structure to handle the exploitation of the bullet.
Follow these steps to modify the Bullet class:
class Bullet(object): def __init__(self): self.x = 0 self.y = -100 self.speed = 600 self.image = pygame.image.load(bullet_image_filename).convert_alpha() self.active = False def move(self, passed_time_second): if self.y < 0: self.active = False else: self.y -= self.speed*passed_time_second def restart(self): self.active = True mouseX, mouseY = pygame.mouse.get_pos() self.x = mouseX - self.image.get_width()/2 self.y = mouseY - self.image.get_width()/2
Added a restart () method to reactivate the bullet, and added a data attribute active to mark whether the bullet itself is activated. Then, we changed the code for adding, moving, and displaying bullets to the following:
Bullet = [] for I in range (6): # Total number of bullets bullet. append (Bullet () interval_bullet = 25 # interval of frames for Bullet launching index_bullet = 0 # initialize Bullet coordinates... interval_bullet-= 1 if interval_bullet <= 0: interval_bullet = 25 bullet [index_bullet]. restart () index_bullet = (index_bullet + 1) % 6 for B in bullet: if B. active: B. move (time_passed_second) # move the bullet screen. BITs (B. image, (B. x, B. y) # Show bullets
The result is as follows:
After the bullet is completed, will the plane be far away?
You can think about how the enemy can write data. The difference between the enemy and the enemy is that the interval between the two sides should be more random.
I will not provide a step-by-step guide here. I will paste the entire code that I implemented. Maybe you have a better way to control it. Let's talk about it together:
#-*-Coding: utf8-*-encoding = 'background.png 'mouse _ image_filename = 'hero.png' bullet _ image_filename = 'bullet.png 'enemy _ image_filename = Shanghai' # specify the image file name import pygame # import the pygame library from sys import exit # use an exit function from the sys module to exit the program from random import randint # introduce a random number # define a Bullet class, data and methods for encapsulating bullets class Bullet (object): def _ init _ (self): self. x = 0 self. y =-100 self. speed= 600 self. image = py Game. image. load (bullet_image_filename ). convert_alpha () self. active = False def move (self, passed_time_second): if self. y <0: self. active = False else: self. y-= self. speed * passed_time_second def restart (self): self. active = True mouseX, mouseY = pygame. mouse. get_pos () self. x = mouseX-self. image. get_width ()/2 self. y = mouseY-self. image. get_width ()/2 class Enemy (object): # define an Enemy class to encapsulate the data and methods of the Enemy server de F restart (self): self. x = randint (-30,400) self. y = randint (-100,-50) self. speed = randint (100,400) self. active = True def _ init _ (self): self. restart () self. active = False self. image = pygame. image. load (enemy_image_filename ). convert_alpha () def move (self, passed_time_second): if self. y< 650: self. y + = self. speed * passed_time_second else: self. active = Falsepygame. init () # initialize pygame to prepare scree for use of hardware N = pygame. display. set_mode (480,650), 0, 32) # create a window named pygame. display. set_caption ("PlaneFight! ") # Set the window title pygame. mouse. set_visible (False) background = pygame. image. load (background_image_filename ). convert () mouse_cursor = pygame. image. load (mouse_image_filename ). convert_alpha () # Load and convert the image bullet = [] for I in range (6): # Total number of bullets bullet. append (Bullet () interval_bullet = 25 # Number of frames for bullets to be fired interval index_bullet = 0 # initialize the Bullet coordinate enemy = [] for I in range (10): # Total number of enemy planes enemy. append (Enemy () interval_enemy = 100 # interval between the Enemy and machine index_enemy = 0 # initialize the coordinates of the Enemy and machine clock = pygame. time. clock () while True: # main game loop for event in pygame. event. get (): if event. type = pygame. QUIT: # exit the pygame program after receiving the exit event. quit () exit () time_passed = clock. tick (100) time_passed_second = time_passed/1000.0 screen. bground (background, () # Add the background image x, y = pygame. mouse. get_pos () # obtain the mouse position interval_bullet-= 1 if interval_bullet <= 0: interval_bullet = 25 bullet [index_bullet]. restart () # reset the bullet index_bullet = (index_bullet + 1) % 6 # cyclically increasing for B in bullet: if B. active: B. move (time_passed_second) # move the bullet screen. BITs (B. image, (B. x, B. y) # Show bullets interval_enemy-= 1 if interval_enemy <= 0: interval_enemy = randint (30,100) enemy [index_enemy]. restart () # reset aircraft index_enemy = (index_enemy + 1) % 10 # cyclically increasing for e in enemy: if e. active: e. move (time_passed_second) # move the enemy's screen. BITs (e. image, (e. x, e. y) # display the enemy's x-= mouse_cursor.get_width ()/2 y-= mouse_cursor.get_height ()/2 # Calculate the position in the upper left corner of the cursor # screen. BITs (bullet. image, (bullet. x, bullet. y) screen. BITs (mouse_cursor, (x, y) # draws each element to pygame. display. update () # refresh the screen