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) > 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.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 > 26):
                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 > 26):
                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

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.