视线#

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
15SCREEN_WIDTH = 800
16SCREEN_HEIGHT = 600
17SCREEN_TITLE = "Line of Sight"
18
19MOVEMENT_SPEED = 5
20
21VIEWPORT_MARGIN = 300
22
23
24class MyGame(arcade.Window):
25 """
26 Main application class.
27 """
28
29 def __init__(self, width, height, title):
30 """
31 Initializer
32 """
33
34 # Call the parent class initializer
35 super().__init__(width, height, title)
36
37 # Variables that will hold sprite lists
38 self.player_list = None
39 self.wall_list = None
40 self.enemy_list = None
41
42 # Set up the player info
43 self.player = None
44
45 # Track the current state of what key is pressed
46 self.left_pressed = False
47 self.right_pressed = False
48 self.up_pressed = False
49 self.down_pressed = False
50
51 self.physics_engine = None
52
53 # Camera for scrolling
54 self.cam = None
55
56 # Set the background color
57 self.background_color = arcade.color.AMAZON
58
59 def setup(self):
60 """ Set up the game and initialize the variables. """
61
62 # Camera
63 self.cam = arcade.camera.Camera2D()
64
65 # Sprite lists
66 self.player_list = arcade.SpriteList()
67 self.wall_list = arcade.SpriteList(use_spatial_hash=True)
68 self.enemy_list = arcade.SpriteList()
69
70 # Set up the player
71 self.player = arcade.Sprite(":resources:images/animated_characters/female_person/femalePerson_idle.png",
72 scale=SPRITE_SCALING)
73 self.player.center_x = 50
74 self.player.center_y = 350
75 self.player_list.append(self.player)
76
77 # Set enemies
78 enemy = arcade.Sprite(":resources:images/animated_characters/zombie/zombie_idle.png", scale=SPRITE_SCALING)
79 enemy.center_x = 350
80 enemy.center_y = 350
81 self.enemy_list.append(enemy)
82
83 spacing = 200
84 for column in range(10):
85 for row in range(10):
86 sprite = arcade.Sprite(":resources:images/tiles/grassCenter.png", scale=0.5)
87
88 x = (column + 1) * spacing
89 y = (row + 1) * sprite.height
90
91 sprite.center_x = x
92 sprite.center_y = y
93 if random.randrange(100) > 20:
94 self.wall_list.append(sprite)
95
96 self.physics_engine = arcade.PhysicsEngineSimple(self.player,
97 self.wall_list)
98
99 def on_draw(self):
100 """
101 Render the screen.
102 """
103 try:
104 # This command has to happen before we start drawing
105 self.clear()
106
107 # Draw all the sprites.
108 self.player_list.draw()
109 self.wall_list.draw()
110 self.enemy_list.draw()
111
112 for enemy in self.enemy_list:
113 if arcade.has_line_of_sight(self.player.position,
114 enemy.position,
115 self.wall_list):
116 color = arcade.color.RED
117 else:
118 color = arcade.color.WHITE
119 arcade.draw_line(self.player.center_x,
120 self.player.center_y,
121 enemy.center_x,
122 enemy.center_y,
123 color,
124 2)
125
126 except Exception as e:
127 print(e)
128
129 def on_update(self, delta_time):
130 """ Movement and game logic """
131
132 # Calculate speed based on the keys pressed
133 self.player.change_x = 0
134 self.player.change_y = 0
135
136 if self.up_pressed and not self.down_pressed:
137 self.player.change_y = MOVEMENT_SPEED
138 elif self.down_pressed and not self.up_pressed:
139 self.player.change_y = -MOVEMENT_SPEED
140 if self.left_pressed and not self.right_pressed:
141 self.player.change_x = -MOVEMENT_SPEED
142 elif self.right_pressed and not self.left_pressed:
143 self.player.change_x = MOVEMENT_SPEED
144
145 self.physics_engine.update()
146
147 # --- Manage Scrolling ---
148
149 # Keep track of if we changed the boundary. We don't want to
150 # update the camera if we don't need to.
151 changed = False
152
153 # Scroll left
154 left_boundary = self.cam.left + VIEWPORT_MARGIN
155 if self.player.left < left_boundary:
156 self.cam.left -= left_boundary - self.player.left
157 changed = True
158
159 # Scroll right
160 right_boundary = self.cam.right - VIEWPORT_MARGIN
161 if self.player.right > right_boundary:
162 self.cam.right += self.player.right - right_boundary
163 changed = True
164
165 # Scroll up
166 top_boundary = self.cam.top - VIEWPORT_MARGIN
167 if self.player.top > top_boundary:
168 self.cam.top += self.player.top - top_boundary
169 changed = True
170
171 # Scroll down
172 bottom_boundary = self.cam.bottom + VIEWPORT_MARGIN
173 if self.player.bottom < bottom_boundary:
174 self.cam.bottom -= bottom_boundary - self.player.bottom
175 changed = True
176
177 # If we changed the boundary values, update the view port to match
178 if changed:
179 # Make sure our boundaries are integer values. While the view port does
180 # support floating point numbers, for this application we want every pixel
181 # in the view port to map directly onto a pixel on the screen. We don't want
182 # any rounding errors.
183 self.cam.left = int(self.cam.left)
184 self.cam.bottom = int(self.cam.bottom)
185
186 self.cam.use()
187
188 def on_key_press(self, key, modifiers):
189 """Called whenever a key is pressed. """
190
191 if key == arcade.key.UP:
192 self.up_pressed = True
193 elif key == arcade.key.DOWN:
194 self.down_pressed = True
195 elif key == arcade.key.LEFT:
196 self.left_pressed = True
197 elif key == arcade.key.RIGHT:
198 self.right_pressed = True
199
200 def on_key_release(self, key, modifiers):
201 """Called when the user releases a key. """
202
203 if key == arcade.key.UP:
204 self.up_pressed = False
205 elif key == arcade.key.DOWN:
206 self.down_pressed = False
207 elif key == arcade.key.LEFT:
208 self.left_pressed = False
209 elif key == arcade.key.RIGHT:
210 self.right_pressed = False
211
212
213def main():
214 """ Main function """
215 window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
216 window.setup()
217 arcade.run()
218
219
220if __name__ == "__main__":
221 main()