How to Create Enemies in Python Arcade Games

MUO 21.06.2023 14:24:23 Imran Alam

Enemies play a crucial role in creating engaging and challenging games. They provide obstacles and adversaries for players, making the gaming experience more exciting. Python's Arcade library offers a straightforward way to incorporate enemies into your games.

Before starting, make sure you have pip installed on your device. Use this command to install the arcade library:

After that, start by creating a simple game where the player can move left and right using the arrow keys.

The code used in this article is available in this GitHub repository and is free for you to use under the MIT license.

import arcade

# Window dimensions

SCREEN_WIDTH = 800

SCREEN_HEIGHT = 600

# Player attributes

PLAYER_RADIUS = 25

PLAYER_SPEED = 5

class GameWindow(arcade.Window):

    def __init__(self, width, height):

        super().__init__(width, height)

        arcade.set_background_color(arcade.color.WHITE)

        self.player_x = width // 2

    def on_draw(self):

        arcade.start_render()

        arcade.draw_circle_filled(self.player_x, PLAYER_RADIUS, PLAYER_RADIUS, arcade.color.BLUE)

    def on_key_press(self, key, modifiers):

        if key == arcade.key.LEFT:

            self.player_x -= PLAYER_SPEED

        elif key == arcade.key.RIGHT:

            self.player_x += PLAYER_SPEED

    def update(self, delta_time):

        pass

def main():

    window = GameWindow(SCREEN_WIDTH, SCREEN_HEIGHT)

    arcade.run()

if __name__ == "__main__":

    main()

To create an enemy that kills the player upon collision, create another circle on the screen. In the on_draw function, you can draw this enemy circle and check for collisions in the update method. You can also use sprites for enemies.

# Add to GameWindow class

class GameWindow(arcade.Window):

    # ...

    def __init__(self, width, height):

        # ...

        # Enemy attributes

        self.enemy_x = width // 2

        self.enemy_y = height - PLAYER_RADIUS

        self.enemy_radius = 20

    def on_draw(self):

        # ...

        arcade.draw_circle_filled(self.enemy_x, self.enemy_y, self.enemy_radius, arcade.color.RED)

    def update(self, delta_time):

        if self.is_collision(self.player_x, self.player_y, self.enemy_x, self.enemy_y, PLAYER_RADIUS, self.enemy_radius):

            print("Game Over!")

    def is_collision(self, x1, y1, x2, y2, radius1, radius2):

        distance_squared = (x1 - x2) ** 2 + (y1 - y2) ** 2

        radius_sum_squared = (radius1 + radius2) ** 2

        return distance_squared <= radius_sum_squared

In some games, enemies can chase the player, adding a dynamic element to the gameplay. To create a following enemy, you need to update its position based on the player's position. Whenever the player moves, the enemy moves in the same direction. You can achieve this by modifying the update method. Create a new file named enemy-follow-player.py and add the code with the below updates:

# Add to GameWindow class

class GameWindow(arcade.Window):

    # ...

    def update(self, delta_time):

        if self.player_x < self.enemy_x:

            self.enemy_x -= PLAYER_SPEED

        elif self.player_x > self.enemy_x:

            self.enemy_x += PLAYER_SPEED

        if self.is_collision(self.player_x, self.player_y,

                            self.enemy_x, self.enemy_y,

                            PLAYER_RADIUS, ENEMY_RADIUS):

           print("Game Over!")

    def is_collision(self, x1, y1, x2, y2, radius1, radius2):

        distance_squared = (x1 - x2) ** 2 + (y1 - y2) ** 2

        radius_sum_squared = (radius1 + radius2) ** 2

        return distance_squared <= radius_sum_squared

Below is the output:

To create an enemy that shoots bullets, create a Bullet class and a list to keep track of active bullets. The enemy will periodically create a new bullet and update its position. Create a new file named bullets.py and add the code with the below updates:

# Add to GameWindow class

class Bullet:

    def __init__(self, x, y, radius, speed):

        self.x = x

        self.y = y

        self.radius = radius

        self.speed = speed

    def update(self):

        self.y -= self.speed

