1"""
2Line of Sight
3
4.. note:: This uses features from the upcoming version 2.4. The API for these
5 functions may still change. To use, you will need to install one of the
6 pre-release packages, or install via GitHub.
7
8Artwork from http://kenney.nl
9
10If Python and Arcade are installed, this example can be run from the command line with:
11python -m arcade.examples.line_of_sight
12"""
13
14import arcade
15import os
16import random
17
18SPRITE_SCALING = 0.5
19
20SCREEN_WIDTH = 800
21SCREEN_HEIGHT = 600
22SCREEN_TITLE = "Line of Sight"
23
24MOVEMENT_SPEED = 5
25
26VIEWPORT_MARGIN = 300
27
28
29class MyGame(arcade.Window):
30 """
31 Main application class.
32 """
33
34 def __init__(self, width, height, title):
35 """
36 Initializer
37 """
38
39 # Call the parent class initializer
40 super().__init__(width, height, title)
41
42 # Set the working directory (where we expect to find files) to the same
43 # directory this .py file is in. You can leave this out of your own
44 # code, but it is needed to easily run the examples using "python -m"
45 # as mentioned at the top of this program.
46 file_path = os.path.dirname(os.path.abspath(__file__))
47 os.chdir(file_path)
48
49 # Variables that will hold sprite lists
50 self.player_list = None
51 self.wall_list = None
52 self.enemy_list = None
53
54 # Set up the player info
55 self.player = None
56
57 # Track the current state of what key is pressed
58 self.left_pressed = False
59 self.right_pressed = False
60 self.up_pressed = False
61 self.down_pressed = False
62
63 self.physics_engine = None
64
65 # Used in scrolling
66 self.view_bottom = 0
67 self.view_left = 0
68
69 # Set the background color
70 arcade.set_background_color(arcade.color.AMAZON)
71
72 def setup(self):
73 """ Set up the game and initialize the variables. """
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(":resources:images/animated_characters/female_person/femalePerson_idle.png", SPRITE_SCALING)
82 self.player.center_x = 50
83 self.player.center_y = 350
84 self.player_list.append(self.player)
85
86 # Set enemies
87 enemy = arcade.Sprite(":resources:images/animated_characters/zombie/zombie_idle.png", SPRITE_SCALING)
88 enemy.center_x = 350
89 enemy.center_y = 350
90 self.enemy_list.append(enemy)
91
92 spacing = 200
93 for column in range(10):
94 for row in range(10):
95 sprite = arcade.Sprite(":resources:images/tiles/grassCenter.png", 0.5)
96
97 x = (column + 1) * spacing
98 y = (row + 1) * sprite.height
99
100 sprite.center_x = x
101 sprite.center_y = y
102 if random.randrange(100) > 20:
103 self.wall_list.append(sprite)
104
105 self.physics_engine = arcade.PhysicsEngineSimple(self.player,
106 self.wall_list)
107
108 def on_draw(self):
109 """
110 Render the screen.
111 """
112 try:
113 # This command has to happen before we start drawing
114 arcade.start_render()
115
116 # Draw all the sprites.
117 self.player_list.draw()
118 self.wall_list.draw()
119 self.enemy_list.draw()
120
121 for enemy in self.enemy_list:
122 if arcade.has_line_of_sight(self.player.position,
123 enemy.position,
124 self.wall_list):
125 color = arcade.color.RED
126 else:
127 color = arcade.color.WHITE
128 arcade.draw_line(self.player.center_x,
129 self.player.center_y,
130 enemy.center_x,
131 enemy.center_y,
132 color,
133 2)
134
135 except Exception as e:
136 print(e)
137
138 def on_update(self, delta_time):
139 """ Movement and game logic """
140
141 # Calculate speed based on the keys pressed
142 self.player.change_x = 0
143 self.player.change_y = 0
144
145 if self.up_pressed and not self.down_pressed:
146 self.player.change_y = MOVEMENT_SPEED
147 elif self.down_pressed and not self.up_pressed:
148 self.player.change_y = -MOVEMENT_SPEED
149 if self.left_pressed and not self.right_pressed:
150 self.player.change_x = -MOVEMENT_SPEED
151 elif self.right_pressed and not self.left_pressed:
152 self.player.change_x = MOVEMENT_SPEED
153
154 self.physics_engine.update()
155
156 # --- Manage Scrolling ---
157
158 # Keep track of if we changed the boundary. We don't want to call the
159 # set_viewport command if we didn't change the view port.
160 changed = False
161
162 # Scroll left
163 left_boundary = self.view_left + VIEWPORT_MARGIN
164 if self.player.left < left_boundary:
165 self.view_left -= left_boundary - self.player.left
166 changed = True
167
168 # Scroll right
169 right_boundary = self.view_left + SCREEN_WIDTH - VIEWPORT_MARGIN
170 if self.player.right > right_boundary:
171 self.view_left += self.player.right - right_boundary
172 changed = True
173
174 # Scroll up
175 top_boundary = self.view_bottom + SCREEN_HEIGHT - VIEWPORT_MARGIN
176 if self.player.top > top_boundary:
177 self.view_bottom += self.player.top - top_boundary
178 changed = True
179
180 # Scroll down
181 bottom_boundary = self.view_bottom + VIEWPORT_MARGIN
182 if self.player.bottom < bottom_boundary:
183 self.view_bottom -= bottom_boundary - self.player.bottom
184 changed = True
185
186 # Make sure our boundaries are integer values. While the view port does
187 # support floating point numbers, for this application we want every pixel
188 # in the view port to map directly onto a pixel on the screen. We don't want
189 # any rounding errors.
190 self.view_left = int(self.view_left)
191 self.view_bottom = int(self.view_bottom)
192
193 # If we changed the boundary values, update the view port to match
194 if changed:
195 arcade.set_viewport(self.view_left,
196 SCREEN_WIDTH + self.view_left,
197 self.view_bottom,
198 SCREEN_HEIGHT + self.view_bottom)
199
200 def on_key_press(self, key, modifiers):
201 """Called whenever a key is pressed. """
202
203 if key == arcade.key.UP:
204 self.up_pressed = True
205 elif key == arcade.key.DOWN:
206 self.down_pressed = True
207 elif key == arcade.key.LEFT:
208 self.left_pressed = True
209 elif key == arcade.key.RIGHT:
210 self.right_pressed = True
211
212 def on_key_release(self, key, modifiers):
213 """Called when the user releases a key. """
214
215 if key == arcade.key.UP:
216 self.up_pressed = False
217 elif key == arcade.key.DOWN:
218 self.down_pressed = False
219 elif key == arcade.key.LEFT:
220 self.left_pressed = False
221 elif key == arcade.key.RIGHT:
222 self.right_pressed = False
223
224
225def main():
226 """ Main method """
227 window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
228 window.setup()
229 arcade.run()
230
231
232if __name__ == "__main__":
233 main()