Line of Sight

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.camera.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        try:
124            # This command has to happen before we start drawing
125            self.clear()
126
127            # Draw all the sprites.
128            self.player_list.draw()
129            self.wall_list.draw()
130            self.enemy_list.draw()
131
132            for enemy in self.enemy_list:
133                if arcade.has_line_of_sight(
134                    self.player.position, enemy.position, self.wall_list
135                ):
136                    color = arcade.color.RED
137                else:
138                    color = arcade.color.WHITE
139                arcade.draw_line(self.player.center_x,
140                                 self.player.center_y,
141                                 enemy.center_x,
142                                 enemy.center_y,
143                                 color,
144                                 2)
145
146        except Exception as e:
147            print(e)
148
149    def on_update(self, delta_time):
150        """ Movement and game logic """
151
152        # Calculate speed based on the keys pressed
153        self.player.change_x = 0
154        self.player.change_y = 0
155
156        if self.up_pressed and not self.down_pressed:
157            self.player.change_y = MOVEMENT_SPEED
158        elif self.down_pressed and not self.up_pressed:
159            self.player.change_y = -MOVEMENT_SPEED
160        if self.left_pressed and not self.right_pressed:
161            self.player.change_x = -MOVEMENT_SPEED
162        elif self.right_pressed and not self.left_pressed:
163            self.player.change_x = MOVEMENT_SPEED
164
165        self.physics_engine.update()
166
167        # --- Manage Scrolling ---
168        self.camera.position = arcade.camera.grips.constrain_boundary_xy(
169            self.camera.view_data, CAMERA_BOUNDARY, self.player.position
170        )
171        self.camera.use()
172
173    def on_key_press(self, key, modifiers):
174        """Called whenever a key is pressed. """
175
176        if key == arcade.key.UP:
177            self.up_pressed = True
178        elif key == arcade.key.DOWN:
179            self.down_pressed = True
180        elif key == arcade.key.LEFT:
181            self.left_pressed = True
182        elif key == arcade.key.RIGHT:
183            self.right_pressed = True
184
185    def on_key_release(self, key, modifiers):
186        """Called when the user releases a key. """
187
188        if key == arcade.key.UP:
189            self.up_pressed = False
190        elif key == arcade.key.DOWN:
191            self.down_pressed = False
192        elif key == arcade.key.LEFT:
193            self.left_pressed = False
194        elif key == arcade.key.RIGHT:
195            self.right_pressed = False
196
197
198def main():
199    """ Main function """
200    # Create a window class. This is what actually shows up on screen
201    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
202
203    # Create and setup the GameView
204    game = GameView()
205    game.setup()
206
207    # Show GameView on screen
208    window.show_view(game)
209
210    # Start the arcade game loop
211    arcade.run()
212
213
214if __name__ == "__main__":
215    main()