class GameWindow(arcade.Window):

    # ...

    def __init__(self, width, height):

        # ...

        # Enemy attributes

        self.bullets = []

        self.bullet_radius = 5

        self.bullet_speed = 3

        self.bullet_cooldown = 60 # Number of frames between bullet spawns

        self.bullet_timer = 0

    def on_draw(self):

        # ...

        for bullet in self.bullets:

            arcade.draw_circle_filled(bullet.x, bullet.y,

           self.bullet_radius, arcade.color.BLACK)

    def update(self, delta_time):

        # ...

        self.bullet_timer += 1

        if self.bullet_timer >= self.bullet_cooldown:

            self.bullets.append(Bullet(self.enemy_x, self.enemy_y - self.enemy_radius,

self.bullet_radius, self.bullet_speed))

            self.bullet_timer = 0

        for bullet in self.bullets:

            bullet.update()

            if self.is_collision(self.player_x, self.player_y, self.enemy_x,

self.enemy_y, PLAYER_RADIUS, ENEMY_RADIUS):

            print("Game Over!")

    def is_collision(self, x1, y1, x2, y2, radius1, radius2):

        distance_squared = (x1 - x2) ** 2 + (y1 - y2) ** 2

        radius_sum_squared = (radius1 + radius2) ** 2

        return distance_squared <= radius_sum_squared

Below is the output:

In many games, enemies can possess health points (HP), allowing them to sustain multiple hits before being defeated. Adding health points to enemies can introduce strategic gameplay elements and provide a sense of progression and challenge. Create a new file named heath-point.py and add the code with the below updates:

# Window dimensions

SCREEN_WIDTH = 800

SCREEN_HEIGHT = 600

# Player attributes

PLAYER_RADIUS = 25

PLAYER_SPEED = 5

# Enemy attributes

ENEMY_RADIUS = 20

ENEMY_HEALTH = 100

class GameWindow(arcade.Window):

    def __init__(self, width, height):

        super().__init__(width, height)

        arcade.set_background_color(arcade.color.WHITE)

        self.player_x = width // 2

        self.player_y = height // 2

        self.enemy_x = width // 2

        self.enemy_y = height - PLAYER_RADIUS

        self.enemy_health = ENEMY_HEALTH

        print(self.enemy_health)

    def on_draw(self):

        arcade.start_render()

        arcade.draw_circle_filled(self.player_x,

                                  self.player_y,

                                  PLAYER_RADIUS,

                                  arcade.color.BLUE)

        if self.enemy_health > 0:

            arcade.draw_circle_filled(self.enemy_x,

                                      self.enemy_y,

                                      ENEMY_RADIUS,

                                      arcade.color.RED)

    def update(self, delta_time):

        if self.is_collision(self.player_x, self.player_y,

                             self.enemy_x, self.enemy_y,

                             PLAYER_RADIUS, ENEMY_RADIUS):

            self.enemy_health -= 10

            print(self.enemy_health)

The ENEMY_HEALTH constant has a value of 100 to represent the enemy's initial health points. When the player collides with the enemy, you can deduct some points from the enemy's health. To display the updated health value, you can print a text object self.health_text that shows the current enemy health.

By incorporating health points for enemies, you can introduce a layer of challenge and strategy for players. The displayed health value provides visual feedback and allows players to track the enemy's remaining health.

Additionally, you can expand the code by adding further logic and visuals, such as displaying health bars or implementing defeat conditions when the enemy's health reaches zero.

When designing enemies for your game, it's important to consider several best practices to ensure they contribute to a challenging and enjoyable gameplay experience. Here are some guidelines to follow when creating enemies:

Create enemies with varying attributes such as speed, size, health, and attack power. Different enemy types should pose different levels of difficulty, requiring players to adapt their strategies accordingly. By introducing a mix of enemy attributes, you can keep the gameplay fresh and engaging.

Give each enemy type its own unique behavior patterns. Some enemies may move in a predictable manner, while others might exhibit more complex or erratic movements. Consider incorporating enemy AI algorithms to make their behavior more intelligent and unpredictable, adding an extra layer of challenge for players.

Implement health points for enemies to introduce a sense of progression and durability. This allows enemies to sustain multiple hits before being defeated. By assigning varying amounts of HP to different enemy types, you can create a hierarchy of difficulty and encourage players to strategize and prioritize their targets.

Adding enemies to your games can significantly enhance the gameplay experience. They introduce challenges and motivate players to improve their skills. Enemies can come in various forms, from simple obstacles to complex AI-driven adversaries. By implementing enemies effectively, you can make your games more engaging and enjoyable for players.

mercredi 21 juin 2023 17:24:23 Categories:

ShareButton
ShareButton
ShareButton
  • RSS

Suomi sisu kantaa
NorpaNet Beta 1.1.0.18818 - Firebird 5.0 LI-V6.3.2.1497

TetraSys Oy.

TetraSys Oy.