In this article we will continue to create a new missile pool object which will be used to recycle the enemy missile object just like the pool object which will be used to recycle the enemy ship object in the previous article. Basically we will use back the previous object pool class which we have created earlier and then add in a new obtain missile method which takes in the x and y coordinate of the enemy ship at that moment that we can later use as the starting point for the missile object returns from the pool. Here is the class.
class Objectpool(object): def __init__(self, size): self.size = size self.count = 0 self.elist = [None]*size def recycle(self, item): if (self.count < self.size): self.elist[self.count] = item self.count += 1 def obtain(self): if (self.count > 0): self.count -= 1 self.item = self.elist[self.count] self.elist[self.count] = None self.item.missile_count = 1 return self.item def obtain_missile(self, x, y): # get the missile object from the pool if (self.count > 0): self.count -= 1 self.item = self.elist[self.count] self.elist[self.count] = None self.item.x = x self.item.y = y self.item.on = True return self.item def getSize(self): return self.count
That is it, now lets amend the Enemy Missile Manager class by adding in the create missile from pool method which will be used to obtain the old missile object from the object pool.
from GameSprite import GameSprite from pygame.locals import * from Enemymissile import Enemymissile class EnemyMissileManager(object): def __init__(self, scene, player): self.scene = scene self.player = player self.missile_count = 60 self.missile_list = [] self.image = 'Asset/e_missile.png' self.width = 20 self.height = 20 self.rect = Rect(0, 0, self.width, self.height) # initialize game sprite object self.sprite = GameSprite(self.image, self.rect) def create_missile(self, x, y): if(self.missile_count >= 0): self.missile_surface = self.sprite.getImage() self.missile_list.append(Enemymissile(self.missile_surface, x, y)) self.missile_count -= 1 def create_missile_from_pool(self, x, y, pool): if (self.missile_count >= 0): self.missile_list.append(pool.obtain_missile(x, y)) self.missile_count -= 1 def update(self, pool): self.missile_update(pool) self.check_boundary() def missile_update(self, pool): for item in list(self.missile_list): if(item.on == False): self.missile_list.remove(item) self.missile_count += 1 pool.recycle(item) else: item.update() def check_boundary(self): for i in range(len(self.missile_list)): if (self.missile_list[i].y + self.missile_list[i].height > 660): self.missile_list[i].on = False def draw(self): # blit the missile on the scene for i in range(len(self.missile_list)): self.scene.blit(self.missile_list[i].missile_surface, self.missile_list[i].missile_pos)
We now need to do the last step which is to edit the Enemy Manager class.
from Enemy import Enemy from GameSprite import GameSprite from pygame.locals import * from EnemyMissileManager import EnemyMissileManager import random from Objectpool import Objectpool class EnemyManager(object): def __init__(self, scene, player): self.enemy_missile_manager = EnemyMissileManager(scene, player) self.scene = scene self.player = player self.enemy_count = 10 self.missile_count = 60 self.enemy_list = [] self.image = 'Asset/enemy0.png' self.width = 30 self.height = 30 self.rect = Rect(0, 0, self.width, self.height) self.more_enemy = 0 self.y = -50 self.boundary_width = 660 self.boundary_height = 660 self.object_pool = Objectpool(self.enemy_count) self.missile_object_pool = Objectpool(self.missile_count) # initialize game sprite object self.sprite = GameSprite(self.image, self.rect) def create_enemy(self, x, y): if(self.enemy_count > 0): if(self.object_pool.getSize() > 0): # get the ship from object pool if the pool is not empty self.enemy_list.append(self.object_pool.obtain()) else: self.enemy_surface = self.sprite.getImage() self.enemy_list.append(Enemy(self.enemy_surface, x, y)) self.enemy_count -= 1 def update(self): if (self.more_enemy > 600): self.more_enemy = 0 x = random.randint(30, self.boundary_width - 50) self.create_enemy(x , self.y) # create more enemy else: self.more_enemy += 1 # increase time self.enemy_update() self.check_boundary() self.create_enemy_missile() self.enemy_missile_manager.update(self.missile_object_pool) def create_enemy_missile(self): for item in list(self.enemy_list): if(self.player.pos.y - item.y < 100 and abs(self.player.pos.x - item.x) < 60 ): if (item.missile_count > 0): if (self.missile_object_pool.getSize() > 0): self.enemy_missile_manager.create_missile_from_pool(item.x + 5, item.y + 4, self.missile_object_pool) else: self.enemy_missile_manager.create_missile(item.x + 5, item.y + 4) item.missile_count -= 1 def enemy_update(self): for item in list(self.enemy_list): if(item.on == False): self.enemy_list.remove(item) self.enemy_count += 1 item.y = self.y item.on = True self.object_pool.recycle(item) else: item.update() def check_boundary(self): for i in range(len(self.enemy_list)): if (self.enemy_list[i].y > self.boundary_height): self.enemy_list[i].on = False def draw(self): # blit the enemy on the scene for i in range(len(self.enemy_list)): self.scene.blit(self.enemy_list[i].enemy_surface, self.enemy_list[i].enemy_pos) # draw enemy missiles self.enemy_missile_manager.draw()
That is it! With that we will be able to reuse the old enemy missile object instead of creating a new one. The next article will still be dealing with the pool object and this time we will create an object pool for the player missile object!