1"""
2Show how to have enemies shoot bullets aimed at the player.
3
4If Python and Arcade are installed, this example can be run from the command line with:
5python -m arcade.examples.sprite_bullets_enemy_aims
6"""
7
8from __future__ import annotations
9
10import arcade
11import math
12
13SCREEN_WIDTH = 800
14SCREEN_HEIGHT = 600
15SCREEN_TITLE = "Sprites and Bullets Enemy Aims Example"
16BULLET_SPEED = 4
17
18
19class MyGame(arcade.Window):
20 """ Main application class """
21
22 def __init__(self, width, height, title):
23 super().__init__(width, height, title)
24
25 self.background_color = arcade.color.BLACK
26
27 self.frame_count = 0
28
29 self.enemy_list = None
30 self.bullet_list = None
31 self.player_list = None
32 self.player = None
33
34 def setup(self):
35 self.enemy_list = arcade.SpriteList()
36 self.bullet_list = arcade.SpriteList()
37 self.player_list = arcade.SpriteList()
38
39 # Add player ship
40 self.player = arcade.Sprite(":resources:images/space_shooter/playerShip1_orange.png", scale=0.5)
41 self.player_list.append(self.player)
42
43 # Add top-left enemy ship
44 enemy = arcade.Sprite(":resources:images/space_shooter/playerShip1_green.png", scale=0.5)
45 enemy.center_x = 120
46 enemy.center_y = SCREEN_HEIGHT - enemy.height
47 enemy.angle = 180
48 self.enemy_list.append(enemy)
49
50 # Add top-right enemy ship
51 enemy = arcade.Sprite(":resources:images/space_shooter/playerShip1_green.png", scale=0.5)
52 enemy.center_x = SCREEN_WIDTH - 120
53 enemy.center_y = SCREEN_HEIGHT - enemy.height
54 enemy.angle = 180
55 self.enemy_list.append(enemy)
56
57 def on_draw(self):
58 """Render the screen. """
59
60 self.clear()
61
62 self.enemy_list.draw()
63 self.bullet_list.draw()
64 self.player_list.draw()
65
66 def on_update(self, delta_time):
67 """All the logic to move, and the game logic goes here. """
68
69 self.frame_count += 1
70
71 # Loop through each enemy that we have
72 for enemy in self.enemy_list:
73
74 # First, calculate the angle to the player. We could do this
75 # only when the bullet fires, but in this case we will rotate
76 # the enemy to face the player each frame, so we'll do this
77 # each frame.
78
79 # Position the start at the enemy's current location
80 start_x = enemy.center_x
81 start_y = enemy.center_y
82
83 # Get the destination location for the bullet
84 dest_x = self.player.center_x
85 dest_y = self.player.center_y
86
87 # Do math to calculate how to get the bullet to the destination.
88 # Calculation the angle in radians between the start points
89 # and end points. This is the angle the bullet will travel.
90 x_diff = dest_x - start_x
91 y_diff = dest_y - start_y
92 angle = -math.atan2(y_diff, x_diff) + 3.14 / 2
93
94 # Set the enemy to face the player.
95 enemy.angle = math.degrees(angle)
96
97 # Shoot every 60 frames change of shooting each frame
98 if self.frame_count % 60 == 0:
99 bullet = arcade.Sprite(":resources:images/space_shooter/laserBlue01.png")
100 bullet.center_x = start_x
101 bullet.center_y = start_y
102
103 # Angle the bullet sprite
104 bullet.angle = math.degrees(angle) - 90
105
106 # Taking into account the angle, calculate our change_x
107 # and change_y. Velocity is how fast the bullet travels.
108 bullet.change_x = math.sin(angle) * BULLET_SPEED
109 bullet.change_y = math.cos(angle) * BULLET_SPEED
110
111 self.bullet_list.append(bullet)
112
113 # Get rid of the bullet when it flies off-screen
114 for bullet in self.bullet_list:
115 if bullet.top < 0:
116 bullet.remove_from_sprite_lists()
117
118 self.bullet_list.update()
119
120 def on_mouse_motion(self, x, y, delta_x, delta_y):
121 """Called whenever the mouse moves. """
122 self.player.center_x = x
123 self.player.center_y = y
124
125
126def main():
127 """ Main function """
128 window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
129 window.setup()
130 arcade.run()
131
132
133if __name__ == "__main__":
134 main()