riley
riley

Reputation: 53

How to make enemies follow me using arcade module?

I'm working on this game for an assesment in school, but I keep getting the error below. I've done everything I can to fix it, but I'm not very experienced in python so it's hard to figure out what's wrong.

File "//<redacted>/Python/Assessment/Assesment 16 june.py", line 49,
  in follow_sprite
    if self.center_y < player_sprite.center_y:
AttributeError: 'SpriteList' object has no attribute 'center_y'

Code:

import arcade
import random
import math

SPRITE_SCALING = 0.5
SPRITE_SCALING_LASER = 0.8

SCREEN_WIDTH = 1280
SCREEN_HEIGHT = 720
SCREEN_TITLE = "zombier shooter"
ENEMY_COUNT = 50

BULLET_SPEED = 30
MOVEMENT_SPEED = 5
SPRITE_SPEED = 2


class Player(arcade.Sprite):

    def update(self):
        """ moves the player """
        # move player.
        self.center_x += self.change_x
        self.center_y += self.change_y

        # check for out of bounds
        if self.left < 0:
            self.left = 0
        elif self.right > SCREEN_WIDTH - 1:
            self.right = SCREEN_WIDTH - 1

        if self.bottom < 0:
            self.bottom = 0
        elif self.top > SCREEN_HEIGHT - 1:
            self.top = SCREEN_HEIGHT - 1

class Enemy(arcade.Sprite):
    """
    This class represents the enemies on our screen.
    """

    def follow_sprite(self, player_sprite):
        """
        This function will move the current sprite towards whatever
        other sprite is specified as a parameter.
        """

        if self.center_y < player_sprite.center_y:
            self.center_y += min(SPRITE_SPEED, player_sprite.center_y - self.center_y)
        elif self.center_y > player_sprite.center_y:
            self.center_y -= min(SPRITE_SPEED, self.center_y - player_sprite.center_y)

        if self.center_x < player_sprite.center_x:
            self.center_x += min(SPRITE_SPEED, player_sprite.center_x - self.center_x)
        elif self.center_x > player_sprite.center_x:
            self.center_x -= min(SPRITE_SPEED, self.center_x - player_sprite.center_x)


