Detect the player’s boundary

In this article, we will start to create the boundary detection mechanism which can be used to help the boy moving around the canvas. We will go slowly where this topic will take a few chapters to complete. In this chapter, we will focus on below issues.

  1. The boy will not be able to move past the horizontal boundary of either 0 or 576 pixels which is the physical boundary for the boy sprite.
  2. The boy will be able to move upward or downward but not side-way when he is inside the ladder.
  3. When the boy is inside the ladder his horizontal movement will be disabled so the boy can either move up or down only, we will enable the boy’s horizontal movement again when the boy reaches the top of the ladder in the next chapter.

In order to achieve the above outcomes, we will edit two files. The boy object file will now contain the ladder boundary which will be used to detect whether the boy is inside the ladder or not. Finally, we will edit the boy sprite to link up those mechanisms that we are talking about.

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.boundary_1 = [[9 * 64, 8 * 64],
                           [9 * 64, 7 * 64]] # the boundary of the ladder

        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.boundary_1
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.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.boy_boundary_list = self.boy_object.get_object_boundary(level)
        self.initialize()

    # set the x and y direction for the player object

    def setX(self, x):
        if(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(self.up == True):
            self.y += y
            if(y == 0 or self.up == False):
                self.frame = 6
            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:
            for boundary in self.boy_boundary_list:
                boundary_rect = Rect(boundary[0], boundary[1], 64, 64)
                if(boundary_rect.collidepoint(self.x, self.y) == True):
                    self.up = True

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

    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

If you run the program again this is what you will see.

Alright, in the next chapter we will continue to modify the boundary detection mechanism for the boy.

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 the player animation

Hello and welcome back, in this chapter we will create a method which will accept either an x increment or y increment from the game manager object that accepts those increments from the main pygame file when the user presses on the up, down, left or the right arrow key on the keyboard. We will not make the player moves yet in this chapter but just animate that player object, we will make the player moves in the next chapter. There are three files that we need to edit here. First is the player sprite class, we will add in the set x and set y method which will later use to animate the player object.

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()

    # set the x and y direction for the player object

    def setX(self, x):
        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):
        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):

        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

If you pressed on the right/left or the up/down key the player will animate accordingly. But before we can see the result we need to connect up another two files first.

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.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.boy_sprite, 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()
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

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(-0.1)
                elif event.key == K_RIGHT:
                    game_manager.set_player_x(0.1)

                elif event.key == K_UP:
                    game_manager.set_player_y(-0.1)
                elif event.key == K_DOWN:
                    game_manager.set_player_y(0.1)

                if event.key == K_SPACE:
                    game_manager.set_missile_strike(True)

                if event.key == K_p:
                    game_manager.set_pause(True)  # set the pause state to true

                if event.key == K_s:
                    game_manager.save_scene()

        elif event.type == KEYUP:

            if (game_manager.state == 1):
                if event.key == K_LEFT:
                    game_manager.set_player_x(0)
                elif event.key == K_RIGHT:
                    game_manager.set_player_x(0)

                elif event.key == K_UP:
                    game_manager.set_player_y(0)
                elif event.key == K_DOWN:
                    game_manager.set_player_y(0)

                if event.key == K_SPACE:
                    game_manager.set_missile_strike(False)

        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()

Now we have a deal, run the program again and you will see the below player’s animation (when you press the key).

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

Create the game background Part 2

Hello and welcome back to part two of this chapter. In this chapter, we will finish up the background rendering process for our new pygame project. If you have missed out the first part of the tutorial then you can read it here. OK let us continue…

In part one we have created two new classes, in this part, we will find out how to use them. First of all, you will need to create a tile sheet which you can then use in this new project. Then you will need to download the free tiled map editor through this link and start to create the tiled map for the game’s background by following this youtube tutorial.

Here is a snapshot of the tiled map editor which I have used to create the tiled map for the game background.

http://islandstropicalman.tumblr.com/post/182413408550/tiled-editor
game tile sheet

Before you can use the tiled editor to create a tiled map you will need to create five 64 x 64 pixels images as shown above which will be used as the background images for the game. You can create the above images with free software such as Inkscape, make sure there is no space in between each image, the final size of that image will be 320px x 64px in a straight line.

The tiled program above will generate a number and position for each image using the above tile sheet in the form of a matrix. We then will turn that matrix into a list which consists of many lists and use it to render the background images for the game. That list will be kept under the BgObject class as shown in the previous article.

Finally, in order to render those background images, we only need to modify the game manager class accordingly.

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
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.player, 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()

