Final touch up for the boy boundary detection mechanism

Sorry for not posting yesterday as I am terribly sick, although I am still sick today mine condition is a lot more better now. After the previous article we have basically developed a boundary detection mechanism for the player object and in this article, we will do the final touch up for that mechanism. Here are the final rules that we need to apply in order to complete the boundary detection mechanism for the boy.

  1. If the boy is halfway up or down when he is insides a ladder then he can either move up or down but not side-way.
  2. If the boy has touched the bottom of the ladder then he can move both side or go up the ladder again but not go downward.
  3. The boy will not be able to move even further if there is an empty space below his feet to avoid him from falling down.

With the above three rules in place, we will slightly modify the boy object class by introducing a new side boundary list which will prevent the boy from going even further if the bottom of his feet is an empty space.

class BoyObject(object):

    def __init__(self):

        self.list_1 = [

            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        ]

        self.ladder_boundary_1 = [[9 * 64, 8 * 64],
                                  [9 * 64, 7 * 64],
                                  [5 * 64, 6 * 64],
                                  [5 * 64, 5 * 64],
                                  [2 * 64, 3 * 64],
                                  [2 * 64, 4 * 64],
                                  [0 * 64, 1 * 64],
                                  [0 * 64, 2 * 64],
                                  ] # the boundary of the ladder

        self.boundary_bottom_1 = [[9 * 64, 9 * 64],
                                  [5 * 64, 7 * 64],
                                  [2 * 64, 5 * 64],
                                  [0 * 64, 3 * 64]]  # the bottom boundary of the ladder

        self.boundary_side_1 = [[4 * 64, 6 * 64],
                                [1 * 64, 4 * 64],
                                [6 * 64, 2 * 64], ]  # the side boundary of the player

        self.initial_1 = [0, 8 * 64]

    def get_original_position(self, level):

        if (level == 1):
            return self.initial_1

    def get_object_list(self, level):

        if(level == 1):
            return self.list_1

    def get_object_boundary(self, level):

        if (level == 1):
            return self.ladder_boundary_1

    def get_object_bottom_boundary(self, level):

        if (level == 1):
            return self.boundary_bottom_1

    def get_object_side_boundary(self, level):

        if (level == 1):
            return self.boundary_side_1

Next, we will need to check the side boundary of the boy to make sure he will not fall down beside checking the ladder boundary and the bottom boundary of the ladder.

from BoyObject import BoyObject
from pygame import math as mt
from pygame.locals import *
from GameSprite import GameSprite

class BoySprite(object):

    def __init__(self, scene, level):

        self.row = 10
        self.column = 10
        self.scene = scene # game scene instance
        self.space = 64 # image width and height
        self.level = level # current game level
        self.frame = 3
        self.prepare_boy(self.level)
        self.WIDTH = 640

    def prepare_boy(self, level):
        self.boy_object = BoyObject()
        self.boy_object_list = self.boy_object.get_object_list(level)
        self.boy_original_position = self.boy_object.get_original_position(level)
        self.x = self.boy_original_position[0]
        self.y = self.boy_original_position[1]
        self.speed = 2
        self.boy_image_sprite_right = 'Asset/bright.png'
        self.boy_image_sprite_left = 'Asset/bleft.png'
        self.boy_sprite = self.boy_image_sprite_right
        self.left = False
        self.up = False
        self.ladder = False
        self.boy_rect = Rect(self.frame * 64, 0, 64, 64)
        self.sprite_boy = GameSprite(self.boy_sprite, self.boy_rect)
        self.boy_surface = self.sprite_boy.getImage()
        self.boy_ladder_list = self.boy_object.get_object_boundary(level)
        self.boy_bottom_boundary_list = self.boy_object.get_object_bottom_boundary(level)
        self.boy_side_boundary_list = self.boy_object.get_object_side_boundary(level)
        self.initialize()

    # set the x and y direction for the player object

    def setX(self, x):

        if(self.ladder == True):
            return
        self.x += x
        if (self.up == True and x < 0):
            self.frame = 1
            self.up = False
        elif(self.up == True and x > 0):
            self.frame = 0
            self.up = False
        if(x < 0):
            self.left = True
            self.frame += 1
            if (self.frame > 5):
                self.frame = 1
            self.boy_sprite = self.boy_image_sprite_left
        elif(x > 0):
            self.frame += 1
            self.left = False
            if (self.frame > 4):
                self.frame = 0
            self.boy_sprite = self.boy_image_sprite_right
        elif(x == 0):
            if(self.left == True):
                self.frame = 2
                self.boy_sprite = self.boy_image_sprite_left
            elif(self.left == False):
                self.frame = 3
                self.boy_sprite = self.boy_image_sprite_right

        self.boy_rect = Rect(self.frame * 64, 0, 64, 64)
        self.sprite_boy = GameSprite(self.boy_sprite, self.boy_rect)
        self.boy_surface = self.sprite_boy.getImage()

    def setY(self, y):

        self.boy_rect = Rect(self.x, self.y+y, 64, 64)
        if(self.isUpDown(self.boy_rect, y) == True):
            self.y += y
        if(y == 0):
            self.frame = 6
        elif(self.up == False):
            self.frame = 6
            self.up = True
        else:
            if(y < 0):
                self.frame -= 1
            elif(y > 0):
                self.frame += 1
            if(self.frame > 10):
                self.frame = 6
            elif(self.frame < 6):
                self.frame += 2
        self.boy_sprite = self.boy_image_sprite_right
        self.boy_rect = Rect(self.frame * 64, 0, 64, 64)
        self.sprite_boy = GameSprite(self.boy_sprite, self.boy_rect)
        self.boy_surface = self.sprite_boy.getImage()

    def checkboundary(self):

        if(self.x < 0):
            self.x = 0
        elif(self.x > self.WIDTH - self.space):
            self.x = self.WIDTH - self.space
        else:
            self.isLeftRight()


    def isUpDown(self, rect, y):

        for boundary in self.boy_ladder_list:
            boundary_rect = Rect(boundary[0], boundary[1], 64, 64)
            if ((boundary_rect.collidepoint(self.x, self.y+y) == True or boundary_rect.collidepoint(self.x, self.y+self.space+y) == True) and (self.x % self.space == 0)):
                for boundary_bottom in self.boy_bottom_boundary_list:
                    boundary_rect = Rect(boundary_bottom[0], boundary_bottom[1], 64, 64)
                    if (boundary_rect.colliderect(rect) == True):
                        self.ladder = False
                        return False
                self.ladder = True
                return True
        self.ladder = False
        return False

    def isLeftRight(self):

        for boundary in self.boy_side_boundary_list:
            boundary_rect = Rect(boundary[0], boundary[1], 64, 64)
            boy_rect = Rect(self.x, self.y, 64, 64)
            if (boundary_rect.colliderect(boy_rect) == True):
                if(self.left == True):
                    self.x += self.speed
                else:
                    self.x -= self.speed

    def update(self):
        self.checkboundary()
        self.move_boy()

    def move_boy(self):
        self.draw_pos = mt.Vector2(self.x, self.y)  # the position of the image on game scene

    def initialize(self):
        for row in range(self.row):
            for column in range(self.column):

                if(self.boy_object_list[row][column] == 1):

                    self.draw_pos = mt.Vector2(self.x, self.y)  # the position of the image on game scene
                    self.scene.blit(self.boy_surface, self.draw_pos)  # draw enemy frame

    def draw(self):

        self.scene.blit(self.boy_surface, self.draw_pos)  # draw enemy frame

Before the boy can move even further the pygame program needs to make sure he can go up, down, left or right.

Like, share or follow me on twitter.

Moving the player object in Pygame

In the last chapter we have created the animation effect for the player object and in this chapter, we will move the player object in the x-axis. We will leave the wall and boundary collision detection mechanism to the next chapter. In the last chapter we have already linked up the keyboard events with the game manager class and in this chapter, we only need a slight modification to move the player across the scene when the left or the right arrow key has been pressed. One of the problems with the pygame event module is that we need to activate the repeated event detection process by our-self with this single line of code before the module can send the repeated keypress event (which means when someone is holding the same key on the keyboard) to us.

pygame.key.set_repeat(100, 40)

By setting the delay and interval in the pygame.key.set_repeat method the program will continue to receive the information of the key which the player has pressed on at the moment, this is very important because if the key repeated event has been disabled then the program will only get the keypress’s feedback once after the user has pressed on any key on the keyboard and will not receive the key pressed event again even-though the user has held on to that same key after he has pressed on it. We need to continuously receive the feedback from the pygame key event module in order to move the player smoothly across the canvas. Below is the modified version of the main file.

import pygame
from pygame.locals import *
from GameManager import GameManager

pygame.init()

size = width, height = 640, 640
pygame.display.set_caption("Amaze Boy")  # set the title of the window
screen = pygame.display.set_mode(size)
game_manager = GameManager(screen)
rect_exit = Rect(229, 456, 200, 53)  # the position of the exit button on the home scene
running = True
pygame.key.set_repeat(100, 40)

while running:

    for event in pygame.event.get():
        # when the user clicks on the 'x'
        if event.type == pygame.QUIT:
            game_manager.save_level()
            running = False

        # detect key press event
        if event.type == KEYDOWN:

            if (game_manager.state == 1):

                if event.key == K_LEFT:
                    game_manager.set_player_x(-2)
                elif event.key == K_RIGHT:
                    game_manager.set_player_x(2)
                elif event.key == K_UP:
                    game_manager.set_player_y(-2)
                elif event.key == K_DOWN:
                    game_manager.set_player_y(2)

        elif event.type == pygame.MOUSEBUTTONDOWN:
            x, y = event.pos
            if (rect_exit.collidepoint(x, y) and game_manager.state == game_manager.LOAD):
                game_manager.save_level()
                running = False
            # 1 is the left mouse button
            elif event.button == 1:
                game_manager.isAreaClick(x, y)

    game_manager.loop()

Next, we will modify the game manager class by including the boy sprite update method in the update method of this class.

from EnemyManager import EnemyManager
from Overlap import Overlap
from ExplosionManager import ExplosionManager
from Score import Score
from StartScene import StartScene
from pygame.locals import *
from LevelManager import LevelManager
import pygame
import webbrowser
from Scene import Scene
from BackGroundSprite import BackGroundSprite
from BoySprite import BoySprite

