In this article we are going to create the third level for our pygame project after we have created the previous two levels, the reason I create the third game level in this chapter is because this level is different from the second level which is only using the same enemy class to generate different type of enemy ship. In this chapter we are going to create a new enemy class which will act differently as compared with the previous enemy class.
We will create a new enemy object which moves from side to side and shoots three missiles at the same time, we can add in more features to this new enemy class later on but for now lets just create a simple one first.
from pygame import math as mtfrom Objectpool import Objectpool
class Enemy1(object):
def __init__(self, enemy_surface, x, y):
self.on = True
self.enemy_surface = enemy_surface
self.x = x
self.y = y
self.hit = False
self.direction = True
self.enemy_pos = mt.Vector2(self.x, self.y)
self.missile_count = 10
self.missile_timer = 0
self.missile_object_pool = Objectpool(self.missile_count)
self.missile_list = []
def update(self):
if(self.direction == True):
self.x += 0.1
else:
self.x -= 0.1
self.enemy_pos = mt.Vector2(self.x, self.y)
self.missile_update(self.missile_object_pool)
def missile_update(self, pool):
for item in list(self.missile_list):
if (item.on == False):
self.missile_list.remove(item)
pool.recycle(item)
else:
item.update()
def missile_draw(self, scene): # draw enemy missiles on game scene
for item in list(self.missile_list):
scene.blit(item.missile_surface, item.missile_pos)
def create_enemy_missile(self, enemy_missile_manager):
if(self.missile_timer > 300):
self.missile_timer = 0
if (self.missile_object_pool.getSize() > 0):
enemy_missile_manager.create_missile(self.x + 3, self.y + 100, self.missile_object_pool, self.missile_list)
enemy_missile_manager.create_missile(self.x + 50, self.y + 100, self.missile_object_pool, self.missile_list)
enemy_missile_manager.create_missile(self.x + 100, self.y + 100, self.missile_object_pool, self.missile_list)
else:
enemy_missile_manager.create_missile(self.x + 3, self.y + 100, None, self.missile_list)
enemy_missile_manager.create_missile(self.x + 50, self.y + 100, None, self.missile_list)
enemy_missile_manager.create_missile(self.x + 100, self.y + 100, None, self.missile_list)
else:
self.missile_timer += 1
Next is to edit the enemy manager class by adding in the level three scene’s objects.
from Enemy import Enemyfrom GameSprite import GameSprite
from pygame.locals import *
from EnemyMissileManager import EnemyMissileManager
import random
from Objectpool import Objectpool
from Enemy1 import Enemy1
class EnemyManager(object):
def __init__(self, scene, player, game_level):
self.enemy_missile_manager = EnemyMissileManager()
self.scene = scene
self.player = player
self.enemy_count = 10
self.horizontal_enemy_count = 1
self.missile_count = 60
self.enemy_list = []
self.horizontal_enemy_list = []
self.image = 'Asset/enemy0.png'
self.image1 = 'Asset/enemy1.png'
self.image2 = 'Asset/enemy2.png'
self.width = 30
self.height = 30
self.width1 = 130
self.height1 = 130
self.rect = Rect(0, 0, self.width, self.height)
self.rect1 = Rect(0, 0, self.width1, self.height1)
self.more_enemy = 0
self.y = -50
self.boundary_width = 660
self.boundary_height = 660
self.object_pool = Objectpool(self.enemy_count)
self.horizontal_object_pool = Objectpool(self.horizontal_enemy_count)
self.next_enemy = 0
self.level = game_level
# initialize game sprite object
self.sprite = GameSprite(self.image, self.rect)
self.sprite1 = GameSprite(self.image1, self.rect)
self.sprite2 = GameSprite(self.image2, self.rect1)
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: # objects setup based on the level of the game
if(self.level == 1):
self.enemy_surface = self.sprite.getImage()
elif(self.level == 2 or self.level == 3):
if(self.next_enemy == 0):
self.enemy_surface = self.sprite.getImage()
self.next_enemy += 1
elif(self.next_enemy == 1):
self.enemy_surface = self.sprite1.getImage()
self.next_enemy = 0
self.enemy_list.append(Enemy(self.enemy_surface, x, y))
self.enemy_count -= 1
def create_horizontal_enemy(self, x, y):
if (self.horizontal_enemy_count > 0):
if (self.horizontal_object_pool.getSize() > 0): # get the ship from object pool if the pool is not empty
self.horizontal_enemy_list.append(self.horizontal_object_pool.obtain())
else: # objects setup based on the level of the game
if (self.level == 3):
self.enemy_surface1 = self.sprite2.getImage()
self.horizontal_enemy_list.append(Enemy1(self.enemy_surface1, x, y))
self.horizontal_enemy_count -= 1
def update(self):
if (self.level == 1 or self.level == 2):
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
elif(self.level == 3):
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
if(self.horizontal_enemy_count > 0):
self.create_horizontal_enemy(-130, 200) # create new enemy
self.enemy_update()
self.check_boundary()
self.create_enemy_missile()
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 ):
item.create_enemy_missile(self.enemy_missile_manager)
if(self.level == 3):
for item in list(self.horizontal_enemy_list):
item.create_enemy_missile(self.enemy_missile_manager)
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()
if (self.level == 3):
for item in list(self.horizontal_enemy_list):
if (item.on == False):
self.horizontal_enemy_list.remove(item)
self.horizontal_enemy_count += 1
item.y = 220
item.x = -130
item.on = True
self.horizontal_object_pool.recycle(item)
else:
item.update()
# check the boundary of the enemy ship with the game scene area
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
if (self.level == 3):
for i in range(len(self.horizontal_enemy_list)):
if (self.horizontal_enemy_list[i].x > self.boundary_width):
self.horizontal_enemy_list[i].direction = False
elif(self.horizontal_enemy_list[i].x <= -130):
self.horizontal_enemy_list[i].direction = True
def draw(self):
# blit the enemy and enemy missiles 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)
self.enemy_list[i].missile_draw(self.scene)
if(self.level == 3):
for i in range(len(self.horizontal_enemy_list)):
self.scene.blit(self.horizontal_enemy_list[i].enemy_surface, self.horizontal_enemy_list[i].enemy_pos)
self.horizontal_enemy_list[i].missile_draw(self.scene)
We also need to edit the overlap class which will now take level three into consideration.
from pygame.locals import *class Overlap(object):
def __init__(self):
pass # nothing here
# is player and enemy, player missile, enemy missile overlap
def isOverlap(self, player, em, ex, score, gm):
self.checkOverlap(em.enemy_list, player, ex, gm, score, em.width, em.height, em.enemy_missile_manager.width, em.enemy_missile_manager.height, None)
if(gm.level_manager.get_level() == 3):
self.checkOverlap(em.horizontal_enemy_list, player, ex, gm, score, em.width1, em.height1, em.enemy_missile_manager.width, em.enemy_missile_manager.height, gm.level_manager.get_level())
def checkOverlap(self, e_list, player, ex, gm, score, width, height, m_width, m_height, level):
self.player_rect = Rect(player.pos.x, player.pos.y, player.width, player.height)
for i in range(len(e_list)): # is player collides with enemy
self.em_rect = Rect(e_list[i].x, e_list[i].y, width, height)
if (self.player_rect.colliderect(self.em_rect)):
e_list[i].on = False
if (e_list[i].hit == False):
ex.create_explosion(player.pos.x + 2, player.pos.y + 2)
e_list[i].hit = True
gm.state = gm.OVER
gm.setup(gm.level_manager.get_level())
for i in range(len(e_list)): # is enemy missile hits player
for j in range(len(e_list[i].missile_list)):
self.em_rect = Rect(e_list[i].missile_list[j].x, e_list[i].missile_list[j].y,
m_width, m_height)
if (self.player_rect.colliderect(self.em_rect)):
e_list[i].missile_list[j].on = False
ex.create_explosion(player.pos.x + 2, player.pos.y + 2)
score.set_score(-1)
if (score.score < 0):
gm.state = gm.OVER
gm.setup(gm.level_manager.get_level())
for i in range(len(e_list)): # is player missile hits enemy
self.em_rect = Rect(e_list[i].x, e_list[i].y, width, height)
for j in range(len(player.getMissileManager().missile_list)):
self.mm_rect = Rect(player.getMissileManager().missile_list[j].x,
player.getMissileManager().missile_list[j].y, player.getMissileManager().width,
player.getMissileManager().height)
if (self.em_rect.colliderect(self.mm_rect)):
e_list[i].on = False
player.getMissileManager().missile_list[j].on = False
if (e_list[i].hit == False):
ex.create_explosion(e_list[i].x, e_list[i].y + 2)
e_list[i].hit = True
if(level == 3):
score.set_score(10)
else:
score.set_score(1)
if (score.score >= gm.level_manager.get_level() * 30):
gm.level_manager.increase_level()
Here is what level 3 looks like.
http://gamingdirectional.com/wp-content/uploads/2018/12/game_strike-4.mp4Now we have concluded the game level related topics and we will create the about scene and the credit scene in the next chapter.