We have stopped updating and rendering the player, enemy and the missile object for a while which we will deal with them later on. Below is the new gaming background.

If you would like to follow me on Twitter or provide your suggestions for this new pygame project kindly do so! See you in the next article!

Create the game background part 1

Hello, and welcome back, starting from today I will definitely use my time effectively which means less Youtubed and Googled around so I can concentrate most of the time on writing article, creating the game and managing my own shoe selling’s business. This year is make money online and offline year for me, wasting time on Youtube or surfing around must be stopped so those time can be used to do more meaningful stuff. Alright, so much for that let us get into the business.

As the title has suggested, in this chapter we will create the game’s background for our new pygame project. As I have mentioned before we are creating a maze game project so you can expect something new as compared to the previous project. Before we start let us look at our strategy to create the background object first.

  1. We will create a container which will hold all those lists that contain the background images for each level.
  2. We will create the background object’s sprite class which will be used to render those background images on the game background.

This chapter consists of two parts, in this first part we will create those two classes above and you will slowly understand what I am doing when we get to the next part.

The BgObject class is the container which will contain all the background images’ lists. At the moment the class only has one list which contains various images.

class BgObject(object):

    def __init__(self):

        self.list_1 = [
            [3, 3, 3, 3, 3, 3, 3, 3, 3, 2],
            [4, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [4, 3, 3, 3, 3, 3, 3, 3, 3, 3],
            [0, 0, 4, 0, 0, 0, 3, 3, 3, 3],
            [3, 3, 4, 3, 3, 3, 3, 3, 3, 3],
            [0, 0, 0, 0, 1, 4, 1, 0, 0, 1],
            [3, 3, 3, 3, 3, 4, 3, 3, 3, 3],
            [3, 3, 3, 3, 3, 1, 1, 0, 0, 4],
            [3, 3, 3, 3, 3, 3, 3, 3, 3, 4],
            [0, 1, 0, 0, 1, 1, 0, 1, 1, 0]
        ]

    def get_object_list(self, level):

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

This class above is a container which holds all the background objects. Now let us create the background sprite class which will responsible for the object’s rendering job.

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

class BackGroundSprite(object):

    def __init__(self, level, scene):

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

        # the road sprite
        self.road_rect = Rect(0, 0, 64, 64)
        self.sprite_road = BgSprite(self.bg_image_sprite, self.road_rect)
        self.road_surface = self.sprite_road.getImage()

        # the grass sprite
        self.grass_rect = Rect(64 * 1, 0, 64, 64)
        self.sprite_grass = BgSprite(self.bg_image_sprite, self.grass_rect)
        self.grass_surface = self.sprite_grass.getImage()

        # the door sprite
        self.door_rect = Rect(64 * 2, 0, 64, 64)
        self.sprite_door = BgSprite(self.bg_image_sprite, self.door_rect)
        self.door_surface = self.sprite_door.getImage()

        # the air sprite
        self.air_rect = Rect(64 * 3, 0, 64, 64)
        self.sprite_air = BgSprite(self.bg_image_sprite, self.air_rect)
        self.air_surface = self.sprite_air.getImage()

        # the ladder sprite
        self.ladder_rect = Rect(64 * 4, 0, 64, 64)
        self.sprite_ladder = BgSprite(self.bg_image_sprite, self.ladder_rect)
        self.ladder_surface = self.sprite_ladder.getImage()

        self.level = level # current game level

        self.bg_object = BgObject()

        self.get_level(self.level)

    def draw(self):

        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.bg_list[row][column] == 0):
                    self.scene.blit(self.road_surface, self.draw_pos)  # draw road
                elif (self.bg_list[row][column] == 1):
                    self.scene.blit(self.grass_surface, self.draw_pos)  # draw grass
                elif (self.bg_list[row][column] == 2):
                    self.scene.blit(self.door_surface, self.draw_pos)  # draw door
                elif (self.bg_list[row][column] == 3):
                    self.scene.blit(self.air_surface, self.draw_pos)  # draw air
                elif (self.bg_list[row][column] == 4):
                    self.scene.blit(self.ladder_surface, self.draw_pos)  # draw ladder

        #pygame.display.flip()

    def get_level(self, level):
        self.bg_list = self.bg_object.get_object_list(level)

The game scene is consists of 10 rows 10 columns. If you are still confused with what the above classes do then you will see what I am up to when we go further down the road. Alright, so much for that, we will continue to develop the background rendering engine on the next part of this chapter, stay tuned!