Line of Sight

line_of_sight.py
1"""
2Line of Sight
3
4Artwork from https://kenney.nl
5
6If Python and Arcade are installed, this example can be run from the command line with:
7python -m arcade.examples.line_of_sight
8"""
9
10import arcade
11import random
12
13SPRITE_SCALING = 0.5
14
15WINDOW_WIDTH = 1280
16WINDOW_HEIGHT = 720
17WINDOW_TITLE = "Line of Sight"
18
19MOVEMENT_SPEED = 5
20
21VIEWPORT_MARGIN = 250
22HORIZONTAL_BOUNDARY = WINDOW_WIDTH / 2.0 - VIEWPORT_MARGIN
23VERTICAL_BOUNDARY = WINDOW_HEIGHT / 2.0 - VIEWPORT_MARGIN
24# If the player moves further than this boundary away from
25# the camera we use a constraint to move the camera
26CAMERA_BOUNDARY = arcade.LRBT(
27 -HORIZONTAL_BOUNDARY,
28 HORIZONTAL_BOUNDARY,
29 -VERTICAL_BOUNDARY,
30 VERTICAL_BOUNDARY,
31)
32
33
34class GameView(arcade.View):
35 """
36 Main application class.
37 """
38
39 def __init__(self):
40 """
41 Initializer
42 """
43
44 # Call the parent class initializer
45 super().__init__()
46
47 # Variables that will hold sprite lists
48 self.player_list = None
49 self.wall_list = None
50 self.enemy_list = None
51
52 # Set up the player info
53 self.player = None
54
55 # Track the current state of what key is pressed
56 self.left_pressed = False
57 self.right_pressed = False
58 self.up_pressed = False
59 self.down_pressed = False
60
61 self.physics_engine = None
62
63 # Camera for scrolling
64 self.camera = None
65
66 # Set the background color
67 self.background_color = arcade.color.AMAZON
68
69 def setup(self):
70 """ Set up the game and initialize the variables. """
71
72 # Camera
73 self.camera = arcade.Camera2D()
74
75 # Sprite lists
76 self.player_list = arcade.SpriteList()
77 self.wall_list = arcade.SpriteList(use_spatial_hash=True)
78 self.enemy_list = arcade.SpriteList()
79
80 # Set up the player
81 self.player = arcade.Sprite(
82 ":resources:images/animated_characters/female_person/femalePerson_idle.png",
83 scale=SPRITE_SCALING,
84 )
85 self.player.center_x = 50
86 self.player.center_y = 350
87 self.player_list.append(self.player)
88
89 # Set enemies
90 enemy = arcade.Sprite(
91 ":resources:images/animated_characters/zombie/zombie_idle.png",
92 scale=SPRITE_SCALING,
93 )
94 enemy.center_x = 350
95 enemy.center_y = 350
96 self.enemy_list.append(enemy)
97
98 spacing = 200
99 for column in range(10):
100 for row in range(10):
101 sprite = arcade.Sprite(
102 ":resources:images/tiles/grassCenter.png",
103 scale=SPRITE_SCALING,
104 )
105
106 x = (column + 1) * spacing
107 y = (row + 1) * sprite.height
108
109 sprite.center_x = x
110 sprite.center_y = y
111 if random.randrange(100) > 20:
112 self.wall_list.append(sprite)
113
114 self.physics_engine = arcade.PhysicsEngineSimple(
115 self.player,
116 self.wall_list,
117 )
118
119 def on_draw(self):
120 """
121 Render the screen.
122 """
123 # This command has to happen before we start drawing
124 self.clear()
125
126 # Draw all the sprites.
127 self.player_list.draw()
128 self.wall_list.draw()
129 self.enemy_list.draw()
130
131 for enemy in self.enemy_list:
132 if arcade.has_line_of_sight(
133 self.player.position, enemy.position, self.wall_list
134 ):
135 color = arcade.color.RED
136 else:
137 color = arcade.color.WHITE
138 arcade.draw_line(self.player.center_x,
139 self.player.center_y,
140 enemy.center_x,
141 enemy.center_y,
142 color,
143 2)
144
145 def on_update(self, delta_time):
146 """ Movement and game logic """
147
148 # Calculate speed based on the keys pressed
149 self.player.change_x = 0
150 self.player.change_y = 0
151
152 if self.up_pressed and not self.down_pressed:
153 self.player.change_y = MOVEMENT_SPEED
154 elif self.down_pressed and not self.up_pressed:
155 self.player.change_y = -MOVEMENT_SPEED
156 if self.left_pressed and not self.right_pressed:
157 self.player.change_x = -MOVEMENT_SPEED
158 elif self.right_pressed and not self.left_pressed:
159 self.player.change_x = MOVEMENT_SPEED
160
161 self.physics_engine.update()
162
163 # --- Manage Scrolling ---
164 self.camera.position = arcade.camera.grips.constrain_boundary_xy(
165 self.camera.view_data, CAMERA_BOUNDARY, self.player.position
166 )
167 self.camera.use()
168
169 def on_key_press(self, key, modifiers):
170 """Called whenever a key is pressed. """
171
172 if key == arcade.key.UP:
173 self.up_pressed = True
174 elif key == arcade.key.DOWN:
175 self.down_pressed = True
176 elif key == arcade.key.LEFT:
177 self.left_pressed = True
178 elif key == arcade.key.RIGHT:
179 self.right_pressed = True
180
181 def on_key_release(self, key, modifiers):
182 """Called when the user releases a key. """
183
184 if key == arcade.key.UP:
185 self.up_pressed = False
186 elif key == arcade.key.DOWN:
187 self.down_pressed = False
188 elif key == arcade.key.LEFT:
189 self.left_pressed = False
190 elif key == arcade.key.RIGHT:
191 self.right_pressed = False
192
193
194def main():
195 """ Main function """
196 # Create a window class. This is what actually shows up on screen
197 window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
198
199 # Create and setup the GameView
200 game = GameView()
201 game.setup()
202
203 # Show GameView on screen
204 window.show_view(game)
205
206 # Start the arcade game loop
207 arcade.run()
208
209
210if __name__ == "__main__":
211 main()