class GameManager(object):

    def __init__(self, scene):

        self.scene = scene

        self.load_music()
        self.play_music()
        self.overlap_manager = Overlap()
        self.level_manager = LevelManager(self)
        self.level_manager.set_level()
        self.setup(self.level_manager.get_level())
        self.start_scene = StartScene(scene, self.level_manager)

        self.pause = False # flag to pause the game

        self.game_scene = Scene(self.scene)

        #game state
        self.LOAD = 0
        self.GAME = 1
        self.OVER = 2
        self.NEXT = 3
        self.WIN = 4
        self.ABOUT = 5
        self.MANUAL = 6
        self.PAUSE = 7
        self.SCORE = 8
        self.SCENE = 9

        self.state = self.LOAD

    def setup(self, game_level):

        self.game_level = game_level
        self.score_manager = Score(self.scene, self.level_manager)
        self.background = BackGroundSprite(game_level, self.scene)
        self.enemy_manager = EnemyManager(self.scene, game_level)
        self.boy_sprite = BoySprite(self.scene, game_level)
        self.explosion_manager = ExplosionManager(self.scene)

    def loop(self):

        if(self.state == self.LOAD):
            self.start_scene.draw(self.state)
        elif(self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE):
            self.start_scene.draw(self.state)
        elif(self.state == self.SCENE):
            self.game_scene.draw()
        elif(self.state == self.GAME):

            self.update()
            self.draw()

        elif(self.state == self.PAUSE):

            self.start_scene.draw(self.state)

    def isAreaClick(self, x, y):
        if (self.state == self.LOAD or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.SCORE or self.state == self.SCENE or self.state == self.MANUAL or self.state == self.PAUSE):
            self.rect = Rect(177, 274, 306, 112) # the position of the play button on the scene
            self.rect_play = Rect(229, 200, 200, 53)  # the position of the play button on the home scene
            self.rect_about = Rect(229, 263, 200, 53)  # the position of the about button on the home scene
            #self.rect_exit = Rect(229, 456, 200, 53)  # the position of the exit button on the home scene
            self.rect_pause_home = Rect(229, 263, 200, 53)  # the position of the home button on pause scene
            self.rect_score = Rect(229, 328, 200, 53)  # the position of the score button on the home scene
            self.rect_manual = Rect(229, 393, 200, 53)  # the position of the manual button on the home scene
            self.rect_scene = Rect(229, 519, 200, 53)  # the position of the manual button on the home scene
            self.rect_back = Rect(10, 620, 40, 30)  # the position of the back button on the home scene
            self.rect_sound = Rect(10, 600, 30, 30) # the position of the sound button on the home scene
            self.rect_scene_next = Rect(610, 330, 30, 30)  # the position of the next scene button on scene
            self.rect_scene_previous = Rect(50, 330, 30, 30)  # the position of the previous scene button on scene

            if(self.rect.collidepoint(x, y) and (self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN)):
                self.state = self.GAME
            elif(self.rect_play.collidepoint(x,y) and self.state == self.LOAD):
                self.state = self.GAME
            elif (self.rect_play.collidepoint(x, y) and self.state == self.PAUSE):
                self.state = self.GAME
            elif (self.rect_about.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.ABOUT
            elif (self.rect_score.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCORE
            elif (self.rect_scene.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCENE
            elif (self.rect_back.collidepoint(x, y) and self.state == self.SCENE):
                self.state = self.LOAD
            elif (self.rect_scene_next.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_next_image()
            elif (self.rect_scene_previous.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_previous_image()
            elif (self.rect_pause_home.collidepoint(x, y) and self.state == self.PAUSE):

                self.state = self.LOAD
                self.setup(self.level_manager.get_level())
                self.save_level()

            elif (self.rect_manual.collidepoint(x, y) and self.state == self.LOAD):
                webbrowser.open_new('http://gamingdirectional.com/blog/2018/12/25/air-strike//')
            elif (self.rect_back.collidepoint(x, y) and (self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE)):
                self.state = self.LOAD
            elif (self.rect_sound.collidepoint(x, y) and self.state == self.LOAD):

                if(self.start_scene.soundon == True):
                    self.start_scene.soundon = False
                    pygame.mixer_music.pause()
                else:
                    self.start_scene.soundon = True
                    pygame.mixer_music.unpause()

    def save_level(self):
        self.level_manager.save_level()

    def set_pause(self, pause):

        self.pause = pause

        if(self.pause == True):

            self.state = self.PAUSE

    def load_music(self):
        pygame.mixer_music.load('Music/winternight.ogg')

    def play_music(self):
        pygame.mixer_music.play(-1) #play the music infinite time

    def set_player_x(self, _x):
        if (self.state == self.GAME):
            self.boy_sprite.setX(_x)

    def save_scene(self):
        self.game_scene.take_screen()

    def set_player_y(self, _y):
        if (self.state == self.GAME):
            self.boy_sprite.setY(_y)

    def update(self):
        self.enemy_manager.update()
        self.boy_sprite.update()
        #self.isOverlap()
        #self.explosion_manager.explosion_update()

    # check for player, enemy, missiles overlap
    def isOverlap(self):
        self.overlap_manager.isOverlap(self.boy_sprite, self.enemy_manager, self.explosion_manager, self.score_manager, self)

    def draw(self):
        if(self.state == self.GAME):
            self.background.draw()

            #self.enemy_manager.update()
            #self.explosion_manager.draw()
            #self.score_manager.draw()
            self.boy_sprite.draw()
            self.enemy_manager.draw()
            pygame.display.flip()

Finally we will slightly modify the boy sprite class.

from BoyObject import BoyObject
from pygame import math as mt
from pygame.locals import *
from GameSprite import GameSprite

class BoySprite(object):

    def __init__(self, scene, level):

        self.row = 10
        self.column = 10
        self.scene = scene # game scene instance
        self.space = 64 # image width and height
        self.level = level # current game level
        self.frame = 3
        self.prepare_boy(self.level)

    def prepare_boy(self, level):
        self.boy_object = BoyObject()
        self.boy_object_list = self.boy_object.get_object_list(level)
        self.boy_original_position = self.boy_object.get_original_position(level)
        self.x = self.boy_original_position[0]
        self.y = self.boy_original_position[1]
        self.boy_image_sprite_right = 'Asset/bright.png'
        self.boy_image_sprite_left = 'Asset/bleft.png'
        self.boy_sprite = self.boy_image_sprite_right
        self.left = False
        self.up = False
        self.boy_rect = Rect(self.frame * 64, 0, 64, 64)
        self.sprite_boy = GameSprite(self.boy_sprite, self.boy_rect)
        self.boy_surface = self.sprite_boy.getImage()
        self.initialize()

    # set the x and y direction for the player object

    def setX(self, x):
        self.up = False
        self.x += x
        if(x < 0):
            self.left = True
            self.frame += 1

            if (self.frame > 5):
                self.frame = 1
            self.boy_sprite = self.boy_image_sprite_left
        elif(x > 0):
            self.frame += 1

            self.left = False
            if (self.frame > 4):
                self.frame = 0
            self.boy_sprite = self.boy_image_sprite_right
        elif(x == 0):
            if(self.left == True):
                self.frame = 2
                self.boy_sprite = self.boy_image_sprite_left
            elif(self.left == False):
                self.frame = 3
                self.boy_sprite = self.boy_image_sprite_right

        self.boy_rect = Rect(self.frame * 64, 0, 64, 64)
        self.sprite_boy = GameSprite(self.boy_sprite, self.boy_rect)
        self.boy_surface = self.sprite_boy.getImage()

    def setY(self, y):
        if(y == 0 or self.up == False):
            self.frame = 6
            self.up = True
        else:
            if(y < 0):
                self.frame -= 1
            elif(y > 0):
                self.frame += 1
            if(self.frame > 10):
                self.frame = 0
            elif(self.frame < 6):
                self.frame += 2
        self.boy_sprite = self.boy_image_sprite_right
        self.boy_rect = Rect(self.frame * 64, 0, 64, 64)
        self.sprite_boy = GameSprite(self.boy_sprite, self.boy_rect)
        self.boy_surface = self.sprite_boy.getImage()

    def update(self):
        self.draw_pos = mt.Vector2(self.x, self.y)  # the position of the image on game scene

    def initialize(self):
        for row in range(self.row):

            for column in range(self.column):

                if(self.boy_object_list[row][column] == 1):

                    self.draw_pos = mt.Vector2(self.x, self.y)  # the position of the image on game scene
                    self.scene.blit(self.boy_surface, self.draw_pos)  # draw enemy frame

    def draw(self):

        self.scene.blit(self.boy_surface, self.draw_pos)  # draw enemy frame

Just in case you wonder why the boy’s sprite has such a wield frame number, I will leave two sprite sheets of the boy object below for you to figure it out.

bright.png
bleft.png

If you run the above program and press the left or right key on your keyboard you will see the below outcome. As I have mentioned earlier the boy’s boundary detection part will be on the next chapter.

Hope you like this post, like, share or tweet!

Create a player object in pygame

In this article, we will create a player sprite class which will render the player image on the game scene. First, we will create the player object class which serves as the container for the player’s location data.

class BoyObject(object):

    def __init__(self):

        self.list_1 = [

            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        ]

        self.initial_1 = [0, 8 * 64]

    def get_original_position(self, level):

        if (level == 1):
            return self.initial_1

    def get_object_list(self, level):

        if(level == 1):
            return self.list_1

The next part is the player sprite class which will handle the image rendering process.

from BoyObject import BoyObject
from pygame import math as mt
from pygame.locals import *
from GameSprite import GameSprite

class BoySprite(object):

    def __init__(self, scene, level):

        self.row = 10
        self.column = 10
        self.scene = scene # game scene instance
        self.space = 64 # image width and height
        self.level = level # current game level
        self.prepare_boy(self.level)

    def prepare_boy(self, level):
        self.boy_object = BoyObject()
        self.boy_object_list = self.boy_object.get_object_list(level)
        self.boy_original_position = self.boy_object.get_original_position(level)
        self.x = self.boy_original_position[0]
        self.y = self.boy_original_position[1]
        self.enemy_image_sprite_right = 'Asset/bright.png'
        self.boy_rect = Rect(3 * 64, 0, 64, 64)
        self.sprite_boy = GameSprite(self.enemy_image_sprite_right, self.boy_rect)
        self.boy_surface = self.sprite_boy.getImage()

    def update(self):

        pass

    def draw(self):

        for row in range(self.row):

            for column in range(self.column):

                if(self.boy_object_list[row][column] == 1):

                    self.draw_pos = mt.Vector2(self.x, self.y)  # the position of the image on game scene
                    self.scene.blit(self.boy_surface, self.draw_pos)  # draw enemy frame

We will render the fourth standstill sprite on the player sprite sheet. Next, we will edit the game manager class to make it includes the player sprite class in it.

from Player import Player
from EnemyManager import EnemyManager
from Overlap import Overlap
from ExplosionManager import ExplosionManager
from Score import Score
from StartScene import StartScene
from pygame.locals import *
from LevelManager import LevelManager
import pygame
import webbrowser
from Scene import Scene
from BackGroundSprite import BackGroundSprite
from BoySprite import BoySprite

class GameManager(object):

    def __init__(self, scene):

        self.scene = scene

        self.load_music()
        self.play_music()
        self.overlap_manager = Overlap()
        self.level_manager = LevelManager(self)
        self.level_manager.set_level()
        self.setup(self.level_manager.get_level())
        self.start_scene = StartScene(scene, self.level_manager)

        self.pause = False # flag to pause the game

        self.game_scene = Scene(self.scene)

        #game state
        self.LOAD = 0
        self.GAME = 1
        self.OVER = 2
        self.NEXT = 3
        self.WIN = 4
        self.ABOUT = 5
        self.MANUAL = 6
        self.PAUSE = 7
        self.SCORE = 8
        self.SCENE = 9

        self.state = self.LOAD

    def setup(self, game_level):

        self.game_level = game_level
        self.score_manager = Score(self.scene, self.level_manager)
        self.background = BackGroundSprite(game_level, self.scene)
        self.player = Player(self.scene)
        self.enemy_manager = EnemyManager(self.scene, game_level)
        self.boy_sprite = BoySprite(self.scene, game_level)
        self.explosion_manager = ExplosionManager(self.scene)

    def loop(self):

        if(self.state == self.LOAD):
            self.start_scene.draw(self.state)
        elif(self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE):
            self.start_scene.draw(self.state)
        elif(self.state == self.SCENE):
            self.game_scene.draw()
        elif(self.state == self.GAME):

            self.update()
            self.draw()

        elif(self.state == self.PAUSE):

            self.start_scene.draw(self.state)

    def isAreaClick(self, x, y):
        if (self.state == self.LOAD or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.SCORE or self.state == self.SCENE or self.state == self.MANUAL or self.state == self.PAUSE):
            self.rect = Rect(177, 274, 306, 112) # the position of the play button on the scene
            self.rect_play = Rect(229, 200, 200, 53)  # the position of the play button on the home scene
            self.rect_about = Rect(229, 263, 200, 53)  # the position of the about button on the home scene
            #self.rect_exit = Rect(229, 456, 200, 53)  # the position of the exit button on the home scene
            self.rect_pause_home = Rect(229, 263, 200, 53)  # the position of the home button on pause scene
            self.rect_score = Rect(229, 328, 200, 53)  # the position of the score button on the home scene
            self.rect_manual = Rect(229, 393, 200, 53)  # the position of the manual button on the home scene
            self.rect_scene = Rect(229, 519, 200, 53)  # the position of the manual button on the home scene
            self.rect_back = Rect(10, 620, 40, 30)  # the position of the back button on the home scene
            self.rect_sound = Rect(10, 600, 30, 30) # the position of the sound button on the home scene
            self.rect_scene_next = Rect(610, 330, 30, 30)  # the position of the next scene button on scene
            self.rect_scene_previous = Rect(50, 330, 30, 30)  # the position of the previous scene button on scene

            if(self.rect.collidepoint(x, y) and (self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN)):
                self.state = self.GAME
            elif(self.rect_play.collidepoint(x,y) and self.state == self.LOAD):
                self.state = self.GAME
            elif (self.rect_play.collidepoint(x, y) and self.state == self.PAUSE):
                self.state = self.GAME
            elif (self.rect_about.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.ABOUT
            elif (self.rect_score.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCORE
            elif (self.rect_scene.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCENE
            elif (self.rect_back.collidepoint(x, y) and self.state == self.SCENE):
                self.state = self.LOAD
            elif (self.rect_scene_next.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_next_image()
            elif (self.rect_scene_previous.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_previous_image()
            elif (self.rect_pause_home.collidepoint(x, y) and self.state == self.PAUSE):

                self.state = self.LOAD
                self.setup(self.level_manager.get_level())
                self.save_level()

            elif (self.rect_manual.collidepoint(x, y) and self.state == self.LOAD):
                webbrowser.open_new('http://gamingdirectional.com/blog/2018/12/25/air-strike//')
            elif (self.rect_back.collidepoint(x, y) and (self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE)):
                self.state = self.LOAD
            elif (self.rect_sound.collidepoint(x, y) and self.state == self.LOAD):

                if(self.start_scene.soundon == True):
                    self.start_scene.soundon = False
                    pygame.mixer_music.pause()
                else:
                    self.start_scene.soundon = True
                    pygame.mixer_music.unpause()

    def save_level(self):
        self.level_manager.save_level()

    def set_pause(self, pause):

        self.pause = pause

        if(self.pause == True):

            self.state = self.PAUSE

    def load_music(self):
        pygame.mixer_music.load('Music/winternight.ogg')

    def play_music(self):
        pygame.mixer_music.play(-1) #play the music infinite time

    def set_player_x(self, _x):
        if (self.state == self.GAME):
            self.player.setX(_x)

    def save_scene(self):
        self.game_scene.take_screen()

    def set_player_y(self, _y):
        if (self.state == self.GAME):
            self.player.setY(_y)

    def set_missile_strike(self, strike):
        if (self.state == self.GAME):
            self.player.setStrike(strike)

    def update(self):
        #self.player.update()
        self.enemy_manager.update()
        #self.isOverlap()
        #self.explosion_manager.explosion_update()

    # check for player, enemy, missiles overlap
    def isOverlap(self):
        self.overlap_manager.isOverlap(self.player, self.enemy_manager, self.explosion_manager, self.score_manager, self)

    def draw(self):
        if(self.state == self.GAME):
            self.background.draw()
            self.boy_sprite.draw()
            #self.enemy_manager.update()
            self.enemy_manager.draw()
            #self.explosion_manager.draw()
            #self.score_manager.draw()
            pygame.display.flip()

There we have it, if we run the above program we will make the player sprite renders the standstill image of the boy on the bottom left of the game scene.

Like, share and comment on above tweet or follow me on twitter.

Move the enemy object with pygame

Hi, here is another quick post on the latest pygame project which I have developed lately. In the previous article, we have created an animated enemy object which can switch direction using the timer control. The timer control is only for demonstration purpose only, during the game the enemy will only switch direction if it hits any obstacle in its path. In this chapter, we will take out the timer and create the moving enemy object which will only switch the direction once it hits an obstacle. The obstacle is consists of an imagination block located on both the right and the left side of the enemy’s path. Each enemy has its own obstacle attached to it. In order to achieve this result, we need to edit three classes. 1) The enemy class which will receive two parameters, the list which contains the left and the right obstacles and the original position of the enemy. The enemy will also move in the x-direction on every update.

from pygame.locals import *
from GameSprite import GameSprite

class Enemy(object):

    def __init__(self, boundary_list, original_position_list):

        self.count = -1
        self.forward = False
        self.timer = 0
        self.right = True
        self.switch_timer = 900
        self.switch_timer_left = 900
        self.sprite_frame_list_right = []
        self.sprite_frame_list_left = []

        #boundary for enemy object
        self.left_boundary = Rect(boundary_list[0][0], boundary_list[0][1], 64, 64)
        self.right_boundary = Rect(boundary_list[1][0], boundary_list[1][1], 64, 64)

        self.x = original_position_list[0]
        self.y = original_position_list[1]

        self.enemy_image_sprite_right = 'Asset/right.png'
        self.enemy_image_sprite_left = 'Asset/left.png'

        self.sprite_frame_list = self.create_surface(self.enemy_image_sprite_right)

    def create_surface(self, enemy_image_sprite):

        if(self.right == True and len(self.sprite_frame_list_right) &gt; 0):
            return self.sprite_frame_list_right
        elif (self.right == True and len(self.sprite_frame_list_right) &lt;= 0):
            self.sprite_frame_list_right = self.create_sub_surface(enemy_image_sprite, self.sprite_frame_list_right)
            return self.sprite_frame_list_right
        elif(self.right == False and len(self.sprite_frame_list_left) &gt; 0):
            return self.sprite_frame_list_left
        elif (self.right == False and len(self.sprite_frame_list_left) &lt;= 0):
            self.sprite_frame_list_left = self.create_sub_surface(enemy_image_sprite, self.sprite_frame_list_left)
            return self.sprite_frame_list_left

    def create_sub_surface(self, enemy_image_sprite, sprite_frame_list):
        # the first frame
        self.frame_1_rect = Rect(0, 0, 64, 64)
        self.sprite_frame_1 = GameSprite(enemy_image_sprite, self.frame_1_rect)
        self.sprite_frame_1_surface = self.sprite_frame_1.getImage()
        sprite_frame_list.append(self.sprite_frame_1_surface)
        # the second frame
        self.frame_2_rect = Rect(64, 0, 64, 64)
        self.sprite_frame_2 = GameSprite(enemy_image_sprite, self.frame_2_rect)
        self.sprite_frame_2_surface = self.sprite_frame_2.getImage()
        sprite_frame_list.append(self.sprite_frame_2_surface)
        # the third frame
        self.frame_3_rect = Rect(64 * 2, 0, 64, 64)
        self.sprite_frame_3 = GameSprite(enemy_image_sprite, self.frame_3_rect)
        self.sprite_frame_3_surface = self.sprite_frame_3.getImage()
        sprite_frame_list.append(self.sprite_frame_3_surface)
        # the fourth frame
        self.frame_4_rect = Rect(64 * 3, 0, 64, 64)
        self.sprite_frame_4 = GameSprite(enemy_image_sprite, self.frame_4_rect)
        self.sprite_frame_4_surface = self.sprite_frame_4.getImage()
        sprite_frame_list.append(self.sprite_frame_4_surface)
        # the fifth frame
        self.frame_5_rect = Rect(64 * 4, 0, 64, 64)
        self.sprite_frame_5 = GameSprite(enemy_image_sprite, self.frame_5_rect)
        self.sprite_frame_5_surface = self.sprite_frame_5.getImage()
        sprite_frame_list.append(self.sprite_frame_5_surface)
        # the sixth frame
        self.frame_6_rect = Rect(64 * 5, 0, 64, 64)
        self.sprite_frame_6 = GameSprite(enemy_image_sprite, self.frame_6_rect)
        self.sprite_frame_6_surface = self.sprite_frame_6.getImage()
        sprite_frame_list.append(self.sprite_frame_6_surface)
        # the seventh frame
        self.frame_7_rect = Rect(64 * 6, 0, 64, 64)
        self.sprite_frame_7 = GameSprite(enemy_image_sprite, self.frame_7_rect)
        self.sprite_frame_7_surface = self.sprite_frame_7.getImage()
        sprite_frame_list.append(self.sprite_frame_7_surface)

        return sprite_frame_list

    def update(self):
        #self.switch_position()
        self.checkboundary()
        self.change_graphic()
        self.move_x()

    def checkboundary(self):
        if(self.left_boundary.collidepoint(self.x, self.y)):
            self.right = False
            self.x += 0.2
            self.sprite_frame_list = self.create_surface(self.enemy_image_sprite_left)
        elif(self.right_boundary.collidepoint(self.x, self.y)):
            self.right = True
            self.x -= 0.2
            self.sprite_frame_list = self.create_surface(self.enemy_image_sprite_right)

    def move_x(self):
        if(self.right == True):
            self.x -= 0.2
        else:
            self.x += 0.2

    def change_graphic(self):
        if (self.right == True):
            if (self.timer &gt; 26):
                if (self.count &gt; 6 and self.forward == True):  # use this logic to control the counter and the image
                    self.count -= 1
                    self.forward = False
                elif (self.count &lt; 1 and self.forward == False):
                    self.count += 1
                    self.forward = True
                elif (self.forward == False):
                    self.count -= 1
                elif (self.forward == True):
                    self.count += 1
                self.timer = 0
            else:
                self.timer += 1
        else:
            if (self.timer &gt; 26):
                if (self.count &gt; 5 and self.forward == True):  # use this logic to control the counter and the image
                    self.count -= 1
                    self.forward = False
                elif (self.count &lt; 0 and self.forward == False):
                    self.count += 1
                    self.forward = True
                elif (self.forward == False):
                    self.count -= 1
                elif (self.forward == True):
                    self.count += 1
                self.timer = 0
            else:
                self.timer += 1

    def switch_position(self):

        if(self.switch_timer &lt;= 0):
            self.right = False
            self.timer = 0
            self.count = 0
            self.switch_timer = 900
            self.sprite_frame_list=self.create_surface(self.enemy_image_sprite_left)
        elif (self.right == True and self.switch_timer &gt; 0):
            self.switch_timer -= 1
        elif(self.right == False and self.switch_timer_left &gt; 0):
            self.switch_timer_left -= 1
        elif(self.switch_timer_left &lt;= 0):
            self.right = True
            self.timer = 0
            self.count = 0
            self.switch_timer_left = 900
            self.sprite_frame_list=self.create_surface(self.enemy_image_sprite_right)

    def get_enemy_surface(self):

        return self.sprite_frame_list[self.get_count()]

    def get_count(self):

        if(self.count &lt; 1 and self.forward == False):
            self.count += 1
            self.forward = True
        elif(self.count &gt; 6 and self.forward == True):
            self.count -= 1
            self.forward = False

        return self.count

2) The enemy object class will now contain the original position list and the obstacle list for each level of the game.

class EnemyObject(object):

    def __init__(self):

        self.list_1 = [

            [0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        ]

        self.boundary_1 = [
            [[0, 0], [8 * 64, 0]],
            [[0, 0], [8 * 64, 0]],
            [[2 * 64, 4 * 64], [8 * 64, 4 * 64]],
            [[2 * 64, 4 * 64], [8 * 64, 4 * 64]],
            [[5 * 64, 6 * 64], [8 * 64, 6 * 64]]
        ]

        self.initial_1 = [[64, 0], [5 * 64, 0],[4 * 64, 4 * 64], [8 * 64, 4 * 64],[6 * 64, 6 * 64]]

    def get_original_position(self, level):

        if (level == 1):
            return self.initial_1

    def get_object_list(self, level):

        if(level == 1):
            return self.list_1

    def get_object_boundary(self, level):

        if (level == 1):
            return self.boundary_1

3) The next class we need to edit is the enemy sprite class which will then connect the above two classes up!

from EnemyObject import EnemyObject
from pygame import math as mt
from Enemy import Enemy

class EnemySprite(object):

    def __init__(self, level, scene):

        self.row = 10
        self.column = 10
        self.scene = scene # game scene instance
        self.space = 64 # image width and height

        self.level = level # current game level

        self.enemy_object = EnemyObject()

        self.create_enemy(level)

    def create_enemy(self, level):

        self.total_enemy_list = []
        self.enemy_boundary_list = self.enemy_object.get_object_boundary(level)
        self.enemy_original_position = self.enemy_object.get_original_position(level)

        i = 0
        if(level == 1):
            while(i < 5):
                self.total_enemy_list.append(Enemy(self.enemy_boundary_list[i], self.enemy_original_position[i]))
                i += 1

    def update(self):

        for enemy in self.total_enemy_list:
            enemy.update()

    def draw(self):
        self.counter = 0
        for row in range(self.row):

            for column in range(self.column):

                if(self.enemy_list[row][column] == 1):

                    self.enemy = self.total_enemy_list[self.counter]

                    self.draw_pos = mt.Vector2(self.enemy.x, self.enemy.y)  # the position of the image on game scene

                    self.scene.blit(self.enemy.get_enemy_surface(), self.draw_pos)  # draw enemy frame

                    self.counter += 1


    def get_level(self, level):
        self.enemy_list = self.enemy_object.get_object_list(level)

Once those classes have been updated you will see the above outcome.

Further modifying the enemy class

In the previous article, we have successfully created the animation effect for the enemy object, in this article, we will add in the switch direction method which will switch the direction of the enemy image from facing left to facing right after a certain time period and then continue to switch back and forth. In order to achieve the previous mentioned effect we only need to further edit the enemy class. We will move all the enemy object surface creation processes to the enemy class and only leave a small amount of image rendering codes on the enemy sprite class.

from pygame.locals import *
from GameSprite import GameSprite

class Enemy(object):

    def __init__(self):

        self.count = 0
        self.forward = False
        self.timer = 0
        self.right = True
        self.switch_timer = 900
        self.switch_timer_left = 900
        self.sprite_frame_list_right = []
        self.sprite_frame_list_left = []

        self.enemy_image_sprite_right = 'Asset/right.png'
        self.enemy_image_sprite_left = 'Asset/left.png'

        self.sprite_frame_list = self.create_surface(self.enemy_image_sprite_right)

    def create_surface(self, enemy_image_sprite):

        if(self.right == True and len(self.sprite_frame_list_right) > 0):
            return self.sprite_frame_list_right
        elif (self.right == True and len(self.sprite_frame_list_right) <= 0):
            self.sprite_frame_list_right = self.create_sub_surface(enemy_image_sprite, self.sprite_frame_list_right)
            return self.sprite_frame_list_right
        elif(self.right == False and len(self.sprite_frame_list_left) > 0):
            return self.sprite_frame_list_left
        elif (self.right == False and len(self.sprite_frame_list_left) <= 0):
            self.sprite_frame_list_left = self.create_sub_surface(enemy_image_sprite, self.sprite_frame_list_left)
            return self.sprite_frame_list_left

    def create_sub_surface(self, enemy_image_sprite, sprite_frame_list):
        # the first frame
        self.frame_1_rect = Rect(0, 0, 64, 64)
        self.sprite_frame_1 = GameSprite(enemy_image_sprite, self.frame_1_rect)
        self.sprite_frame_1_surface = self.sprite_frame_1.getImage()
        sprite_frame_list.append(self.sprite_frame_1_surface)
        # the second frame
        self.frame_2_rect = Rect(64, 0, 64, 64)
        self.sprite_frame_2 = GameSprite(enemy_image_sprite, self.frame_2_rect)
        self.sprite_frame_2_surface = self.sprite_frame_2.getImage()
        sprite_frame_list.append(self.sprite_frame_2_surface)
        # the third frame
        self.frame_3_rect = Rect(64 * 2, 0, 64, 64)
        self.sprite_frame_3 = GameSprite(enemy_image_sprite, self.frame_3_rect)
        self.sprite_frame_3_surface = self.sprite_frame_3.getImage()
        sprite_frame_list.append(self.sprite_frame_3_surface)
        # the fourth frame
        self.frame_4_rect = Rect(64 * 3, 0, 64, 64)
        self.sprite_frame_4 = GameSprite(enemy_image_sprite, self.frame_4_rect)
        self.sprite_frame_4_surface = self.sprite_frame_4.getImage()
        sprite_frame_list.append(self.sprite_frame_4_surface)
        # the fifth frame
        self.frame_5_rect = Rect(64 * 4, 0, 64, 64)
        self.sprite_frame_5 = GameSprite(enemy_image_sprite, self.frame_5_rect)
        self.sprite_frame_5_surface = self.sprite_frame_5.getImage()
        sprite_frame_list.append(self.sprite_frame_5_surface)
        # the sixth frame
        self.frame_6_rect = Rect(64 * 5, 0, 64, 64)
        self.sprite_frame_6 = GameSprite(enemy_image_sprite, self.frame_6_rect)
        self.sprite_frame_6_surface = self.sprite_frame_6.getImage()
        sprite_frame_list.append(self.sprite_frame_6_surface)
        # the seventh frame
        self.frame_7_rect = Rect(64 * 6, 0, 64, 64)
        self.sprite_frame_7 = GameSprite(enemy_image_sprite, self.frame_7_rect)
        self.sprite_frame_7_surface = self.sprite_frame_7.getImage()
        sprite_frame_list.append(self.sprite_frame_7_surface)

        return sprite_frame_list

    def update(self):

        self.switch_position()
        self.change_graphic()

    def change_graphic(self):
        if (self.right == True):
            if (self.timer > 30):
                if (self.count > 6 and self.forward == True):  # use this logic to control the counter and the image
                    self.count -= 1
                    self.forward = False
                elif (self.count < 1 and self.forward == False):
                    self.count += 1
                    self.forward = True
                elif (self.forward == False):
                    self.count -= 1
                elif (self.forward == True):
                    self.count += 1
                self.timer = 0
            else:
                self.timer += 1
        else:
            if (self.timer > 30):
                if (self.count > 5 and self.forward == True):  # use this logic to control the counter and the image
                    self.count -= 1
                    self.forward = False
                elif (self.count < 0 and self.forward == False):
                    self.count += 1
                    self.forward = True
                elif (self.forward == False):
                    self.count -= 1
                elif (self.forward == True):
                    self.count += 1
                self.timer = 0
            else:
                self.timer += 1

    def switch_position(self):

        if(self.switch_timer <= 0):
            self.right = False
            self.timer = 0
            self.count = 0
            self.switch_timer = 900
            self.sprite_frame_list=self.create_surface(self.enemy_image_sprite_left)
        elif (self.right == True and self.switch_timer > 0):
            self.switch_timer -= 1
        elif(self.right == False and self.switch_timer_left > 0):
            self.switch_timer_left -= 1
        elif(self.switch_timer_left <= 0):
            self.right = True
            self.timer = 0
            self.count = 0
            self.switch_timer_left = 900
            self.sprite_frame_list=self.create_surface(self.enemy_image_sprite_right)

    def get_enemy_surface(self):

        return self.sprite_frame_list[self.get_count()]

    def get_count(self):

        if(self.count < 1 and self.forward == False):
            self.count += 1
            self.forward = True
        elif(self.count > 6 and self.forward == True):
            self.count -= 1
            self.forward = False

        return self.count

As you can see we have included another sprite sheet for the right facing images. Now, all we need is to modify the enemy sprite class a little bit.

from EnemyObject import EnemyObject
from pygame import math as mt
from Enemy import Enemy

class EnemySprite(object):

    def __init__(self, level, scene):

        self.row = 10
        self.column = 10
        self.scene = scene # game scene instance
        self.space = 64 # image width and height

        self.create_enemy(level)

        self.level = level # current game level

        self.enemy_object = EnemyObject()

    def create_enemy(self, level):
        self.total_enemy_list = []
        i = 0
        if(level == 1):
            while(i < 5):
                self.total_enemy_list.append(Enemy())
                i += 1

    def update(self):

        for enemy in self.total_enemy_list:
            enemy.update()

    def draw(self):
        self.counter = 0
        for row in range(self.row):

            for column in range(self.column):

                self.draw_pos = mt.Vector2(self.space * column, self.space * row) # the position of the image on game scene

                if(self.enemy_list[row][column] == 1):

                    self.enemy = self.total_enemy_list[self.counter]

                    self.scene.blit(self.enemy.get_enemy_surface(), self.draw_pos)  # draw enemy frame

                    self.counter += 1


    def get_level(self, level):
        self.enemy_list = self.enemy_object.get_object_list(level)

Basically, we will get the below outcome after we have changed the above classes.

Modify the enemy sprite’s animation

After we have finished creating our first animated enemy sprite in the previous chapter we will need to further modify that animation class because I have found numerous shortages in the previous program. In the previous program 1) We only create a single counter to handle the sprite animation for all five enemy objects which is simply unrealistic because during the game not every enemy will move to the same frame on the sprite sheet due to the change of the direction of that enemy. 2) There is no adjustment on the image’s transition speed at all, we need to slow down the image transition process so the image will not change too fast.

With all that taking into the consideration we will create an enemy class which will handle each enemy movement differently.

class Enemy(object):

    def __init__(self):

        self.count = 0
        self.forward = False
        self.timer = 0

    def update(self):
        if(self.timer &amp;gt; 30):
            if (self.count &amp;gt; 6 and self.forward == True):  # use this logic to control the counter and the image
                self.count -= 1
                self.forward = False
            elif (self.count &amp;lt; 1 and self.forward == False):
                self.count += 1
                self.forward = True
            elif (self.forward == False):
                self.count -= 1
            elif (self.forward == True):
                self.count += 1
            self.timer = 0
        else:
            self.timer += 1

    def get_count(self):

        if(self.count &amp;lt; 1 and self.forward == False):
            self.count += 1
            self.forward = True
        elif(self.count &amp;gt; 6 and self.forward == True):
            self.count -= 1
            self.forward = False

        return self.count

The above class consists of a image’s counter and a timer which controls the speed of the image transition process.

Now we just need to modify the enemy manager class and the enemy sprite manager class accordingly.

from EnemySprite import EnemySprite

class EnemyManager(object):

    def __init__(self, scene, game_level):

        self.scene = scene
        self.enemy_list = []
        self.level = game_level
        self.enemy = EnemySprite(self.level, self.scene)
        self.create_enemy()

    def create_enemy(self):

        self.enemy.get_level(self.level)

    def update(self):

        self.enemy.update()

    # check the boundary of the enemy with the game scene area
    def check_boundary(self):

        pass

    def draw(self):

        self.enemy.draw()
from EnemyObject import EnemyObject
from pygame.locals import *
from pygame import math as mt
from GameSprite import GameSprite
from Enemy import Enemy

class EnemySprite(object):

    def __init__(self, level, scene):

        self.row = 10
        self.column = 10
        self.enemy_image_sprite = 'Asset/right.png'
        self.scene = scene # game scene instance
        self.space = 64 # image width and height

        self.sprite_frame_list = []

        self.create_enemy(level)

        # the first frame
        self.frame_1_rect = Rect(0, 0, 64, 64)
        self.sprite_frame_1 = GameSprite(self.enemy_image_sprite, self.frame_1_rect)
        self.sprite_frame_1_surface = self.sprite_frame_1.getImage()
        self.sprite_frame_list.append(self.sprite_frame_1_surface)

        # the second frame
        self.frame_2_rect = Rect(64, 0, 64, 64)
        self.sprite_frame_2 = GameSprite(self.enemy_image_sprite, self.frame_2_rect)
        self.sprite_frame_2_surface = self.sprite_frame_2.getImage()
        self.sprite_frame_list.append(self.sprite_frame_2_surface)

        # the third frame
        self.frame_3_rect = Rect(64 * 2, 0, 64, 64)
        self.sprite_frame_3 = GameSprite(self.enemy_image_sprite, self.frame_3_rect)
        self.sprite_frame_3_surface = self.sprite_frame_3.getImage()
        self.sprite_frame_list.append(self.sprite_frame_3_surface)

        # the fourth frame
        self.frame_4_rect = Rect(64 * 3, 0, 64, 64)
        self.sprite_frame_4 = GameSprite(self.enemy_image_sprite, self.frame_4_rect)
        self.sprite_frame_4_surface = self.sprite_frame_4.getImage()
        self.sprite_frame_list.append(self.sprite_frame_4_surface)

        # the fifth frame
        self.frame_5_rect = Rect(64 * 4, 0, 64, 64)
        self.sprite_frame_5 = GameSprite(self.enemy_image_sprite, self.frame_5_rect)
        self.sprite_frame_5_surface = self.sprite_frame_5.getImage()
        self.sprite_frame_list.append(self.sprite_frame_5_surface)

        # the sixth frame
        self.frame_6_rect = Rect(64 * 5, 0, 64, 64)
        self.sprite_frame_6 = GameSprite(self.enemy_image_sprite, self.frame_6_rect)
        self.sprite_frame_6_surface = self.sprite_frame_6.getImage()
        self.sprite_frame_list.append(self.sprite_frame_6_surface)

        # the seventh frame
        self.frame_7_rect = Rect(64 * 6, 0, 64, 64)
        self.sprite_frame_7 = GameSprite(self.enemy_image_sprite, self.frame_7_rect)
        self.sprite_frame_7_surface = self.sprite_frame_7.getImage()
        self.sprite_frame_list.append(self.sprite_frame_7_surface)

        self.level = level # current game level

        self.enemy_object = EnemyObject()

    def create_enemy(self, level):
        self.total_enemy_list = []
        i = 0
        if(level == 1):
            while(i &amp;lt; 5):
                self.total_enemy_list.append(Enemy())
                i += 1

    def update(self):

        for enemy in self.total_enemy_list:
            enemy.update()

    def draw(self):
        self.counter = 0
        for row in range(self.row):

            for column in range(self.column):

                self.draw_pos = mt.Vector2(self.space * column, self.space * row) # the position of the image on game scene

                if(self.enemy_list[row][column] == 1):

                    self.enemy = self.total_enemy_list[self.counter]


                    self.scene.blit(self.sprite_frame_list[self.enemy.get_count()], self.draw_pos)  # draw enemy frame

                    self.counter += 1


    def get_level(self, level):
        self.enemy_list = self.enemy_object.get_object_list(level)

Finally, we do a little bit of modification by activated the update method of the enemy manager instance on the game manager class.

from Player import Player
from EnemyManager import EnemyManager
from Overlap import Overlap
from ExplosionManager import ExplosionManager
from Score import Score
from StartScene import StartScene
from pygame.locals import *
from LevelManager import LevelManager
import pygame
import webbrowser
from Scene import Scene
from BackGroundSprite import BackGroundSprite

class GameManager(object):

    def __init__(self, scene):

        self.scene = scene

        self.load_music()
        self.play_music()
        self.overlap_manager = Overlap()
        self.level_manager = LevelManager(self)
        self.level_manager.set_level()
        self.setup(self.level_manager.get_level())
        self.start_scene = StartScene(scene, self.level_manager)

        self.pause = False # flag to pause the game

        self.game_scene = Scene(self.scene)

        #game state
        self.LOAD = 0
        self.GAME = 1
        self.OVER = 2
        self.NEXT = 3
        self.WIN = 4
        self.ABOUT = 5
        self.MANUAL = 6
        self.PAUSE = 7
        self.SCORE = 8
        self.SCENE = 9

        self.state = self.LOAD

    def setup(self, game_level):

        self.game_level = game_level
        self.score_manager = Score(self.scene, self.level_manager)
        self.background = BackGroundSprite(self.game_level, self.scene)
        self.player = Player(self.scene)
        self.enemy_manager = EnemyManager(self.scene, self.game_level)
        self.explosion_manager = ExplosionManager(self.scene)

    def loop(self):

        if(self.state == self.LOAD):
            self.start_scene.draw(self.state)
        elif(self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE):
            self.start_scene.draw(self.state)
        elif(self.state == self.SCENE):
            self.game_scene.draw()
        elif(self.state == self.GAME):

            self.update()
            self.draw()

        elif(self.state == self.PAUSE):

            self.start_scene.draw(self.state)

    def isAreaClick(self, x, y):
        if (self.state == self.LOAD or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.SCORE or self.state == self.SCENE or self.state == self.MANUAL or self.state == self.PAUSE):
            self.rect = Rect(177, 274, 306, 112) # the position of the play button on the scene
            self.rect_play = Rect(229, 200, 200, 53)  # the position of the play button on the home scene
            self.rect_about = Rect(229, 263, 200, 53)  # the position of the about button on the home scene
            #self.rect_exit = Rect(229, 456, 200, 53)  # the position of the exit button on the home scene
            self.rect_pause_home = Rect(229, 263, 200, 53)  # the position of the home button on pause scene
            self.rect_score = Rect(229, 328, 200, 53)  # the position of the score button on the home scene
            self.rect_manual = Rect(229, 393, 200, 53)  # the position of the manual button on the home scene
            self.rect_scene = Rect(229, 519, 200, 53)  # the position of the manual button on the home scene
            self.rect_back = Rect(10, 620, 40, 30)  # the position of the back button on the home scene
            self.rect_sound = Rect(10, 600, 30, 30) # the position of the sound button on the home scene
            self.rect_scene_next = Rect(610, 330, 30, 30)  # the position of the next scene button on scene
            self.rect_scene_previous = Rect(50, 330, 30, 30)  # the position of the previous scene button on scene

            if(self.rect.collidepoint(x, y) and (self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN)):
                self.state = self.GAME
            elif(self.rect_play.collidepoint(x,y) and self.state == self.LOAD):
                self.state = self.GAME
            elif (self.rect_play.collidepoint(x, y) and self.state == self.PAUSE):
                self.state = self.GAME
            elif (self.rect_about.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.ABOUT
            elif (self.rect_score.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCORE
            elif (self.rect_scene.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCENE
            elif (self.rect_back.collidepoint(x, y) and self.state == self.SCENE):
                self.state = self.LOAD
            elif (self.rect_scene_next.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_next_image()
            elif (self.rect_scene_previous.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_previous_image()
            elif (self.rect_pause_home.collidepoint(x, y) and self.state == self.PAUSE):

                self.state = self.LOAD
                self.setup(self.level_manager.get_level())
                self.save_level()

            elif (self.rect_manual.collidepoint(x, y) and self.state == self.LOAD):
                webbrowser.open_new('http://gamingdirectional.com/blog/2018/12/25/air-strike//')
            elif (self.rect_back.collidepoint(x, y) and (self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE)):
                self.state = self.LOAD
            elif (self.rect_sound.collidepoint(x, y) and self.state == self.LOAD):

                if(self.start_scene.soundon == True):
                    self.start_scene.soundon = False
                    pygame.mixer_music.pause()
                else:
                    self.start_scene.soundon = True
                    pygame.mixer_music.unpause()

    def save_level(self):
       self.level_manager.save_level()

    def set_pause(self, pause):

        self.pause = pause

        if(self.pause == True):

            self.state = self.PAUSE

    def load_music(self):
        pygame.mixer_music.load('Music/winternight.ogg')

    def play_music(self):
        pygame.mixer_music.play(-1) #play the music infinite time

    def set_player_x(self, _x):
        if (self.state == self.GAME):
            self.player.setX(_x)

    def save_scene(self):
        self.game_scene.take_screen()

    def set_player_y(self, _y):
        if (self.state == self.GAME):
            self.player.setY(_y)

    def set_missile_strike(self, strike):
        if (self.state == self.GAME):
            self.player.setStrike(strike)

    def update(self):
        #self.player.update()
        self.enemy_manager.update()
        #self.isOverlap()
        #self.explosion_manager.explosion_update()

    # check for player, enemy, missiles overlap
    def isOverlap(self):
        self.overlap_manager.isOverlap(self.player, self.enemy_manager, self.explosion_manager, self.score_manager, self)

    def draw(self):
        if(self.state == self.GAME):
            self.background.draw()
            #self.player.draw()
            #self.enemy_manager.update()
            self.enemy_manager.draw()
            #self.explosion_manager.draw()
            #self.score_manager.draw()
            pygame.display.flip()

With that, we have made the sprite animation a lot more efficient than the previous one. We will continue to work on the enemy sprite movement in the next chapter. If you want to support this site do consider to donate a few crypto coins to fund this project, the crypto addresses are on the sidebar of this website.

http://islandstropicalman.tumblr.com/post/182577491488/pygame

Create the animation character on the maze

Today we are going to create the animated enemy for our new pygame project. We are going to edit the enemy manager class and the game manager class then we are going to create an enemy sprite class and an enemy object class which will serve as the original sprite container just like the previous background object class does.

Alright, let us get the thing going. First of all we are going to create the enemy object class which will hold the list which contains the initial enemy object’s position on the maze board for each level.

class EnemyObject(object):

    def __init__(self):

        self.list_1 = [

            [0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        ]

    def get_object_list(self, level):

        if(level == 1):
            return self.list_1

The above class is just like the background object class which you have seen previously.

Next we will create the enemy sprite class which will perform the same job as the background sprite class which is to render the enemy object on the game scene.

from EnemyObject import EnemyObject
from pygame.locals import *
from pygame import math as mt
from GameSprite import GameSprite

class EnemySprite(object):

    def __init__(self, level, scene):

        self.row = 10
        self.column = 10
        self.enemy_image_sprite = 'Asset/right.png'
        self.scene = scene # game scene instance
        self.space = 64 # image width and height

        self.sprite_frame_list = []
        self.count = -1 # frame controller
        self.forward = False # switch to move counter forward or backward

        # the first frame
        self.frame_1_rect = Rect(0, 0, 64, 64)
        self.sprite_frame_1 = GameSprite(self.enemy_image_sprite, self.frame_1_rect)
        self.sprite_frame_1_surface = self.sprite_frame_1.getImage()
        self.sprite_frame_list.append(self.sprite_frame_1_surface)

        # the second frame
        self.frame_2_rect = Rect(64, 0, 64, 64)
        self.sprite_frame_2 = GameSprite(self.enemy_image_sprite, self.frame_2_rect)
        self.sprite_frame_2_surface = self.sprite_frame_2.getImage()
        self.sprite_frame_list.append(self.sprite_frame_2_surface)

        # the third frame
        self.frame_3_rect = Rect(64 * 2, 0, 64, 64)
        self.sprite_frame_3 = GameSprite(self.enemy_image_sprite, self.frame_3_rect)
        self.sprite_frame_3_surface = self.sprite_frame_3.getImage()
        self.sprite_frame_list.append(self.sprite_frame_3_surface)

        # the fourth frame
        self.frame_4_rect = Rect(64 * 3, 0, 64, 64)
        self.sprite_frame_4 = GameSprite(self.enemy_image_sprite, self.frame_4_rect)
        self.sprite_frame_4_surface = self.sprite_frame_4.getImage()
        self.sprite_frame_list.append(self.sprite_frame_4_surface)

        # the fifth frame
        self.frame_5_rect = Rect(64 * 4, 0, 64, 64)
        self.sprite_frame_5 = GameSprite(self.enemy_image_sprite, self.frame_5_rect)
        self.sprite_frame_5_surface = self.sprite_frame_5.getImage()
        self.sprite_frame_list.append(self.sprite_frame_5_surface)

        # the sixth frame
        self.frame_6_rect = Rect(64 * 5, 0, 64, 64)
        self.sprite_frame_6 = GameSprite(self.enemy_image_sprite, self.frame_6_rect)
        self.sprite_frame_6_surface = self.sprite_frame_6.getImage()
        self.sprite_frame_list.append(self.sprite_frame_6_surface)

        # the seventh frame
        self.frame_7_rect = Rect(64 * 6, 0, 64, 64)
        self.sprite_frame_7 = GameSprite(self.enemy_image_sprite, self.frame_7_rect)
        self.sprite_frame_7_surface = self.sprite_frame_7.getImage()
        self.sprite_frame_list.append(self.sprite_frame_7_surface)

        self.level = level # current game level

        self.enemy_object = EnemyObject()

    def draw(self):

        for row in range(self.row):

            for column in range(self.column):

                if (self.count > 6 and self.forward == True):  # use this logic to control the counter and the image
                    self.count -= 1
                    self.forward = False
                elif (self.count < 0 and self.forward == False):
                    self.count += 1
                    self.forward = True
                elif (self.forward == False):
                    self.count -= 1
                elif (self.forward == True):
                    self.count += 1

                self.draw_pos = mt.Vector2(self.space * column, self.space * row) # the position of the image on game scene

                if(self.enemy_list[row][column] == 1):
                    self.scene.blit(self.sprite_frame_list[self.count], self.draw_pos)  # draw enemy frame

    def get_level(self, level):
        self.enemy_list = self.enemy_object.get_object_list(level)

The above class is more complicated than the background sprite class but the idea is the same, which is to render the game’s object on the scene. We will come back to further modify this class in the next chapter but for now this class will just initiate the enemy object on the game scene and then continuously animates the enemy object on each update.

Our next target is to modify the enemy manager class accordingly.

from EnemySprite import EnemySprite

class EnemyManager(object):

    def __init__(self, scene, game_level):

        self.scene = scene
        self.enemy_list = []
        self.level = game_level
        self.enemy = EnemySprite(self.level, self.scene)
        self.create_enemy()

    def create_enemy(self):

        self.enemy.get_level(self.level)

    def update(self):

        pass

    # check the boundary of the enemy with the game scene area
    def check_boundary(self):

        pass

    def draw(self):

        self.enemy.draw()

Then on the game manager class, we will call the enemy manager class to prepare and to draw the enemy object during each game loop.

from Player import Player
from EnemyManager import EnemyManager
from Overlap import Overlap
from ExplosionManager import ExplosionManager
from Score import Score
from StartScene import StartScene
from pygame.locals import *
from LevelManager import LevelManager
import pygame
import webbrowser
from Scene import Scene
from BackGroundSprite import BackGroundSprite

class GameManager(object):

    def __init__(self, scene):

        self.scene = scene

        self.load_music()
        self.play_music()
        self.overlap_manager = Overlap()
        self.level_manager = LevelManager(self)
        self.level_manager.set_level()
        self.setup(self.level_manager.get_level())
        self.start_scene = StartScene(scene, self.level_manager)

        self.pause = False # flag to pause the game

        self.game_scene = Scene(self.scene)

        #game state
        self.LOAD = 0
        self.GAME = 1
        self.OVER = 2
        self.NEXT = 3
        self.WIN = 4
        self.ABOUT = 5
        self.MANUAL = 6
        self.PAUSE = 7
        self.SCORE = 8
        self.SCENE = 9

        self.state = self.LOAD

    def setup(self, game_level):

        self.game_level = game_level
        self.score_manager = Score(self.scene, self.level_manager)
        self.background = BackGroundSprite(self.game_level, self.scene)
        self.player = Player(self.scene)
        self.enemy_manager = EnemyManager(self.scene, self.game_level)
        self.explosion_manager = ExplosionManager(self.scene)

    def loop(self):

        if(self.state == self.LOAD):
            self.start_scene.draw(self.state)
        elif(self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE):
            self.start_scene.draw(self.state)
        elif(self.state == self.SCENE):
            self.game_scene.draw()
        elif(self.state == self.GAME):

            self.update()
            self.draw()

        elif(self.state == self.PAUSE):

            self.start_scene.draw(self.state)

    def isAreaClick(self, x, y):
        if (self.state == self.LOAD or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.SCORE or self.state == self.SCENE or self.state == self.MANUAL or self.state == self.PAUSE):
            self.rect = Rect(177, 274, 306, 112) # the position of the play button on the scene
            self.rect_play = Rect(229, 200, 200, 53)  # the position of the play button on the home scene
            self.rect_about = Rect(229, 263, 200, 53)  # the position of the about button on the home scene
            #self.rect_exit = Rect(229, 456, 200, 53)  # the position of the exit button on the home scene
            self.rect_pause_home = Rect(229, 263, 200, 53)  # the position of the home button on pause scene
            self.rect_score = Rect(229, 328, 200, 53)  # the position of the score button on the home scene
            self.rect_manual = Rect(229, 393, 200, 53)  # the position of the manual button on the home scene
            self.rect_scene = Rect(229, 519, 200, 53)  # the position of the manual button on the home scene
            self.rect_back = Rect(10, 620, 40, 30)  # the position of the back button on the home scene
            self.rect_sound = Rect(10, 600, 30, 30) # the position of the sound button on the home scene
            self.rect_scene_next = Rect(610, 330, 30, 30)  # the position of the next scene button on scene
            self.rect_scene_previous = Rect(50, 330, 30, 30)  # the position of the previous scene button on scene

            if(self.rect.collidepoint(x, y) and (self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN)):
                self.state = self.GAME
            elif(self.rect_play.collidepoint(x,y) and self.state == self.LOAD):
                self.state = self.GAME
            elif (self.rect_play.collidepoint(x, y) and self.state == self.PAUSE):
                self.state = self.GAME
            elif (self.rect_about.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.ABOUT
            elif (self.rect_score.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCORE
            elif (self.rect_scene.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.SCENE
            elif (self.rect_back.collidepoint(x, y) and self.state == self.SCENE):
                self.state = self.LOAD
            elif (self.rect_scene_next.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_next_image()
            elif (self.rect_scene_previous.collidepoint(x, y) and self.state == self.SCENE):
                self.game_scene.set_previous_image()
            elif (self.rect_pause_home.collidepoint(x, y) and self.state == self.PAUSE):

                self.state = self.LOAD
                self.setup(self.level_manager.get_level())
                self.save_level()

            elif (self.rect_manual.collidepoint(x, y) and self.state == self.LOAD):
                webbrowser.open_new('http://gamingdirectional.com/blog/2018/12/25/air-strike//')
            elif (self.rect_back.collidepoint(x, y) and (self.state == self.ABOUT or self.state == self.MANUAL or self.state == self.SCORE)):
                self.state = self.LOAD
            elif (self.rect_sound.collidepoint(x, y) and self.state == self.LOAD):

                if(self.start_scene.soundon == True):
                    self.start_scene.soundon = False
                    pygame.mixer_music.pause()
                else:
                    self.start_scene.soundon = True
                    pygame.mixer_music.unpause()

    def save_level(self):
       self.level_manager.save_level()

    def set_pause(self, pause):

        self.pause = pause

        if(self.pause == True):

            self.state = self.PAUSE

    def load_music(self):
        pygame.mixer_music.load('Music/winternight.ogg')

    def play_music(self):
        pygame.mixer_music.play(-1) #play the music infinite time

    def set_player_x(self, _x):
        if (self.state == self.GAME):
            self.player.setX(_x)

    def save_scene(self):
        self.game_scene.take_screen()

    def set_player_y(self, _y):
        if (self.state == self.GAME):
            self.player.setY(_y)

    def set_missile_strike(self, strike):
        if (self.state == self.GAME):
            self.player.setStrike(strike)

    def update(self):
        #self.player.update()
        #self.enemy_manager.update()
        #self.isOverlap()
        #self.explosion_manager.explosion_update()
        pass

    # check for player, enemy, missiles overlap
    def isOverlap(self):
        self.overlap_manager.isOverlap(self.player, self.enemy_manager, self.explosion_manager, self.score_manager, self)

    def draw(self):
        if(self.state == self.GAME):
            self.background.draw()
            #self.player.draw()
            self.enemy_manager.draw()
            #self.explosion_manager.draw()
            #self.score_manager.draw()
            pygame.display.flip()

That is it, as we slowly develop our new pygame project we will further edit the above game manager class.

http://islandstropicalman.tumblr.com/post/182491960069/pygame-project

If you like this tutorial and you have excessive bitcoins or other cryptocurrencies then kindly do consider to support this site by donating any amount of them through the below donation box. I have created many sites like this one and I do need cryptocurrencies to pay for the web hosting package so those sites include this one will be able to continue producing free source code for those who need it. Every cent you pay will be used to fund this free source code’s website and the other free source code sites that I have created so please help me out if it is possible. A little amount such as a few dollars will do, thank you very much indeed.

  • Bitcoin
  • Ethereum
  • Bitcoin cash
  • Litecoin
  • Stellar
Scan to Donate Bitcoin to 38han7NG6KHtxZsS4ppTwAtSw7UfLSY5Vd

Donate Bitcoin to this address

Scan the QR code or copy the address below into your wallet to send some Bitcoin

Scan to Donate Ethereum to 0x9Dfd0786c5fE998deebf6C86326bD036Ee2518c1

Donate Ethereum to this address

Scan the QR code or copy the address below into your wallet to send some Ethereum

Scan to Donate Bitcoin cash to qqegrlxc93q5ah0s2s6w9zxwf685vr26nu0kxlkvpc

Donate Bitcoin cash to this address

Scan the QR code or copy the address below into your wallet to send some Bitcoin cash

Scan to Donate Litecoin to MJJ2T1XyD4NtSjTA3NpcqTuaTaCKfT3fdA

Donate Litecoin to this address

Scan the QR code or copy the address below into your wallet to send some Litecoin

Scan to Donate Stellar to GAJRUOEMPNSHHR2ZB4KOOQ3MIR2BN54BBXGHTYA6QWMGST7AGI46WIHU

Donate Stellar to this address

Scan the QR code or copy the address below into your wallet to send some Stellar

Change the direction of the enemy ship

Hello and happy new year to all readers of this website, in this new year’s eve I would like to list out the entire plan for this website in the year 2019 before we proceed even further. After a long thought about the future plan for this website in the year 2019 I have decided to continue writing about the previous pygame project which I have developed last year which means instead of stop posting about any further change or the latest features that have been included into this project I will continue to post an update on this project so you can play the game and continue to learn about the programming part of this game at the same time. If you have not yet downloaded version 1 of this game then go ahead and do so first through below link. The latest update of this game on this article will not appear immediately on those major gaming sites, this game will only get updated once a week on those major gaming sites.

Besides continue developing and posting the previous project, I will also start to write about the next pygame project which is a maze game project in this same website, so make sure you subscribed to this website by clicking on the bell button below this post.

Alright, so much for that, now let us continue with the previous pygame project which we will now change the direction of the enemy ship from which previously moves horizontally from left to right to move in both directions instead. In the previous program, a new enemy ship which moves from left to right will be created each time the player has destroyed the old one which makes the path of that enemy ship always look the same. In this new update, we will change the direction of the new enemy ship from right to left if the old one which gets destroyed is moving from left to right and vice-versa. In order to achieve this, we only need to edit the enemy manager class like before.

from Enemy import Enemy
from 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 &gt; 0):

            if(self.object_pool.getSize() &gt; 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 &gt; 0):

            if (self.horizontal_object_pool.getSize() &gt; 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 &gt; 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 &gt; 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 &gt; 0):
                self.create_horizontal_enemy(-130, 200)  # create new enemy

        self.create_enemy_missile()
        self.enemy_update()
        self.check_boundary()

    def create_enemy_missile(self):

        for item in list(self.enemy_list):

            if(self.player.pos.y - item.y  &lt; 200 and abs(self.player.pos.x - item.x) &lt; 160):

                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:
                if ((self.player.pos.y - item.y &lt; 200 and self.player.pos.y - item.y &gt; -2) and abs(self.player.pos.x - item.x) &lt; 200):
                    item.update((self.player.pos.x - item.x) * 0.004, 0.1)
                else:
                    item.update(0, 0.1)

        if (self.level == 3):

            for item in list(self.horizontal_enemy_list):

                if (item.on == False):

                    self.horizontal_enemy_count += 1
                    item.y = 220

                    if(item.direction == True):
                        item.x = 800
                        item.direction = False
                    else:
                        item.x = -130
                        item.direction = True
                    self.horizontal_enemy_list.remove(item)
                    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 &gt; 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 &gt; self.boundary_width):
                    self.horizontal_enemy_list[i].direction = False
                elif(self.horizontal_enemy_list[i].x &lt;= -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)

By changing the above program we will be able to achieve that change of path effect for the horizontally moving enemy ship.

Change the direction of the enemy ship

I wish you all the best of luck in the year 2019 and stay tuned for more game development articles in this website.

The beginning of Game AI

We have basically finished including all the game features in our pygame project and we are now ready to further tune up this pygame project. In this article, we will further tune up the path of the enemy ships. In the previous program, the enemy ship is moving downward in the vertical position and shooting missile at the player if the distance between the player and the enemy is close enough. In this article, we will make the enemy a lot smarter than previously by making it moves toward the direction of the player when it spots the player within a certain range.

We will need to modify the enemy class’s update method by including the x and the y parameter into it that will be used to adjust the path of the enemy ship to make it moves toward the player direction during the game.

from pygame import math as mt
from Objectpool import Objectpool

class Enemy(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.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, x, y):
        self.y += y
        self.x += x
        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 &gt; 300):

            self.missile_timer = 0

            if (self.missile_object_pool.getSize() &gt; 0):
                enemy_missile_manager.create_missile(self.x + 5, self.y + 4, self.missile_object_pool, self.missile_list)
            else:
                enemy_missile_manager.create_missile(self.x + 5, self.y + 4, None, self.missile_list)

        else:

            self.missile_timer += 1

The next class we need to modify is the enemy manager class which we will adjust the range where the enemy will fire a missile at the player as well as creating the range where the enemy will start to move toward the player during the game.

from Enemy import Enemy
from 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 &gt; 0):

            if(self.object_pool.getSize() &gt; 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 &gt; 0):

            if (self.horizontal_object_pool.getSize() &gt; 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 &gt; 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 &gt; 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 &gt; 0):
                self.create_horizontal_enemy(-130, 200)  # create new enemy

        self.create_enemy_missile()
        self.enemy_update()
        self.check_boundary()

    def create_enemy_missile(self):

        for item in list(self.enemy_list):

            if(self.player.pos.y - item.y  &lt; 200 and abs(self.player.pos.x - item.x) &lt; 160):

                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:
                if ((self.player.pos.y - item.y &lt; 200 and self.player.pos.y - item.y &gt; -2) and abs(self.player.pos.x - item.x) &lt; 200):
                    item.update((self.player.pos.x - item.x) * 0.005, 0.1)
                else:
                    item.update(0, 0.1)

        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 &gt; 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 &gt; self.boundary_width):
                    self.horizontal_enemy_list[i].direction = False
                elif(self.horizontal_enemy_list[i].x &lt;= -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)

Now, whenever the enemy spots the player within a certain range it will move toward that player.

The enemy will move toward the player

Lets put the game instruction online instead

In the previous article we have successfully created an about page which contains both game instruction as well as game credit, however it is better to put the game instruction into it’s own page to make our game looks more professional. In this article we are going to create an online game manual which will open up once the player has clicked on the manual button on the main game page.

Lets go ahead and create the game manual button on the start scene class just like we did previously for the about button. We will also create an offline manual page for this game just like how we create the about page but we are not going to use it at the moment, this page is for the future use just in case we want to bring the manual page offline. Here is the modify version of the start scene class with a new manual button.

from BgSprite import BgSprite
from GameSprite import GameSprite
from pygame.locals import *
from pygame import math as mt
import pygame

class StartScene(object):

    def __init__(self, scene):
        self.scene = scene
        self.play_button = 'Asset/play.png'
        self.about_button  = 'Asset/about.png'
        self.score_button = 'Asset/score.png'
        self.home_button = 'Asset/back.png'
        self.button_image = 'Asset/button_play.png'
        self.manual_button = 'Asset/manual.png'
        self.bg_image = 'Asset/start.png'
        self.over_image = 'Asset/ove.png'
        self.next_image = 'Asset/next.png'
        self.win_image = 'Asset/winn.png'
        self.general_image = 'Asset/general.png'
        self.about_page = 'Asset/about_page.png'
        self.manual_page = 'Asset/manual_page.png'
        self.soundon = 'Asset/sound.png'
        self.soundoff = 'Asset/soundoff.png'
        self.bg_rect = Rect(0, 0, 660, 660)
        self.button_rect = Rect(0, 0,  306, 112)
        self.home_button_rect = Rect(0, 0, 200, 53)
        self.back_button_rect = Rect(0, 0, 40, 30)
        self.sound_button_rect = Rect(0, 0, 29, 30)

        self.sprite = BgSprite(self.bg_image, self.bg_rect)
        self.sprite_about = BgSprite(self.about_page, self.bg_rect)
        self.sprite_manual = BgSprite(self.manual_page, self.bg_rect)
        self.sprite_win = BgSprite(self.win_image, self.bg_rect)
        self.sprite_over = BgSprite(self.over_image, self.bg_rect)
        self.sprite_next = BgSprite(self.next_image, self.bg_rect)

        self.soundon_button = GameSprite(self.soundon, self.sound_button_rect)
        self.soundoff_button = GameSprite(self.soundoff, self.sound_button_rect)

        self.soundoff_button_surface = self.soundoff_button.getImage()  # get the button sprite surface
        self.soundon_button_surface = self.soundon_button.getImage()  # get the button sprite surface

        self.sprite_button = GameSprite(self.button_image, self.button_rect)
        self.sprite_manual_button = GameSprite(self.manual_button, self.home_button_rect)
        self.sprite_play_button = GameSprite(self.play_button, self.home_button_rect)
        self.sprite_about_button = GameSprite(self.about_button, self.home_button_rect)
        self.sprite_score_button = GameSprite(self.score_button, self.home_button_rect)
        self.sprite_home_button = GameSprite(self.home_button, self.back_button_rect)
        self.about_surface = self.sprite_about.getImage()  # get the about sprite surface
        self.manual_surface = self.sprite_manual.getImage()  # get the manual sprite surface
        self.win_surface = self.sprite_win.getImage()  # get the win sprite surface
        self.next_surface = self.sprite_next.getImage()  # get the next level sprite surface
        self.over_surface = self.sprite_over.getImage()  # get the game over sprite surface
        self.surface = self.sprite.getImage()  # get the start scene sprite surface
        self.button_surface = self.sprite_button.getImage() # get the button sprite surface
        self.play_button_surface = self.sprite_play_button.getImage()  # get the button sprite surface
        self.about_button_surface = self.sprite_about_button.getImage()  # get the button sprite surface
        self.score_button_surface = self.sprite_score_button.getImage()  # get the button sprite surface
        self.manual_button_surface = self.sprite_manual_button.getImage()  # get the button sprite surface
        self.home_button_surface = self.sprite_home_button.getImage()  # get the button sprite surface
        self.draw_pos = mt.Vector2(0, 0)
        self.draw_button_pos = mt.Vector2(177, 274)
        self.draw_play_button_pos = mt.Vector2(229, 200)
        self.draw_about_button_pos = mt.Vector2(229, 263)
        self.draw_score_button_pos = mt.Vector2(229, 328)
        self.draw_manual_button_pos = mt.Vector2(229, 393)
        self.draw_back_button_pos = mt.Vector2(10, 620)

        self.draw_sound_button_pos = mt.Vector2(10, 620)

        self.soundon = True

    def draw(self, state):

        if(state == 0):
            self.scene.blit(self.surface, self.draw_pos) # draw a start scene sprite
            self.scene.blit(self.play_button_surface, self.draw_play_button_pos)  # draw a button sprite
            self.scene.blit(self.about_button_surface, self.draw_about_button_pos)  # draw a button sprite
            self.scene.blit(self.score_button_surface, self.draw_score_button_pos)  # draw a button sprite
            self.scene.blit(self.manual_button_surface, self.draw_manual_button_pos)  # draw a button sprite
            if(self.soundon == True):
                self.scene.blit(self.soundon_button_surface, self.draw_sound_button_pos)  # draw a button sprite
            else:
                self.scene.blit(self.soundoff_button_surface, self.draw_sound_button_pos)  # draw a button sprite
        elif(state == 2):
            self.scene.blit(self.over_surface, self.draw_pos)  # draw a game over sprite

        elif (state == 3):
            self.scene.blit(self.next_surface, self.draw_pos)  # draw a next level sprite

        elif(state == 4):
            self.scene.blit(self.win_surface, self.draw_pos)  # draw a win sprite

        elif (state == 5):
            self.scene.blit(self.about_surface, self.draw_pos)  # draw a about sprite
            self.scene.blit(self.home_button_surface, self.draw_back_button_pos)  # draw a button sprite

        elif (state == 6):
            self.scene.blit(self.manual_surface, self.draw_pos)  # draw a manual sprite
            self.scene.blit(self.home_button_surface, self.draw_back_button_pos)  # draw a button sprite

        if(state == 2 or state == 3 or state == 4):
            self.scene.blit(self.button_surface, self.draw_button_pos)  # draw a button sprite

        pygame.display.flip()

Next we will modify the game manager class, we will create a new game state for the game manual but we are not going to use it now because we will directly open up a web browser with the help of the python’s webbrowser module. Here is the modify version of the game manager class.

from Player import Player
from Background import Background
from EnemyManager import EnemyManager
from Overlap import Overlap
from ExplosionManager import ExplosionManager
from Score import Score
from StartScene import StartScene
from pygame.locals import *
from LevelManager import LevelManager
import pygame
import webbrowser

class GameManager(object):

    def __init__(self, scene):

        self.scene = scene
        self.start_scene = StartScene(scene)
        self.load_music()
        self.play_music()
        self.overlap_manager = Overlap()
        self.level_manager = LevelManager(self)

        self.setup(self.level_manager.get_level())

        #game state
        self.LOAD = 0
        self.GAME = 1
        self.OVER = 2
        self.NEXT = 3
        self.WIN = 4
        self.ABOUT = 5
        self.MANUAL = 6

        self.state = self.LOAD

    def setup(self, game_level):

        self.game_level = game_level
        self.score_manager = Score(self.scene)
        self.background = Background(self.scene)

        self.player = Player(self.scene)
        self.enemy_manager = EnemyManager(self.scene, self.player, game_level)
        self.explosion_manager = ExplosionManager(self.scene)

    def loop(self):

        if(self.state == self.LOAD or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.MANUAL):

            self.start_scene.draw(self.state)

        elif(self.state == self.GAME):

            self.update()
            self.draw()

    def isAreaClick(self, pos):
        if (self.state == self.LOAD or self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN or self.state == self.ABOUT or self.state == self.MANUAL):
            self.rect = Rect(177, 274, 306, 112) # the position of the play button on the scene
            self.rect_play = Rect(229, 200, 200, 53)  # the position of the play button on the home scene
            self.rect_about = Rect(229, 263, 200, 53)  # the position of the about button on the home scene
            self.rect_manual = Rect(229, 393, 200, 53)  # the position of the manual button on the home scene
            self.rect_back = Rect(10, 620, 40, 30)  # the position of the back button on the home scene
            self.rect_sound = Rect(10, 620, 29, 30) # the position of the sound button on the home scene
            x, y = pos
            if(self.rect.collidepoint(x, y) and (self.state == self.OVER or self.state == self.NEXT or self.state == self.WIN)):
                self.state = self.GAME
            elif(self.rect_play.collidepoint(x,y) and self.state == self.LOAD):
                self.state = self.GAME
            elif (self.rect_about.collidepoint(x, y) and self.state == self.LOAD):
                self.state = self.ABOUT
            elif (self.rect_manual.collidepoint(x, y) and self.state == self.LOAD):
                #self.state = self.MANUAL
                webbrowser.open_new('http://gamingdirectional.com/')
            elif (self.rect_back.collidepoint(x, y) and (self.state == self.ABOUT or self.state == self.MANUAL)):
                self.state = self.LOAD
            elif (self.rect_sound.collidepoint(x, y) and self.state == self.LOAD):

                if(self.start_scene.soundon == True):
                    self.start_scene.soundon = False
                    pygame.mixer_music.pause()
                else:
                    self.start_scene.soundon = True
                    pygame.mixer_music.unpause()


    def load_music(self):
        pygame.mixer_music.load('Music/winternight.ogg')

    def play_music(self):
        pygame.mixer_music.play(-1) #play the music infinite time

    def set_player_x(self, _x):
        if (self.state == self.GAME):
            self.player.setX(_x)

    def set_player_y(self, _y):
        if (self.state == self.GAME):
            self.player.setY(_y)

    def set_missile_strike(self, strike):
        if (self.state == self.GAME):
            self.player.setStrike(strike)

    def update(self):
        self.player.update()
        self.enemy_manager.update()
        self.isOverlap()
        self.explosion_manager.explosion_update()

    # check for player, enemy, missiles overlap
    def isOverlap(self):
        self.overlap_manager.isOverlap(self.player, self.enemy_manager, self.explosion_manager, self.score_manager, self)

    def draw(self):
        self.background.draw()
        self.player.draw()
        self.enemy_manager.draw()
        self.explosion_manager.draw()
        self.score_manager.draw()
        pygame.display.flip()

That is it, when you have clicked on the manual button on the home scene the online manual page will open up!