class MyGame(arcade.Window): def __init__(self, width, height, title): """ Set up the application. """ super().__init__(width, height, title) self.time = 0 self.frame = 0 self.background = arcade.load_texture(":resources:images/backgrounds/abstract_1.jpg") self.light_layer = LightLayer(SCREEN_WIDTH, SCREEN_HEIGHT) self.light_layer.set_background_color(arcade.color.WHITE) # Add some random lights for _ in range(500): self.light_layer.add( Light( random.randrange(0, SCREEN_WIDTH), random.randrange(0, SCREEN_HEIGHT), radius=50, mode='soft', color=(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) ), ) def on_draw(self): arcade.start_render() # Everything that should be affected by lights in here with self.light_layer: # The light layer is just cleared using the background color here (white) pass # Draw the contents with lighting self.light_layer.draw() # image = arcade.get_image() # image.save(f'screenshots/frame{str(self.frame).zfill(3)}.png', 'png') def on_update(self, dt): # dt = 0.1 self.frame += 1 try: self.time += dt for i, light in enumerate(self.light_layer): light.radius = 20 + math.sin(self.time + i) * 40 except Exception as e: print(e) def on_resize(self, width, height): arcade.set_viewport(0, width, 0, height) self.light_layer.resize(width, height)
class Game(arcade.Window): def __init__(self): super(Game, self).__init__(SW, SH, "Adventure Dungeon") map = arcade.tilemap.read_tmx("resources/dungeon.tmx") # process each layer from tilemap and create a spritelist from it self.ground_list = arcade.tilemap.process_layer(map, "floor", scaling=SCALE) self.wall_list = arcade.tilemap.process_layer(map, "walls", scaling=SCALE) self.background = arcade.tilemap.process_layer(map, "bg", scaling=SCALE) self.doors = arcade.tilemap.process_layer(map, "doors", scaling=SCALE) self.light_list = arcade.tilemap.process_layer(map, "lit_lights", scaling=SCALE) self.perma_torches = arcade.tilemap.process_layer(map, "perma_lights", scaling=SCALE) self.unlit_lights = arcade.tilemap.process_layer(map, "unlit_lights", scaling=SCALE) self.chests = arcade.tilemap.process_layer(map, "chests", scaling=SCALE) self.decor = arcade.tilemap.process_layer(map, "decor", scaling=SCALE) # viewport scroll manager self.scroll_manager = screen_scroll.ScrollManager(self) # create the player self.player = player_sprite.Player(2816*SCALE, 192*SCALE, SCALE, player_sprite.Inventory(10)) # initialize control values self.controls = {'w': MOVEMENT_SPEED, 'a': -MOVEMENT_SPEED, 's': -MOVEMENT_SPEED, 'd': MOVEMENT_SPEED} self.keys_pressed = [] # mouse position self.mouse_pos = 0 # scroll margin (how close player needs to be to the edge of view for it to scroll) margin_lr = SW/2 - self.player.width/2 margin_tb = SH/2 - self.player.height/2 # set the margins self.scroll_manager.set_view_change_margins(right=margin_lr, left=margin_lr, top=margin_tb, bottom=margin_tb) # set the initial view self.scroll_manager.set_view("right", 2208) self.scroll_manager.set_view("left", 2208 - SW) self.scroll_manager.set_view("bottom", self.player.center_y - (SH/2)) self.scroll_manager.set_view("top", self.player.center_y + (SH/2)) self.hit_wall = False # create physics engine self.physics_engine = arcade.PhysicsEngineSimple(self.player, self.wall_list) self.light_index = 0 # self.textures = arcade.load_spritesheet("resources/dungeon_sprites.png", 16, 16, 16, 72) # print(len(self.textures)) # for lighting self.light_layer = None self.player_light = None self.torches = {} self.text = Dialogue("Welcome to Adventure Game!", delay=3) self.candle = None self.candle_light = None self.start_time = time.time() candle = items.Candle(self.player.right, self.player.center_y, .5, False) self.player.set_candle(candle) # generate loot self.room_loot = backend.gen_loot() self.show_text = False # inv show self.show_inv = False self.setup() def setup(self): # create the light layer (width and height of screen) self.light_layer = LightLayer(SW, SH) # set background color self.light_layer.set_background_color(arcade.color.BLACK) # create the player light radius = 100 * SCALE mode = 'soft' color = arcade.csscolor.WHITE self.player_light = Light(0, 0, radius, color, mode) # add the light layer self.light_layer.add(self.player_light) # create a light for each torch for torch in self.light_list: light = TorchLight(torch.center_x, torch.center_y, TORCH_RADIUS) self.light_layer.add(light) self.torches[torch] = light # lighting for torches that cant be unlit for torch in self.perma_torches: light = TorchLight(torch.center_x, torch.center_y, TORCH_RADIUS) self.light_layer.add(light) self.torches[torch] = light # add loot to chests loot = [] for room in self.room_loot: loot += room for chest, loot in zip(self.chests, loot): chest.loot = loot def on_draw(self): arcade.start_render() # draw background (but dont illuminate it) self.background.draw() # draw all the sprites in light layer (lighting will illuminate them) with self.light_layer: self.ground_list.draw() self.doors.draw() self.wall_list.draw() self.chests.draw() self.decor.draw() self.player.draw() self.light_list.draw() self.unlit_lights.draw() self.perma_torches.draw() # draw the actual light layer self.light_layer.draw(ambient_color=AMBIENT_COLOR) if self.candle: fuel_len = self.candle.fuel_level / 2 if self.candle_light.radius > 1: # draw the candle fuel bar above player arcade.draw_lrtb_rectangle_filled(self.player.left, self.player.left + fuel_len + 1, self.player.top + 10, self.player.top + 5, (255, 213, 105)) # draw tutorial text for the first 5 seconds after startup if time.time() - self.start_time < 5: x = self.scroll_manager.get_view('right') y = self.scroll_manager.get_view('bottom') arcade.draw_text("press 'space' to toggle your candle", x - (SW / 2), y + 225, arcade.color.CREAM, 20, anchor_x='center') arcade.draw_text("press 'q' to toggle torches on the wall (some torches can't be toggled)", x - (SW / 2), y + 250, arcade.color.CREAM, 20, anchor_x='center') # show dialogue text if self.show_text: x = self.scroll_manager.get_view('right') y = self.scroll_manager.get_view('bottom') arcade.draw_text(self.text.output(), x - (SW/2), y + 200, arcade.color.CREAM, 20, anchor_x='center', align='center') if self.show_inv: inv_text = self.player.inv.display() leng = self.player.inv.get_len() * 20 top = self.player.center_y + leng/2 bottom = self.player.center_y - leng/2 # ban = arcade.Sprite("resources/sprites/Dungeon_Tileset/sprite_074.png", self.player.right + 10, self.player.center_y, image_height=leng, image_width=150) # ban.draw() arcade.draw_lrtb_rectangle_filled(self.player.right + 10, self.player.center_x + 200, top, bottom, (118, 74, 45)) arcade.draw_text(inv_text, self.player.right + 15, self.player.center_y, (255, 253, 208, 200), 11, anchor_x='left', anchor_y='center', align='left', font_name='Chalkboard') def on_update(self, delta_time: float): # update physics engine self.physics_engine.update() self.decor.update_animation() if self.player.holding_candle: self.candle.update() # calculate ratio of remaining fuel fuel_ratio = self.candle.fuel_level / 100 # set light radius progressively smaller as fuel runs out if fuel_ratio < .5: self.candle_light.radius = CANDLE_RADI[int(self.light_index)] - ((400 - (400 * fuel_ratio))/5) else: self.candle_light.radius = CANDLE_RADI[int(self.light_index)] # change candle position based on player direction if self.player.direction == 1: self.player.candle.position = self.player.right, self.player.center_y else: self.player.candle.position = self.player.left, self.player.center_y # set the position of light object equal to candles position self.candle_light.position = self.candle.position # if the candle runs out of fuel, disable it and re-enable players light source if self.candle.fuel_level <= 0: self.candle_light.radius = 0 self.player_light.radius = 100 # make player light follow self.player_light.position = self.player.position # update screen view self.scroll_manager.update() # vary the light radius of torches to simulate real fire for light in self.torches.values(): light.radius = TORCH_RADI[int(self.light_index)] # increase light index by .1. only whole number indexes so every # 10 frames it will increase by a whole number and update self.light_index += .1 if self.light_index >= len(TORCH_RADI): self.light_index = 0 self.perma_torches.update_animation() self.light_list.update_animation() # update self.player.update() # update keys self.key_change() # advance dialogue text\ if self.text: self.text.advance() # movement system def key_change(self): v_keys = 0 h_keys = 0 if self.keys_pressed: for key in self.keys_pressed: if key in 'ws': self.player.move_y(self.controls[key]) v_keys += 1 elif key in 'ad': h_keys += 1 self.player.move_x(self.controls[key]) if not v_keys: self.player.move_y(0) elif not h_keys: self.player.move_x(0) else: self.player.move_x(0) self.player.move_y(0) def on_mouse_press(self, x: float, y: float, button: int, modifiers: int): light = arcade.get_sprites_at_point((x, y), self.unlit_lights) # if light: def on_mouse_release(self, x: float, y: float, button: int, modifiers: int): pass def on_key_press(self, symbol: int, modifiers: int): global SCALE key = chr(symbol) # if key in movement controls add to keys pressed if key in list(self.controls.keys()): self.keys_pressed.append(key) elif key == 'q': # toggle torches on the wall on/off if not self.loot_chest(): self.toggle_torch() elif key == 'e': if self.show_inv: self.show_inv = False else: self.show_inv = True elif symbol == arcade.key.SPACE and self.show_text: self.show_text = False self.text = None elif key == 'm': print("mouse_pos:", self.mouse_pos) print("playerpos:", self.player.position) self.scroll_manager.output_values() # toggle the players candle elif symbol == arcade.key.SPACE: # if the player is holding a candle, toggle it off if self.player.holding_candle: self.player.toggle_candle() # toggle self.light_layer.remove(self.candle_light) # remove light source self.perma_torches.remove(self.candle) # remove from torches (it will not draw anymore) self.player_light.radius = 100 * SCALE # re-enable player default light self.candle = None # set candle to None # if player isn't holding candle, toggle it on else: # toggle self.player.toggle_candle() # create lightsource object light = Light(self.player.candle.center_x, self.player.candle.center_y, 400 * SCALE, TORCH_LIGHT, 'soft') self.perma_torches.append(self.player.candle) # add player candle to perma_torches (cant be toggled by pressing q) self.candle = self.player.candle # set the candle to the players candle self.candle_light = light # set candle light to light object self.player_light.radius = 0 # disable the players default light self.light_layer.add(self.candle_light) # add light source to light layer self.key_change() def loot_chest(self): # get closest chest sprite chest = arcade.get_closest_sprite(self.player, self.chests) dist = chest[1] chest = chest[0] # if the chest is within range, loot it and display the contents if dist < ACTION_RANGE: item = chest.loot if item: # set show text to true and create new dialogue object self.show_text = True self.text = Dialogue(self.player.collect(item),'\n', item.description, delay=3) chest.loot = None return True else: # loot can only be found once self.show_text = True self.text = Dialogue(f"You already found the loot in this chest.") def toggle_torch(self): # get closest unlit torch unlit_torch = arcade.get_closest_sprite(self.player, self.unlit_lights) dist = unlit_torch[1] unlit_torch = unlit_torch[0] # if torch is within action range, turn it on if dist < ACTION_RANGE: # create new lit torch to replace unlit torch new_torch = items.Torch(unlit_torch.center_x, unlit_torch.center_y, SCALE) # get rid of unlit torch unlit_torch.kill() # add torch to list of torches self.light_list.append(new_torch) # create a new light source and assign it to the torch light = Light(new_torch.center_x, new_torch.center_y, TORCH_RADIUS, TORCH_LIGHT, 'soft') self.torches[new_torch] = light self.light_layer.add(light) else: lit_torch = arcade.get_closest_sprite(self.player, self.light_list) dist = lit_torch[1] lit_torch = lit_torch[0] # self.torches.pop(lit_torch) # if there isnt an unlit torch in range, but there is a lit torch, turn it off if dist < ACTION_RANGE: # make new unlit torch new_torch = items.UnlitTorch(lit_torch.center_x, lit_torch.center_y, SCALE) # get rid of light source light = self.torches[lit_torch] self.light_layer.remove(light) # get rid of lit torch and add unlit torch lit_torch.kill() self.unlit_lights.append(new_torch) def on_key_release(self, symbol: int, modifiers: int): key = chr(symbol) if key in self.keys_pressed: self.keys_pressed.remove(key) self.key_change() def on_mouse_motion(self, x: float, y: float, dx: float, dy: float): self.mouse_pos = (x, y) pass
class MyGame(arcade.Window): """ Main Game Window """ def __init__(self, width, height, title): """ Set up the class. """ super().__init__(width, height, title, resizable=True) # Sprite lists self.background_sprite_list = None self.player_list = None self.wall_list = None self.player_sprite = None # Physics engine self.physics_engine = None # Used for scrolling self.view_left = 0 self.view_bottom = 0 # --- Light related --- # List of all the lights self.light_layer = None # Individual light we move with player, and turn on/off self.player_light = None def setup(self): """ Create everything """ # Create sprite lists self.background_sprite_list = arcade.SpriteList() self.player_list = arcade.SpriteList() self.wall_list = arcade.SpriteList() # Create player sprite self.player_sprite = arcade.Sprite( ":resources:images/animated_characters/female_person/femalePerson_idle.png", 0.4) self.player_sprite.center_x = 64 self.player_sprite.center_y = 270 self.player_list.append(self.player_sprite) # --- Light related --- # Lights must shine on something. If there is no background sprite or color, # you will just see black. Therefore, we use a loop to create a whole bunch of brick tiles to go in the # background. for x in range(-128, 2000, 128): for y in range(-128, 1000, 128): sprite = arcade.Sprite( ":resources:images/tiles/brickTextureWhite.png") sprite.position = x, y self.background_sprite_list.append(sprite) # Create a light layer, used to render things to, then post-process and # add lights. This must match the screen size. self.light_layer = LightLayer(SCREEN_WIDTH, SCREEN_HEIGHT) # We can also set the background color that will be lit by lights, # but in this instance we just want a black background self.light_layer.set_background_color(arcade.color.BLACK) # Here we create a bunch of lights. # Create a small white light x = 100 y = 200 radius = 100 mode = 'soft' color = arcade.csscolor.WHITE light = Light(x, y, radius, color, mode) self.light_layer.add(light) # Create an overlapping, large white light x = 300 y = 150 radius = 200 color = arcade.csscolor.WHITE mode = 'soft' light = Light(x, y, radius, color, mode) self.light_layer.add(light) # Create three, non-overlapping RGB lights x = 50 y = 450 radius = 100 mode = 'soft' color = arcade.csscolor.RED light = Light(x, y, radius, color, mode) self.light_layer.add(light) x = 250 y = 450 radius = 100 mode = 'soft' color = arcade.csscolor.GREEN light = Light(x, y, radius, color, mode) self.light_layer.add(light) x = 450 y = 450 radius = 100 mode = 'soft' color = arcade.csscolor.BLUE light = Light(x, y, radius, color, mode) self.light_layer.add(light) # Create three, overlapping RGB lights x = 650 y = 450 radius = 100 mode = 'soft' color = arcade.csscolor.RED light = Light(x, y, radius, color, mode) self.light_layer.add(light) x = 750 y = 450 radius = 100 mode = 'soft' color = arcade.csscolor.GREEN light = Light(x, y, radius, color, mode) self.light_layer.add(light) x = 850 y = 450 radius = 100 mode = 'soft' color = arcade.csscolor.BLUE light = Light(x, y, radius, color, mode) self.light_layer.add(light) # Create three, overlapping RGB lights # But 'hard' lights that don't fade out. x = 650 y = 150 radius = 100 mode = 'hard' color = arcade.csscolor.RED light = Light(x, y, radius, color, mode) self.light_layer.add(light) x = 750 y = 150 radius = 100 mode = 'hard' color = arcade.csscolor.GREEN light = Light(x, y, radius, color, mode) self.light_layer.add(light) x = 850 y = 150 radius = 100 mode = 'hard' color = arcade.csscolor.BLUE light = Light(x, y, radius, color, mode) self.light_layer.add(light) # Create a light to follow the player around. # We'll position it later, when the player moves. # We'll only add it to the light layer when the player turns the light # on. We start with the light off. radius = 150 mode = 'soft' color = arcade.csscolor.WHITE self.player_light = Light(0, 0, radius, color, mode) # Create the physics engine self.physics_engine = arcade.PhysicsEngineSimple( self.player_sprite, self.wall_list) # Set the viewport boundaries # These numbers set where we have 'scrolled' to. self.view_left = 0 self.view_bottom = 0 def on_draw(self): """ Draw everything. """ arcade.start_render() # --- Light related --- # Everything that should be affected by lights gets rendered inside this # 'with' statement. Nothing is rendered to the screen yet, just the light # layer. with self.light_layer: self.background_sprite_list.draw() self.player_list.draw() # Draw the light layer to the screen. # This fills the entire screen with the lit version # of what we drew into the light layer above. self.light_layer.draw(ambient_color=AMBIENT_COLOR) # Now draw anything that should NOT be affected by lighting. arcade.draw_text("Press SPACE to turn character light on/off.", 10 + self.view_left, 10 + self.view_bottom, arcade.color.WHITE, 20) def on_resize(self, width, height): """ User resizes the screen. """ # --- Light related --- # We need to resize the light layer to self.light_layer.resize(width, height) # Scroll the screen so the user is visible self.scroll_screen() def on_key_press(self, key, _): """Called whenever a key is pressed. """ if key == arcade.key.UP: self.player_sprite.change_y = MOVEMENT_SPEED elif key == arcade.key.DOWN: self.player_sprite.change_y = -MOVEMENT_SPEED elif key == arcade.key.LEFT: self.player_sprite.change_x = -MOVEMENT_SPEED elif key == arcade.key.RIGHT: self.player_sprite.change_x = MOVEMENT_SPEED elif key == arcade.key.SPACE: # --- Light related --- # We can add/remove lights from the light layer. If they aren't # in the light layer, the light is off. if self.player_light in self.light_layer: self.light_layer.remove(self.player_light) else: self.light_layer.add(self.player_light) def on_key_release(self, key, _): """Called when the user releases a key. """ if key == arcade.key.UP or key == arcade.key.DOWN: self.player_sprite.change_y = 0 elif key == arcade.key.LEFT or key == arcade.key.RIGHT: self.player_sprite.change_x = 0 def scroll_screen(self): """ Manage Scrolling """ # Scroll left left_boundary = self.view_left + VIEWPORT_MARGIN if self.player_sprite.left < left_boundary: self.view_left -= left_boundary - self.player_sprite.left # Scroll right right_boundary = self.view_left + self.width - VIEWPORT_MARGIN if self.player_sprite.right > right_boundary: self.view_left += self.player_sprite.right - right_boundary # Scroll up top_boundary = self.view_bottom + self.height - VIEWPORT_MARGIN if self.player_sprite.top > top_boundary: self.view_bottom += self.player_sprite.top - top_boundary # Scroll down bottom_boundary = self.view_bottom + VIEWPORT_MARGIN if self.player_sprite.bottom < bottom_boundary: self.view_bottom -= bottom_boundary - self.player_sprite.bottom # Make sure our boundaries are integer values. While the viewport does # support floating point numbers, for this application we want every pixel # in the view port to map directly onto a pixel on the screen. We don't want # any rounding errors. self.view_left = int(self.view_left) self.view_bottom = int(self.view_bottom) arcade.set_viewport(self.view_left, self.width + self.view_left, self.view_bottom, self.height + self.view_bottom) def on_update(self, delta_time): """ Movement and game logic """ # Call update on all sprites (The sprites don't do much in this # example though.) self.physics_engine.update() # --- Light related --- # We can easily move the light by setting the position, # or by center_x, center_y. self.player_light.position = self.player_sprite.position # Scroll the screen so we can see the player self.scroll_screen()
class MyGame(arcade.Window): """ Main application class. """ def __init__(self): """ Initializer """ # Call the parent class initializer super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, fullscreen=False) # Set the working directory (where we expect to find files) to the same # directory this .py file is in. You can leave this out of your own # code, but it is needed to easily run the examples using "python -m" # as mentioned at the top of this program. file_path = os.path.dirname(os.path.abspath(__file__)) os.chdir(file_path) # Variables that will hold sprite lists self.player_list = None self.coin_list = None self.bullet_list = None self.explosions_list = None self.wall_list = None # Set up the player info self.player = None self.score = 0 self.can_move = True self.light_layer = None self.player_light = None self.player_radius = 200 # Pre-load the animation frames. We don't do this in the __init__ # of the explosion sprite because it # takes too long and would cause the game to pause. self.explosion_texture_list = [] columns = 16 count = 60 sprite_width = 256 sprite_height = 256 file_name = ":resources:images/spritesheets/explosion.png" # Load the explosions from a sprite sheet self.explosion_texture_list = arcade.load_spritesheet( file_name, sprite_width, sprite_height, columns, count) # Load sounds. Sounds from kenney.nl self.gun_sound = arcade.sound.load_sound( ":resources:sounds/laser2.wav") self.hit_sound = arcade.sound.load_sound( ":resources:sounds/explosion2.wav") self.a_down = False self.d_down = False self.s_down = False self.w_down = False self.VIEW_LEFT = 0 - (SCREEN_WIDTH / 2) self.VIEW_BOT = 0 - (SCREEN_HEIGHT / 2) def setup(self): """ Set up the game and initialize the variables. """ # Sprite lists self.player_list = arcade.SpriteList() self.coin_list = arcade.SpriteList() self.bullet_list = arcade.SpriteList() self.explosions_list = arcade.SpriteList() self.wall_list = maps.create_walls() # Set up the player self.score = 0 # Image from kenney.nl self.player = player.PlayerCharacter() self.player.center_x = 0 self.player.center_y = 0 self.player_list.append(self.player) self.physics_engine = arcade.PhysicsEngineSimple( self.player, self.wall_list) # Create the coins for coin_index in range(COIN_COUNT): # Create the coin instance # Coin image from kenney.nl coin = arcade.Sprite(":resources:images/items/coinGold.png", SPRITE_SCALING_COIN) # Position the coin coin.center_x = random.randrange(SCREEN_WIDTH) coin.center_y = random.randrange(150, SCREEN_HEIGHT) # Add the coin to the lists self.coin_list.append(coin) # Set the background color #arcade.set_background_color(arcade.color.CELESTIAL_BLUE) # Lighting self.light_layer = LightLayer(SCREEN_WIDTH, SCREEN_HEIGHT) self.light_layer.set_background_color(arcade.color.CELESTIAL_BLUE) # Player lighting self.player_light = Light(0, 0, self.player_radius, arcade.csscolor.WHITE, 'soft') self.light_layer.add(self.player_light) def on_key_press(self, key, modifiers): if not self.can_move: return if key == arcade.key.A: self.a_down = True self.player.change_x = -PLAYER_SPEED elif key == arcade.key.D: self.d_down = True self.player.change_x = PLAYER_SPEED elif key == arcade.key.S: self.s_down = True self.player.change_y = -PLAYER_SPEED elif key == arcade.key.W: self.w_down = True self.player.change_y = PLAYER_SPEED def on_key_release(self, key, modifiers): if key == arcade.key.A: self.a_down = False if not self.d_down: self.player.change_x = 0 elif key == arcade.key.D: self.d_down = False if not self.a_down: self.player.change_x = 0 elif key == arcade.key.S: self.s_down = False if not self.w_down: self.player.change_y = 0 elif key == arcade.key.W: self.w_down = False if not self.s_down: self.player.change_y = 0 def disable_movement(self): self.player.change_x = 0 self.player.change_y = 0 self.can_move = False def enable_movement(self): self.can_move = True def on_draw(self): """ Render the screen. """ # This command has to happen before we start drawing arcade.start_render() # Draw all the sprites. with self.light_layer: self.coin_list.draw() self.bullet_list.draw() self.player_list.draw() self.light_layer.draw(ambient_color=(0, 0, 0)) self.explosions_list.draw() self.wall_list.draw() # Render the text arcade.draw_text(f"Score: {self.score}", 10, 20, arcade.color.WHITE, 14) def on_mouse_press(self, x, y, button, modifiers): """ Called whenever the mouse button is clicked. """ self.shoot() def on_update(self, delta_time): """ Movement and game logic """ self.physics_engine.update() self.player_list.update_animation() # Call update on bullet sprites self.bullet_list.update() self.explosions_list.update() arcade.set_viewport( self.VIEW_LEFT + self.player.center_x, self.VIEW_LEFT + self.player.center_x + SCREEN_WIDTH, self.VIEW_BOT + self.player.center_y, self.VIEW_BOT + self.player.center_y + SCREEN_HEIGHT, ) self.player_light.position = self.player.position # Loop through each bullet for bullet in self.bullet_list: # Check this bullet to see if it hit a coin hit_list = arcade.check_for_collision_with_list( bullet, self.coin_list) # If it did... if len(hit_list) > 0: # Make an explosion explosion = Explosion(self.explosion_texture_list) # Move it to the location of the coin explosion.center_x = hit_list[0].center_x explosion.center_y = hit_list[0].center_y # Call update() because it sets which image we start on explosion.update() # Add to a list of sprites that are explosions self.explosions_list.append(explosion) # Get rid of the bullet bullet.remove_from_sprite_lists() # For every coin we hit, add to the score and remove the coin for coin in hit_list: coin.remove_from_sprite_lists() self.score += 1 # Hit Sound arcade.sound.play_sound(self.hit_sound) # If the bullet flies off-screen, remove it. if bullet.bottom > SCREEN_HEIGHT: bullet.remove_from_sprite_lists()
class MyGame(arcade.Window): def __init__(self, width, height, title): """ Set up the application. """ super().__init__(width, height, title) self.time = 0 self.background = arcade.load_texture(":resources:images/backgrounds/abstract_1.jpg") self.torch_list = arcade.SpriteList(is_static=True) self.torch_list.extend([ arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=100, center_y=150), arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=300, center_y=150), arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=500, center_y=150), arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=700, center_y=150), arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=100, center_y=450), arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=300, center_y=450), arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=500, center_y=450), arcade.Sprite(":resources:images/tiles/torch1.png", scale=0.4, center_x=700, center_y=450), ]) self.light_layer = LightLayer(SCREEN_WIDTH, SCREEN_HEIGHT) # Add lights to the location of the torches. We're just using hacky tweak value list here params = ( (100, 'hard'), (100, 'hard'), (100, 'hard'), (100, 'hard'), (120, 'soft'), (120, 'soft'), (120, 'soft'), (120, 'soft'), ) for sprite, p in zip(self.torch_list, params): self.light_layer.add( Light(sprite.center_x, sprite.center_y, radius=p[0], mode=p[1]), ) self.moving_light = Light(400, 300, radius=300, mode='soft') self.light_layer.add(self.moving_light) def on_draw(self): arcade.start_render() # Everything that should be affected by lights in here with self.light_layer: arcade.draw_lrwh_rectangle_textured( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background) self.torch_list.draw() # Draw the contents with lighting self.light_layer.draw() # draw with ambient # self.light_layer.draw(ambient_color=(127, 127, 127)) def on_update(self, dt): # Keep track of elapsed time self.time += dt self.moving_light.position = ( 400 + math.sin(self.time) * 300, 300 + math.cos(self.time) * 50 ) self.moving_light.radius = 300 + math.sin(self.time * 2.34) * 150 def on_resize(self, width, height): arcade.set_viewport(0, width, 0, height) self.light_layer.resize(width, height)
class SingleScene(BaseScene): def setup(self, win): left, self.screen_width, bottom, self.screen_height = win.get_viewport( ) self.coils = ActorList() self.light_layer = LightLayer(self.screen_width, self.screen_height) # self.light_layer.set_background_color(arcade.color.BLACK) radius = 1000 b = arcade.color.MIDNIGHT_BLUE darken = 0.2 light_color = b[0] * darken, b[1] * darken, b[2] * darken self.light1 = Light(0, 0, radius=radius, mode='soft', color=light_color) self.light_layer.add(self.light1) self.light2 = Light(0, 0, radius=radius, mode='soft', color=light_color) self.light_layer.add(self.light2) self.light3 = Light(0, 0, radius=radius, mode='soft', color=light_color) self.light_layer.add(self.light3) self.light4 = Light(0, 0, radius=radius, mode='soft', color=light_color) self.light_layer.add(self.light4) def add_coil(self): x = random.randint(0, self.screen_width) y = random.randint(0, self.screen_height) arc_count = random.randint(MIN_ARCS, MAX_ARCS) coil = Coil(self, x, y, START_RADIUS, RADIUS_STEP, arc_count) self.coils.append(coil) coil.start_anim(self) def enter_scene(self, previous_scene): for _ in range(COIL_COUNT): self.add_coil() self.add_anim_to_light(self.light1) self.add_anim_to_light(self.light2) self.add_anim_to_light(self.light3) self.add_anim_to_light(self.light4) def add_anim_to_light(self, light): light.animate = AnimationManagerProxy(light) elapsed = 0.0 seq = Sequence(loop=True) for _ in range(10): key = KeyFrame(position=(random.randint(0, self.screen_width), random.randint(0, self.screen_height))) seq.add_keyframe(elapsed, key) elapsed += random.uniform(15.0, 30.0) light.animate(seq) def draw(self): with self.light_layer: arcade.draw_xywh_rectangle_filled(0, 0, self.screen_width, self.screen_height, arcade.color.WHITE) self.light_layer.draw(ambient_color=arcade.color.BLACK) self.coils.draw() self.coils.update(0.0) # to make sure coils get reaped from ActorList