Have Enemies Aim at Player

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