class MyGame(arcade.Window):
    """
    main game class
    """

    def __init__(self, width, height, title):
        """
        initialises stuff
        """

        #call the parent class initializer
        super().__init__(width, height, title)

        #variables that will hold sprite lists
        self.player_list = None

        #set up the player info
        self.player_sprite = None


        #track the current state of what key is pressed

        self.left_pressed = False

        self.right_pressed = False

        self.up_pressed = False

        self.down_pressed = False


        #set the background color
        arcade.set_background_color(arcade.color.AMAZON)

    def setup(self):
        """ Set up the game and initialize the variables. """

        #sprite lists
        self.player_list = arcade.SpriteList()
        self.enemy_list = arcade.SpriteList()
        self.bullet_list = arcade.SpriteList()

        #setup score
        self.score = 0
        self.score_text = None

        #add sounds for shooting and hitting enemy
        self.gun_sound = arcade.sound.load_sound(":resources:sounds/laser1.wav")
        self.hit_sound = arcade.sound.load_sound(":resources:sounds/phaseJump1.wav")

        #set up the player
        self.player_sprite = Player(":resources:images/animated_characters/female_person/femalePerson_idle.png", SPRITE_SCALING)
        self.player_sprite.center_x = 50
        self.player_sprite.center_y = 50
        self.player_list.append(self.player_sprite)

        self.score = 0

        for i in range(ENEMY_COUNT):

            #enemy texture
            enemy = arcade.Sprite(":resources:images/animated_characters/zombie/zombie_idle.png", SPRITE_SCALING)

            enemy.center_x = random.randrange(SCREEN_WIDTH)
            enemy.center_y = random.randrange(SCREEN_HEIGHT)

            self.enemy_list.append(enemy)

    def on_draw(self):
        """ render the screen. """

        #clear the screen
        self.clear()

        #draw all the sprites.
        self.player_list.draw()
        self.enemy_list.draw()
        self.bullet_list.draw()

        #put score text on the sscsre
        output = f"Score: {self.score}"
        arcade.draw_text(output, 10, 20, arcade.color.WHITE, 14)



    def on_mouse_press(self, x, y, button, modifiers):
        """ Called whenever the mouse button is clicked. """

        # Create a bullet
        bullet = arcade.Sprite(":resources:images/space_shooter/laserBlue01.png", SPRITE_SCALING_LASER)

        # Position the bullet at the player's current location
        start_x = self.player_sprite.center_x
        start_y = self.player_sprite.center_y
        bullet.center_x = start_x
        bullet.center_y = start_y

        # Get from the mouse the destination location for the bullet
        # IMPORTANT! If you have a scrolling screen, you will also need
        # to add in self.view_bottom and self.view_left.
        dest_x = x
        dest_y = y

        # Do math to calculate how to get the bullet to the destination.
        # Calculation the angle in radians between the start points
        # and end points. This is the angle the bullet will travel.
        x_diff = dest_x - start_x
        y_diff = dest_y - start_y
        angle = math.atan2(y_diff, x_diff)

        # Angle the bullet sprite so it doesn't look like it is flying
        # sideways.
        bullet.angle = math.degrees(angle)
        print(f"Bullet angle: {bullet.angle:.2f}")

        # Taking into account the angle, calculate our change_x
        # and change_y. Velocity is how fast the bullet travels.
        bullet.change_x = math.cos(angle) * BULLET_SPEED
        bullet.change_y = math.sin(angle) * BULLET_SPEED

        # Add the bullet to the appropriate lists
        self.bullet_list.append(bullet)


    def update_player_speed(self):



        #calculate speed based on the keys pressed

        self.player_sprite.change_x = 0

        self.player_sprite.change_y = 0



        if self.up_pressed and not self.down_pressed:

            self.player_sprite.change_y = MOVEMENT_SPEED

        elif self.down_pressed and not self.up_pressed:

            self.player_sprite.change_y = -MOVEMENT_SPEED

        if self.left_pressed and not self.right_pressed:

            self.player_sprite.change_x = -MOVEMENT_SPEED

        elif self.right_pressed and not self.left_pressed:

            self.player_sprite.change_x = MOVEMENT_SPEED


    def on_update(self, delta_time):
        """ Movement and game logic """

        #call update to move the sprite
        self.player_list.update()

         # Call update on all sprites
        self.bullet_list.update()

        # Loop through each bullet
        for bullet in self.bullet_list:

            # Check this bullet to see if it hit a enemy
            hit_list = arcade.check_for_collision_with_list(bullet, self.enemy_list)

            # If it did, get rid of the bullet
            if len(hit_list) > 0:
                bullet.remove_from_sprite_lists()

            # For every enemy we hit, add to the score and remove the enemy
            for enemy in hit_list:
                enemy.remove_from_sprite_lists()
                self.score += 1

            # If the bullet flies off-screen, remove it.
            if bullet.bottom > self.width or bullet.top < 0 or bullet.right < 0 or bullet.left > self.width:
                bullet.remove_from_sprite_lists()

        for enemy in self.enemy_list:
            Enemy.follow_sprite(self.enemy_list, self.player_sprite)

        # Generate a list of all sprites that collided with the player.
        hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.enemy_list)

        # Loop through each colliding sprite, remove it, and add to the score.
        for enemy in hit_list:
            enemy.remove_from_sprite_lists()
            self.score -= 1

    def on_key_press(self, key, modifiers):

        """called when user presses a key. """



        if key == arcade.key.UP:

            self.up_pressed = True

            self.update_player_speed()

        elif key == arcade.key.DOWN:

            self.down_pressed = True

            self.update_player_speed()

        elif key == arcade.key.LEFT:

            self.left_pressed = True

            self.update_player_speed()

        elif key == arcade.key.RIGHT:

            self.right_pressed = True

            self.update_player_speed()



    def on_key_release(self, key, modifiers):

        """called when user releases a key. """



        if key == arcade.key.UP:

            self.up_pressed = False

            self.update_player_speed()

        elif key == arcade.key.DOWN:

            self.down_pressed = False

            self.update_player_speed()

        elif key == arcade.key.LEFT:

            self.left_pressed = False

            self.update_player_speed()

        elif key == arcade.key.RIGHT:

            self.right_pressed = False

            self.update_player_speed()



def main():
    """ Main function """
    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    window.setup()
    arcade.run()


if __name__ == "__main__":
    main()

Upvotes: 2

Views: 146

Answers (1)

Alderven
Alderven

Reputation: 8270

Replace

Enemy.follow_sprite(self.enemy_list, self.player_sprite)

with

Enemy.follow_sprite(enemy, self.player_sprite)

and you'll see following:

Enemies follow me

Upvotes: 2

Related Questions