Have Enemies Randomly Shoot

Having enemies randomly shoot is easier than periodically shooting enemies as shown in Have Enemies Periodically Shoot. This is because we don’t have to track how long it has been since we last fired.

See the highlighted lines for what is specific to this example.

Screenshot of using sprites to shoot things
sprite_bullets_random.py
  1"""
  2Show how to have enemies shoot bullets at random intervals.
  3
  4If Python and Arcade are installed, this example can be run from the command line with:
  5python -m arcade.examples.sprite_bullets_random
  6"""
  7import arcade
  8import random
  9
 10WINDOW_WIDTH = 1280
 11WINDOW_HEIGHT = 720
 12WINDOW_TITLE = "Sprites and Random Bullets Example"
 13
 14
 15class GameView(arcade.View):
 16    """ Main application class """
 17
 18    def __init__(self):
 19        super().__init__()
 20
 21        self.background_color = arcade.color.BLACK
 22
 23        self.frame_count = 0
 24        self.player_list = None
 25        self.enemy_list = None
 26        self.bullet_list = None
 27
 28        self.player = None
 29
 30    def setup(self):
 31        """ Setup the variables for the game. """
 32        self.player_list = arcade.SpriteList()
 33        self.enemy_list = arcade.SpriteList()
 34        self.bullet_list = arcade.SpriteList()
 35
 36        # Add player ship
 37        self.player = arcade.Sprite(
 38            ":resources:images/space_shooter/playerShip1_orange.png",
 39            scale=0.5,
 40        )
 41        self.player_list.append(self.player)
 42
 43        # Add top-left enemy ship
 44        enemy = arcade.Sprite(
 45            ":resources:images/space_shooter/playerShip1_green.png",
 46            scale=0.5,
 47        )
 48        enemy.center_x = 120
 49        enemy.center_y = WINDOW_HEIGHT - enemy.height
 50        enemy.angle = 180
 51        self.enemy_list.append(enemy)
 52
 53        # Add top-right enemy ship
 54        enemy = arcade.Sprite(
 55            ":resources:images/space_shooter/playerShip1_green.png",
 56            scale=0.5,
 57        )
 58        enemy.center_x = WINDOW_WIDTH - 120
 59        enemy.center_y = WINDOW_HEIGHT - enemy.height
 60        enemy.angle = 180
 61        self.enemy_list.append(enemy)
 62
 63    def on_draw(self):
 64        """Render the screen. """
 65
 66        self.clear()
 67
 68        self.enemy_list.draw()
 69        self.bullet_list.draw()
 70        self.player_list.draw()
 71
 72    def on_update(self, delta_time):
 73        """All the logic to move, and the game logic goes here. """
 74
 75        # Loop through each enemy that we have
 76        for enemy in self.enemy_list:
 77
 78            # Have a random 1 in 200 change of shooting each 1/60th of a second
 79            odds = 200
 80
 81            # Adjust odds based on delta-time
 82            adj_odds = int(odds * (1 / 60) / delta_time)
 83
 84            if random.randrange(adj_odds) == 0:
 85                bullet = arcade.Sprite(":resources:images/space_shooter/laserBlue01.png")
 86                bullet.center_x = enemy.center_x
 87                bullet.angle = 90
 88                bullet.top = enemy.bottom
 89                bullet.change_y = -2
 90                self.bullet_list.append(bullet)
 91
 92        # Get rid of the bullet when it flies off-screen
 93        for bullet in self.bullet_list:
 94            if bullet.top < 0:
 95                bullet.remove_from_sprite_lists()
 96
 97        self.bullet_list.update()
 98
 99    def on_mouse_motion(self, x, y, delta_x, delta_y):
100        """ Called whenever the mouse moves. """
101        self.player.center_x = x
102        self.player.center_y = 20
103
104
105def main():
106    """ Main function """
107    # Create a window class. This is what actually shows up on screen
108    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
109
110    # Create and setup the GameView
111    game = GameView()
112    game.setup()
113
114    # Show GameView on screen
115    window.show_view(game)
116
117    # Start the arcade game loop
118    arcade.run()
119
120
121if __name__ == "__main__":
122    main()