def generate_sprites(map_object: TiledMap, layer_name: str, scaling: float, base_directory="") -> SpriteList: """ Generate the sprites for a layer in a map. :param TiledMap map_object: Map previously read in from read_tiled_map function :param layer_name: Name of the layer we want to generate sprites from. Case sensitive. :param scaling: Scaling factor. :param base_directory: Directory to read images from. Defaults to current directory. :return: List of sprites :rtype: SpriteList """ sprite_list = SpriteList() if layer_name not in map_object.layers_int_data: print(f"Warning, no layer named '{layer_name}'.") return sprite_list map_array = map_object.layers_int_data[layer_name] # Loop through the layer and add in the wall list for row_index, row in enumerate(map_array): for column_index, item in enumerate(row): if str(item) in map_object.global_tile_set: tile_info = map_object.global_tile_set[str(item)] tmx_file = base_directory + tile_info.source my_sprite = Sprite(tmx_file, scaling) my_sprite.right = column_index * (map_object.tilewidth * scaling) my_sprite.top = (map_object.height - row_index) * (map_object.tileheight * scaling) if tile_info.points is not None: my_sprite.set_points(tile_info.points) sprite_list.append(my_sprite) elif item != 0: print(f"Warning, could not find {item} image to load.") return sprite_list
def _process_object_layer(map_object: pytiled_parser.objects.TileMap, layer: pytiled_parser.objects.ObjectLayer, scaling: float = 1, base_directory: str = "") -> SpriteList: sprite_list = SpriteList() for cur_object in layer.tiled_objects: if cur_object.gid is None: print("Warning: Currently only tiles (not objects) are supported in object layers.") continue tile = _get_tile_by_gid(map_object, cur_object.gid) my_sprite = _create_sprite_from_tile(map_object, tile, scaling=scaling, base_directory=base_directory) my_sprite.right = cur_object.location.x * scaling my_sprite.top = (map_object.map_size.height * map_object.tile_size[1] - cur_object.location.y) * scaling if cur_object.properties is not None and 'change_x' in cur_object.properties: my_sprite.change_x = float(cur_object.properties['change_x']) if cur_object.properties is not None and 'change_y' in cur_object.properties: my_sprite.change_y = float(cur_object.properties['change_y']) if cur_object.properties is not None and 'boundary_bottom' in cur_object.properties: my_sprite.boundary_bottom = float(cur_object.properties['boundary_bottom']) if cur_object.properties is not None and 'boundary_top' in cur_object.properties: my_sprite.boundary_top = float(cur_object.properties['boundary_top']) if cur_object.properties is not None and 'boundary_left' in cur_object.properties: my_sprite.boundary_left = float(cur_object.properties['boundary_left']) if cur_object.properties is not None and 'boundary_right' in cur_object.properties: my_sprite.boundary_right = float(cur_object.properties['boundary_right']) my_sprite.properties.update(cur_object.properties) # sprite.properties sprite_list.append(my_sprite) return sprite_list
class MonsterAI(Processor): def __init__(self): self.targets = SpriteList() def process(self, *args, **kwargs): [ self.targets.append(x[1][0]) for x in self.world.get_components(Renderable, Player) ] for m, (render, monster, vel) in self.world.get_components(Renderable, Monster, Velocity): target, dist = get_closest_sprite(render, self.targets) if 1000 >= dist >= 120: self.follow_target(render, target, vel) else: vel.x = 0 vel.y = 0 for i in range(len(self.targets)): self.targets.pop() def follow_target(self, monster, target, velocity): if monster.center_y < target.center_y: velocity.y = min(velocity.speed, target.center_y - monster.center_y) print(velocity.x, velocity.y) elif monster.center_y > target.center_y: velocity.y = min(velocity.speed, monster.center_y - target.center_y) * (-1) else: velocity.y = 0 if monster.center_x < target.center_x: velocity.x = min(velocity.speed, target.center_x - monster.center_x) elif monster.center_x > target.center_x: velocity.x = min(velocity.speed, monster.center_x - target.center_x) * (-1) else: velocity.x = 0
class MovementProcessor(Processor): def __init__(self): self.blocked_tiles = SpriteList() def process(self): from components.render import Velocity, Renderable, Block [ self.blocked_tiles.append(x[1][0]) for x in self.world.get_components(Renderable, Block) ] for ent, (vel, rend, name) in self.world.get_components(Velocity, Renderable, Name): rend.center_x += vel.x if check_for_collision_with_list(rend, self.blocked_tiles): rend.center_x += (vel.x * -1) rend.center_y += vel.y if check_for_collision_with_list(rend, self.blocked_tiles): rend.center_y += (vel.y * -1) if not vel.x and not vel.y: rend.idle = True rend.texture = rend.walking_textures[rend.direction][0] else: rend.idle = False if vel.y > 0: rend.direction = 0 elif vel.y < 0: rend.direction = 2 if vel.x > 0: rend.direction = 3 elif vel.x < 0: rend.direction = 1 for b in range(len(self.blocked_tiles)): self.blocked_tiles.pop()
class UIManager(EventDispatcher): """ Central component of :py:mod:`arcade.gui` . Holds :py:class:`arcade.gui.UIElement` and connects them with :py:class:`arcade.Window` callbacks. Basics: * Add :py:class:`arcade.gui.UIElement` with :py:meth:`arcade.gui.UIManager.add_ui_element()` * Remove all :py:class:`arcade.gui.UIElement` with :py:meth:`arcade.gui.UIManager.purge_ui_elements()` """ def __init__(self, window=None, attach_callbacks=True, **kwargs): """ Creates a new :py:class:`arcade.gui.UIManager` and registers the corresponding handlers to the current window. The UIManager has to be created, before :py:meth:`arcade.Window.show_view()` has been called. To support multiple views a singleton UIManager should be passed to all views. As an alternative you can remove all registered handlers of a UIManager by calling :py:meth:`arcade.gui.UIManager.unregister_handlers()` within :py:meth:`arcade.View.on_hide_view()`. :param arcade.Window window: Window to register handlers to, defaults to :py:meth:`arcade.get_window()` :param kwargs: catches unsupported named parameters """ super().__init__() # TODO really needed? self.window: Window = window if window else arcade.get_window() self._focused_element: Optional[UIElement] = None self._hovered_element: Optional[UIElement] = None self._ui_elements: SpriteList = SpriteList(use_spatial_hash=True) self._id_cache: Dict[str, UIElement] = {} self.register_event_type('on_ui_event') if attach_callbacks: self.register_handlers() def register_handlers(self): """ Registers handler functions (`on_...`) to :py:attr:`arcade.gui.UIElement` """ # self.window.push_handlers(self) # Not as explicit as following self.window.push_handlers( self.on_resize, self.on_update, self.on_draw, self.on_mouse_press, self.on_mouse_release, self.on_mouse_scroll, self.on_mouse_motion, self.on_key_press, self.on_key_release, self.on_text, self.on_text_motion, self.on_text_motion_select, ) def unregister_handlers(self): """ Remove handler functions (`on_...`) from :py:attr:`arcade.Window` If every :py:class:`arcade.View` uses its own :py:class:`arcade.gui.UIManager`, this method should be called in :py:meth:`arcade.View.on_hide_view()`. """ self.window.remove_handlers( self.on_resize, self.on_update, self.on_draw, self.on_mouse_press, self.on_mouse_release, self.on_mouse_scroll, self.on_mouse_motion, self.on_key_press, self.on_key_release, self.on_text, self.on_text_motion, self.on_text_motion_select, ) @property def focused_element(self) -> Optional[UIElement]: """ :return: focused UIElement, only one UIElement can be focused at a time """ return self._focused_element @focused_element.setter def focused_element(self, new_focus: UIElement): if self._focused_element is not None: self._focused_element.on_unfocus() self._focused_element = None if new_focus is not None: new_focus.on_focus() self._focused_element = new_focus @property def hovered_element(self) -> Optional[UIElement]: """ :return: hovered UIElement, only one UIElement can be focused at a time """ return self._hovered_element @hovered_element.setter def hovered_element(self, new_hover: UIElement): if self._hovered_element is not None: self._hovered_element.on_unhover() self._hovered_element = None if new_hover is not None: new_hover.on_hover() self._hovered_element = new_hover def purge_ui_elements(self): """ Removes all UIElements which where added to the :py:class:`arcade.gui.UIManager`. """ self._ui_elements = SpriteList() self._id_cache = {} def add_ui_element(self, ui_element: UIElement): """ Adds a :py:class:`arcade.gui.UIElement` to the :py:class:`arcade.gui.UIManager`. :py:attr:`arcade.gui.UIElement.id` has to be unique. The :py:class:`arcade.gui.UIElement` will be drawn by the :py:class:`arcade.gui.UIManager`. :param UIElement ui_element: element to add. """ if not hasattr(ui_element, 'id'): raise UIException( 'UIElement seems not to be properly setup, please check if you' ' overwrite the constructor and forgot "super().__init__(**kwargs)"' ) ui_element.render() self._ui_elements.append(ui_element) ui_element.mng = self # Add elements with id to lookup if ui_element.id is not None: if ui_element.id in self._id_cache: raise UIException(f'duplicate id "{ui_element.id}"') self._id_cache[ui_element.id] = ui_element def find_by_id(self, ui_element_id: str) -> Optional[UIElement]: """ Finds an :py:class:`arcade.gui.UIElement` by its ID. :param str ui_element_id: id of the :py:class:`arcade.gui.UIElement` :return: :py:class:`arcade.gui.UIElement` if available else None """ return self._id_cache.get(ui_element_id) def on_resize(self, width, height): """ Callback triggered on window resize """ pass def on_draw(self): """ Draws all added :py:class:`arcade.gui.UIElement`. """ self._ui_elements.draw() def on_update(self, dt): """ Callback triggered on update """ pass def dispatch_ui_event(self, event: UIEvent): """ Dispatches a :py:class:`arcade.gui.UIEvent` to all added :py:class:`arcade.gui.UIElement`\ s. :param UIEvent event: event to dispatch :return: """ self.dispatch_event('on_ui_event', event) def on_ui_event(self, event: UIEvent): """ Processes UIEvents, forward events to added elements and manages focused and hovered elements """ for ui_element in list(self._ui_elements): ui_element = cast(UIElement, ui_element) if event.type == MOUSE_PRESS: if ui_element.collides_with_point( (event.get('x'), event.get('y'))): self.focused_element = ui_element elif ui_element is self.focused_element: # TODO does this work like expected? self.focused_element = None if event.type == MOUSE_MOTION: if ui_element.collides_with_point( (event.get('x'), event.get('y'))): self.hovered_element = ui_element elif ui_element is self.hovered_element: self.hovered_element = None ui_element.on_ui_event(event) def on_mouse_press(self, x: float, y: float, button: int, modifiers: int): """ Dispatches :py:meth:`arcade.View.on_mouse_press()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.MOUSE_PRESS` """ self.dispatch_ui_event( UIEvent(MOUSE_PRESS, x=x, y=y, button=button, modifiers=modifiers)) def on_mouse_release(self, x: float, y: float, button: int, modifiers: int): """ Dispatches :py:meth:`arcade.View.on_mouse_release()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.MOUSE_RELEASE` """ self.dispatch_ui_event( UIEvent(MOUSE_RELEASE, x=x, y=y, button=button, modifiers=modifiers)) def on_mouse_scroll(self, x: int, y: int, scroll_x: int, scroll_y: int): """ Dispatches :py:meth:`arcade.View.on_mouse_scroll()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.MOUSE_SCROLL` """ self.dispatch_ui_event( UIEvent( MOUSE_SCROLL, x=x, y=y, scroll_x=scroll_x, scroll_y=scroll_y, )) def on_mouse_motion(self, x: float, y: float, dx: float, dy: float): """ Dispatches :py:meth:`arcade.View.on_mouse_motion()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.MOUSE_MOTION` """ self.dispatch_ui_event(UIEvent( MOUSE_MOTION, x=x, y=y, dx=dx, dy=dy, )) def on_key_press(self, symbol: int, modifiers: int): """ Dispatches :py:meth:`arcade.View.on_key_press()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.KEY_PRESS` """ self.dispatch_ui_event( UIEvent(KEY_PRESS, symbol=symbol, modifiers=modifiers)) def on_key_release(self, symbol: int, modifiers: int): """ Dispatches :py:meth:`arcade.View.on_key_release()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.KEY_RELEASE` """ self.dispatch_ui_event( UIEvent(KEY_RELEASE, symbol=symbol, modifiers=modifiers)) def on_text(self, text): """ Dispatches :py:meth:`arcade.View.on_text()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.TEXT_INPUT` """ self.dispatch_ui_event(UIEvent( TEXT_INPUT, text=text, )) def on_text_motion(self, motion): """ Dispatches :py:meth:`arcade.View.on_text_motion()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.TEXT_MOTION` """ self.dispatch_ui_event(UIEvent( TEXT_MOTION, motion=motion, )) def on_text_motion_select(self, selection): """ Dispatches :py:meth:`arcade.View.on_text_motion_select()` as :py:class:`arcade.gui.UIElement` with type :py:attr:`arcade.gui.TEXT_MOTION_SELECT` """ self.dispatch_ui_event( UIEvent( TEXT_MOTION_SELECTION, selection=selection, ))
class Game(ge.Platformer): """ Simple game my_level """ final = 90 SCORE = 2 viewport_margin_horizontal = 400 viewport_margin_vertical = 300 LIMIT = 3 cal = False # SOUNDS coin_sound = arcade.load_sound('examples/sounds/coin.wav') jump_sound = arcade.load_sound('examples/sounds/jump.wav') disc_sound = arcade.load_sound('examples/sounds/disc.wav') def init_world(self): # Inicio e chão self.create_tower(10, 2, coords=(0, 1)) self.create_ground(self.final, coords=(0, 0), smooth_ends=True) # Plataforma para fazer a camera acompanhar o jogador em qualquer altura self.create_platform(1, coords=(20, 90)) # Cenário self.moving_platform_list = SpriteList() platform = self.create_object('tile/blue/gl', (34, 3), at=self.moving_platform_list, role=Role.OBJECT) platform = self.create_object('tile/blue/g', (35, 3), at=self.moving_platform_list, role=Role.OBJECT) platform = self.create_object('tile/blue/gr', (36, 3), at=self.moving_platform_list, role=Role.OBJECT) def create_spike(tam, x, y): for i in range(tam): spike = self.create_object('other/spikes/spikes-high', (x, y), at=self.spikes) x += 1 self.discs = SpriteList() def create_disc(x, y): disc = self.create_object('other/items/discGreen', (x, y), at=self.discs) def create_door_key(x, y): doorkey = self.create_object('other/door/doorRed_lock', (x, y), at=self.doorkey) def create_door_top(x, y): doortop = self.create_object('other/door/doorRed_top', (x, y), at=self.doortop) for pt in [(3, (6, 3)), (3, (9, 6)), (3, (12, 9)), (3, (20, 9)), (1, (20, 3)), (3, (62, 5)), (3, (67, 3)), (3, (30, 6))]: s, l = pt self.create_platform(s, l) for pt in [(2, 3, (12, 1)), (4, 3, (14, 1)), (2, 3, (24, 1)), (4, 3, (26, 1)), (2, 3, (52, 1)), (2, 3, (56, 1)), (5, 3, (54, 1)), (2, 3, (75, 1)), (5, 3, (73, 1)), (7, 3, (87, 1))]: x, y, w = pt self.create_tower(x, y, w) # Final tower self.create_tower(10, coords=(self.final - 1, 1)) # Spikes self.spikes = SpriteList() create_spike(7, 17, 1) create_spike(23, 29, 1) create_spike(14, 59, 1) # Discs create_disc(63, 11) create_disc(21, 10) create_disc(20, 4) create_disc(40, 4) create_disc(40, 8) # Door key self.doorkey = SpriteList() create_door_key(88, 8) # Door top self.doortop = SpriteList() create_door_top(88, 9) # Foreground self.create_arrow('right', (3, 1)) self.create_fence('left', (52, 3)) self.create_fence('right', (53, 3)) self.create_fence('left', (57, 3)) self.create_fence('left', (58, 3)) self.create_fence('left', (58, 3)) self.create_fence('left', (76, 3)) self.create_fence('right', (77, 3)) # Background self.background_near = SpriteList(use_spatial_hash=False) self.background_fixed = SpriteList(use_spatial_hash=False) self.background_fixed.append(Sprite(get_sprite_path('background/bg1'))) # Limite da Plataforma que anda def limit_of_platforms(self): self.limit_of_platform_moving = SpriteList(is_static=True) limit = self.create_object('other/block/brown', (30, 3), at=self.limit_of_platform_moving) limit = self.create_object('other/block/brown', (50, 3), at=self.limit_of_platform_moving) # Limite do inimigo que anda def limit_of_enemies(self): self.limit_of_enemies_moving_in_x = SpriteList(is_static=True) limit = self.create_object('other/block/brown', (30, 7), at=self.limit_of_enemies_moving_in_x) limit = self.create_object('other/block/brown', (50, 7), at=self.limit_of_enemies_moving_in_x) def limit_enemies(self): self.limit_of_enemies_moving_in_y = SpriteList(is_static=True) limit = self.create_object('other/block/green', (72, 10), at=self.limit_of_enemies_moving_in_y) limit = self.create_object('other/block/green', (72, 2), at=self.limit_of_enemies_moving_in_y) def init_enemies(self): self.enemies = SpriteList(is_static=True) self.moving_enemies_list_in_x = SpriteList(is_static=False) self.moving_enemies_list_in_y = SpriteList(is_static=False) def create_enemy(x, y, condition, direction_x): if condition: if direction_x: enemy = self.create_object( 'enemy/enemySwimming_1', (x, y), at=self.moving_enemies_list_in_x) else: enemy = self.create_object( 'enemy/enemyFlyingAlt_1', (x, y), at=self.moving_enemies_list_in_y) else: enemy = self.create_object('enemy/enemyFloating_1', (x, y), at=self.enemies) # Parâmetro True caso seja um Inimigo que se move create_enemy(35, 7, True, True) create_enemy(35, 10, True, True) create_enemy(35, 8, True, True) create_enemy(35, 9, True, True) #create_enemy(21, 10, False, False) create_enemy(34, 6, True, False) #create_enemy(40, 4, False, False) create_enemy(46, 6, True, False) create_enemy(72, 6, True, False) create_enemy(66, 6, True, False) create_enemy(18, 6, True, False) create_enemy(23, 6, True, False) create_enemy(60, 6, True, False) def init_items(self): self.coins = SpriteList() def create_coin(x, y, *args): if args: for i in range(args[0]): coin = self.create_object('other/items/yellowGem', (x, y), at=self.coins) self.coins.append(coin) x += 1 else: coin = self.create_object('other/items/yellowGem', (x, y), at=self.coins) self.coins.append(coin) #Coins create_coin(6, 4, 3) create_coin(9, 7, 3) create_coin(14, 5, 3) create_coin(12, 10, 3) create_coin(20, 10, 3) create_coin(24, 3, 2) create_coin(26, 5, 3) create_coin(33, 4, 1) create_coin(35, 4, 1) create_coin(39, 4, 1) create_coin(41, 4, 1) create_coin(45, 4, 1) create_coin(47, 4, 1) create_coin(54, 6, 3) create_coin(62, 6, 3) create_coin(67, 4, 3) create_coin(78, 1, 3) create_coin(81, 1, 3) create_coin(84, 1, 3) self.items = SpriteList() def init(self): self.init_world() self.init_items() self.init_enemies() self.limit_of_platforms() self.limit_of_enemies() self.limit_enemies() self.score_coins = 0 self.cont = 0 self.player_life = 4 self.move_platform = 3 self.move_enemie = 5 self.move_enemy = 5 def collide_coins(self, dt): self.coins.update() coins_hit_list = arcade.check_for_collision_with_list( self.player, self.coins) i = 0 for coin in coins_hit_list: coin.remove_from_sprite_lists() i += 1 if i == self.SCORE: self.score_coins += 10 i = 0 arcade.play_sound(self.coin_sound) def collide_spikes(self, dt): self.spikes.update() spikes_hit_list = arcade.check_for_collision_with_list( self.player, self.spikes) for spike in spikes_hit_list: self.cont += 1 self.player_die() def collide_enemies(self, dt): self.enemies.update() enemies_hit_list = arcade.check_for_collision_with_list( self.player, self.enemies) moving_enemies_in_x_hit_list = arcade.check_for_collision_with_list( self.player, self.moving_enemies_list_in_x) moving_enemies_in_y_hit_list = arcade.check_for_collision_with_list( self.player, self.moving_enemies_list_in_y) for enemie in enemies_hit_list: self.cont += 1 self.player_die() for enemie in moving_enemies_in_x_hit_list: self.cont += 1 self.player_die() for enemie in moving_enemies_in_y_hit_list: self.cont += 1 self.player_die() def collide_discs(self, dt): self.discs.update() discs_hit_list = arcade.check_for_collision_with_list( self.player, self.discs) for disc in discs_hit_list: disc.remove_from_sprite_lists() self.player.jump += 50 arcade.play_sound(self.disc_sound) def player_die(self): if self.cont == self.SCORE: sleep(0.5) super().player.player_initial_tile = 4, 1 del self.physics_engine self.init_items() self.init_enemies() self.init_world() self.score_coins = 0 self.player_life -= 1 self.cont = 0 def game_over(self, dt): game.exit() def object_can_move(self, name, collision): check_hit = [] for limit in name: hit = arcade.check_for_collision_with_list(limit, collision) check_hit.append(hit) for hit in check_hit: if hit: return True return False def move_platforms(self, dt): check = self.object_can_move(self.limit_of_platform_moving, self.moving_platform_list) cont = 3 check_player = arcade.check_for_collision_with_list( self.player, self.moving_platform_list) if check_player or self.cal: self.cal = True for platform in self.moving_platform_list: if check and cont == self.LIMIT: self.move_platform *= (-1) cont = 0 platform.center_x += self.move_platform cont = 3 def move_enemies_in_x(self, dt): for enemie in self.moving_enemies_list_in_x: check_in_x = arcade.check_for_collision_with_list( enemie, self.limit_of_enemies_moving_in_x) if check_in_x: self.move_enemie *= (-1) enemie.center_x += self.move_enemie def move_enemies_in_y(self, dt): for enemy in self.moving_enemies_list_in_y: check_in_y = arcade.check_for_collision_with_list( enemy, self.limit_of_enemies_moving_in_y) if check_in_y: self.move_enemy *= (-1) enemy.center_y += self.move_enemy def on_update(self, dt): if self.player_life >= 1: super().on_update(dt) self.collide_coins(dt) self.collide_spikes(dt) self.collide_enemies(dt) self.move_enemies_in_x(dt) self.move_enemies_in_y(dt) self.collide_discs(dt) self.move_platforms(dt) else: self.game_over(dt) # JUMP SOUND if self.player.change_y > 0: if not self.jumping: arcade.play_sound(self.jump_sound) self.jumping = True else: self.jumping = False def draw_elements(self): super().draw_elements() self.enemies.draw() self.coins.draw() self.spikes.draw() self.moving_enemies_list_in_x.draw() self.moving_enemies_list_in_y.draw() self.moving_platform_list.draw() self.discs.draw() self.doorkey.draw() self.doortop.draw() #Placar de Contagem das moedas e vidas output_score = f"Score: {self.score_coins} ||" output_life = f"Life: {self.player_life}" arcade.draw_text(output_score, self.viewport_horizontal_start, self.viewport_vertical_start + 10, arcade.color.BLACK, 25) arcade.draw_text(output_life, self.viewport_horizontal_start + 250, self.viewport_vertical_start + 10, arcade.color.BLACK, 25)
class MyGame(Window): """ Main application class. """ def __init__(self, width, height, title): """ Initializer """ super().__init__(width, height, title) """ Set up the game and initialize the variables. """ # Sprite lists self.char_list = None self.shoot_list = None self.particule_list = None self.background = None self.sky_list = None self.score_list = None self.life_list = None self.ship = None # Set up other settings self.score = 0 self.time = 0 self.frame = 0 self.fps = 0 self.combo = 0 self.life = 3 self.music = None self.music_timer = 0 def setup(self): self.background = SpriteList() self.sky_list = SpriteList() self.particule_list = SpriteList() self.ship_list = SpriteList() self.score_list = SpriteList() self.life_list = SpriteList() # Set up lane 1 ship_texture = [] for i in range(6): ship_texture.append( load_texture(f"qs../ressources/E_Run_{i+1}.png") ) ship = Sprite("../ressources/E_Run_1.png", center_x=SCREEN_WIDTH//10, center_y=SCREEN_HEIGHT//2, scale= 2) self.ship = ship self.ship_list.append(ship) for tier in range(3): background = Background("../ressources/E_Sky_1.png", SCREEN_WIDTH) background.center_y = ((SCREEN_HEIGHT // 3) * tier + 1) + 100 background.center_x = SCREEN_WIDTH // 2 background.change_x = - 2 self.background.append(background) background = Background("../ressources/E_Sky_1.png", SCREEN_WIDTH) background.center_y = ((SCREEN_HEIGHT // 3) * tier + 1) + 100 background.center_x = SCREEN_WIDTH + SCREEN_WIDTH // 2 background.change_x = - 2 self.background.append(background) for tier in range(3): sky = Background("../ressources/E_Sky_2.png", SCREEN_WIDTH) sky.center_y = ((SCREEN_HEIGHT // 3) * tier + 1) + 100 sky.center_x = SCREEN_WIDTH // 2 sky.change_x = - 6 self.sky_list.append(sky) sky = Background("./ressources/E_Sky_2.png", SCREEN_WIDTH) sky.center_y = ((SCREEN_HEIGHT // 3) * tier + 1) + 100 sky.center_x = SCREEN_WIDTH + SCREEN_WIDTH // 2 sky.change_x = - 6 self.sky_list.append(sky) # Set up life system self.life = 3 life_pos = [SCREEN_WIDTH // 2 + 40, SCREEN_HEIGHT - 30] for life_sprite in range(self.life): self.life_list.append(Sprite("../ressources/Life_Orb.png", center_x=life_pos[0], center_y=life_pos[1])) life_pos[0] += 40 # Set up Combo and Score and difficulty self.score_list.append(Sprite("../ressources/Score_Box.png", center_x=700, center_y=560, scale=1.2)) self.score = 0 self.combo = 0 self.time = 0 self.frame = 0 self.fps = 0 def on_draw(self): """ Function to draw the game (on_draw) """ start_render() # Draw all the sprites (order determine Z axis) self.sky_list.draw(filter=GL_NEAREST) self.background.draw(filter=GL_NEAREST) self.particule_list.draw(filter=GL_NEAREST) self.ship_list.draw(filter=GL_NEAREST) self.score_list.draw(filter=GL_NEAREST) self.life_list.draw(filter=GL_NEAREST) # Put the text on the screen. output = f"{self.score}" draw_text(output, 693, 560, color.DARK_RED, 15) combo = f"{self.combo}" draw_text(combo, 693, 542, color.DARK_RED, 15) # Put the fps on the bottom left fps = f"FPS: {self.fps}" draw_text(fps, 730, 10, color.YELLOW, 14) def on_key_press(self, key, modifiers): """ Called whenever a key is pressed. """ if key == arcade.key.UP: self.ship.change_y += 5 elif key == arcade.key.DOWN: self.ship.change_y -= 5 elif key == arcade.key.LEFT: self.ship.change_x -= 5 elif key == arcade.key.RIGHT: self.ship.change_x += 5 elif key == arcade.key.SPACE: particule = Sprite("../ressources/Life_Orb.png", center_x=self.ship.right, center_y=self.ship.center_y) particule.change_x = 3 self.particule_list.append(particule) def on_key_release(self, key, modifiers): """ Called whenever a key is pressed. """ if key == arcade.key.UP: self.ship.change_y = 0 elif key == arcade.key.DOWN: self.ship.change_y = 0 elif key == arcade.key.LEFT: self.ship.change_x = 0 elif key == arcade.key.RIGHT: self.ship.change_x = 0 def on_update(self, delta_time): """ Movement and game logic """ self.time += delta_time self.frame += 1 if self.time >= 1: self.fps = self.frame self.frame = 0 self.time = 0 # Update Sprite_Lists self.sky_list.update() self.background.update() self.score_list.update() self.ship_list.update() self.particule_list.update() self.life_list.update()
class QuadrantMediator(Singleton): """ This class avoids putting UI logic (arcade) in the model class, Quadrant. """ # noinspection SpellCheckingInspection def init(self, *args, **kwds): self.logger: Logger = getLogger(__name__) self._gameEngine: GameEngine = GameEngine() self._gameState: GameState = GameState() self._gameSettings: GameSettings = GameSettings() self._computer: Computer = Computer() self._intelligence: Intelligence = Intelligence() self._ktm: KlingonTorpedoMediator = KlingonTorpedoMediator() self._ctm: CommanderTorpedoMediator = CommanderTorpedoMediator() self._ptm: EnterpriseTorpedoMediator = EnterpriseTorpedoMediator() self._stm: SuperCommanderTorpedoMediator = SuperCommanderTorpedoMediator( ) self._km: KlingonMediator = KlingonMediator() self._cm: CommanderMediator = CommanderMediator() self._scm: SuperCommanderMediator = SuperCommanderMediator() self._epm: EnterprisePhaserMediator = EnterprisePhaserMediator() self._messageConsole: MessageConsole = MessageConsole() self._soundMachine: SoundMachine = SoundMachine() self._playerList: SpriteList = SpriteList() self._klingonList: SpriteList = SpriteList() self._commanderList: SpriteList = SpriteList() self._superCommanderList: SpriteList = SpriteList() @property def playerList(self) -> SpriteList: return self._playerList @playerList.setter def playerList(self, newValues: SpriteList): self._playerList = newValues @property def klingonList(self) -> SpriteList: return self._klingonList @klingonList.setter def klingonList(self, newValues: SpriteList): self._klingonList = newValues @property def commanderList(self) -> SpriteList: return self._commanderList @commanderList.setter def commanderList(self, newValues: SpriteList): self._commanderList = newValues @property def superCommanderList(self) -> SpriteList: return self._superCommanderList @superCommanderList.setter def superCommanderList(self, newValues: SpriteList): self._superCommanderList = newValues def fireEnterpriseTorpedoes(self, quadrant: Quadrant): self._ptm.fireEnterpriseTorpedoesAtKlingons(quadrant=quadrant) def firePhasers(self, quadrant: Quadrant): self._epm.firePhasers(quadrant=quadrant) def dock(self, quadrant: Quadrant): """ TODO: Move this code to a more relevant place Args: quadrant: """ if quadrant.hasStarBase is False: self._soundMachine.playSound(soundType=SoundType.UnableToComply) self._messageConsole.displayMessage(f'No Star Base in quadrant') return shipPosition: Coordinates = quadrant.enterprise.gameCoordinates basePosition: Coordinates = quadrant.starBase.gameCoordinates if self._gameEngine.shipAdjacentToBase( shipPosition=shipPosition, basePosition=basePosition) is True: self._gameState.shipCondition = ShipCondition.Docked self._gameEngine.resetEnergyLevels() self._messageConsole.displayMessage(f'Docked.') self._soundMachine.playSound(SoundType.Docked) else: self._soundMachine.playSound(SoundType.UnableToComply) self._messageConsole.displayMessage( f'You are not adjacent to base') def enterQuadrant(self, quadrant: Quadrant, enterprise): currentSectorCoordinates: Coordinates = self._intelligence.generateSectorCoordinates( ) if self._gameSettings.debugManualPlaceShipInQuadrant is True: currentSectorCoordinates = self._gameSettings.manualSectorCoordinates playerList: SpriteList = SpriteList() playerList.append(enterprise) self._gameState.currentSectorCoordinates = currentSectorCoordinates quadrant.placeEnterprise(enterprise, currentSectorCoordinates) self.playerList = playerList # Don't do this until we have set up the current quadrant self._makeEnemySpriteLists(quadrant=quadrant) self._doDebugActions(quadrant=quadrant) # noinspection PyUnusedLocal def handleMousePress(self, quadrant: Quadrant, arcadePoint: ArcadePoint, button: int, keyModifiers: int): pass def draw(self, quadrant: Quadrant): self.playerList.draw() self.klingonList.draw() self.commanderList.draw() self.superCommanderList.draw() self._ktm.draw() self._ctm.draw() self._stm.draw() self._ptm.draw(quadrant=quadrant) self._epm.draw(quadrant=quadrant) if quadrant.hasPlanet is True: quadrant.planet.draw() if quadrant.hasStarBase is True: quadrant.starBase.draw() def update(self, quadrant: Quadrant): if self.logger.getEffectiveLevel() == DEBUG: self.logger.debug(f'{quadrant.enterpriseCoordinates=}') if quadrant.klingonCount > 0: self.logger.debug(f'{quadrant.klingonCount=}') self._updateQuadrant(quadrant) self.playerList.update() self._ktm.update(quadrant=quadrant) self._ctm.update(quadrant=quadrant) self._ptm.update(quadrant=quadrant) self._stm.update(quadrant=quadrant) self._epm.update(quadrant=quadrant) def _updateQuadrant(self, quadrant): for y in range(QUADRANT_ROWS): for x in range(QUADRANT_COLUMNS): sector: Sector = quadrant.getSector(Coordinates(x, y)) self.logger.debug(f'{sector}') gamePiece: GamePiece = sector.sprite sectorType: SectorType = sector.type if sectorType != SectorType.EMPTY: if sectorType == SectorType.KLINGON: self._km.update(quadrant=quadrant, klingon=cast(Klingon, gamePiece)) elif self._noUpdateSector(sectorType=sectorType) is True: pass elif sectorType == SectorType.COMMANDER: self._cm.update(quadrant=quadrant, commander=cast(Commander, gamePiece)) elif sectorType == sectorType.SUPER_COMMANDER: self._scm.update(quadrant=quadrant, superCommander=cast( SuperCommander, gamePiece)) else: assert False, 'Bad Game Piece' def _noUpdateSector(self, sectorType: SectorType) -> bool: """ Some sector have sprites that do not move or are transient and handled by the mediators; Args: sectorType: Returns: True for the mediator handled sectors or for static sprites """ ans: bool = False if sectorType == SectorType.PLANET or sectorType == SectorType.KLINGON_TORPEDO_MISS or \ sectorType == SectorType.ENTERPRISE_TORPEDO_MISS or sectorType == SectorType.STARBASE or \ sectorType == SectorType.ENTERPRISE: ans = True return ans def _makeEnemySpriteLists(self, quadrant: Quadrant): """ Place enemies in the appropriate sprite lists Depends on the correct quadrant mediator is in place """ self.__makeKlingonSpriteList(quadrant=quadrant) self.__makeCommanderSpriteList(quadrant=quadrant) self.__makeSuperCommanderSpriteList(quadrant=quadrant) def _doDebugActions(self, quadrant: Quadrant): self.__doEnemyDebugActions(quadrant=quadrant) if self._gameSettings.debugAddPlanet is True: quadrant.addPlanet() if self._gameSettings.debugAddStarBase is True: quadrant.addStarBase() def __makeKlingonSpriteList(self, quadrant: Quadrant): if quadrant.klingonCount > 0: self._gameState.shipCondition = ShipCondition.Red klingonSprites: SpriteList = SpriteList() for klingon in quadrant.klingons: klingonSprites.append(klingon) self.klingonList = klingonSprites else: self.klingonList = SpriteList() def __makeCommanderSpriteList(self, quadrant: Quadrant): if quadrant.commanderCount > 0: self._gameState.shipCondition = ShipCondition.Red commanderSprites: SpriteList = SpriteList() for commander in quadrant.commanders: commanderSprites.append(commander) self.commanderList = commanderSprites else: self.commanderList = SpriteList() def __makeSuperCommanderSpriteList(self, quadrant: Quadrant): if quadrant.superCommanderCount > 0: self._gameState.shipCondition = ShipCondition.Red superCommanderSprites: SpriteList = SpriteList() for superCommander in quadrant.superCommanders: superCommanderSprites.append(superCommander) self.superCommanderList = superCommanderSprites else: self.superCommanderList = SpriteList() def __doEnemyDebugActions(self, quadrant: Quadrant): if self._gameSettings.debugAddKlingons is True: numKlingons: int = self._gameSettings.debugKlingonCount for x in range(numKlingons): klingon: Klingon = quadrant.addKlingon() self.klingonList.append(klingon) self._gameState.remainingKlingons += numKlingons if self._gameSettings.debugAddCommanders is True: nCommanders: int = self._gameSettings.debugCommanderCount for x in range(nCommanders): commander: Commander = quadrant.addCommander() self.commanderList.append(commander) self._gameState.remainingCommanders += nCommanders if self._gameSettings.debugAddSuperCommanders: nSuperCommanders: int = self._gameSettings.debugSuperCommanderCount for x in range(nSuperCommanders): superCommander: SuperCommander = quadrant.addSuperCommander() self.superCommanderList.append(superCommander) self._gameState.remainingSuperCommanders += nSuperCommanders
class Game(LoadableWindowView, UiBundlesHandler, EventsCreator): """This is an actual Game-instance, created when player starts the game.""" instance: Optional[Game] = None def __init__(self, loader: Optional[Generator] = None): LoadableWindowView.__init__(self, loader) UiBundlesHandler.__init__(self) EventsCreator.__init__(self) self.assign_reference_to_self_for_all_classes() self.generate_random_entities = self.loader is None self.configs = self.window.configs self.settings = self.window.settings # shared with Window class self.timer = { 'start': time.time(), 'total': 0, 'f': 0, 's': 0, 'm': 0, 'h': 0 } self.dialog: Optional[Tuple[str, Color, Color]] = None # SpriteLists: self.terrain_tiles = SpriteListWithSwitch(is_static=True, update_on=False) self.vehicles_threads = SpriteList(is_static=True) self.units_ordered_destinations = UnitsOrderedDestinations() self.units = SelectiveSpriteList() self.static_objects = SpriteListWithSwitch(is_static=True, update_on=False) self.buildings = SelectiveSpriteList(is_static=True) self.effects = SpriteList(is_static=True) self.selection_markers_sprites = SpriteList() self.interface: UiSpriteList() = self.create_user_interface() self.set_updated_and_drawn_lists() self.events_scheduler = EventsScheduler() self.map: Optional[Map] = None self.pathfinder: Optional[Pathfinder] = None self.fog_of_war: Optional[FogOfWar] = None self.scenario_editor = None # All GameObjects are initialized by the specialised factory: self.spawner: Optional[GameObjectsSpawner] = None self.explosions_pool: Optional[ExplosionsPool] = None self.mini_map: Optional[MiniMap] = None # Units belongs to the Players, Players belongs to the Factions, which # are updated each frame to evaluate AI, enemies-visibility, etc. self.factions: Dict[int, Faction] = {} self.players: Dict[int, Player] = {} self.local_human_player: Optional[Player] = None # We only draw those Units and Buildings, which are 'known" to the # local human Player's Faction or belong to it, the rest of entities # is hidden. This set is updated each frame: self.local_drawn_units_and_buildings: Set[PlayerEntity] = set() self.units_manager: UnitsManager = self.window.cursor.units_manager self.current_mission: Optional[Mission] = None self.debugger: Optional[GameDebugger] = None # list used only when Game is randomly-generated: self.things_to_load = [ ['map', Map, 0.35, {'rows': ROWS, 'columns': COLUMNS, 'grid_width': TILE_WIDTH, 'grid_height': TILE_HEIGHT}], ['pathfinder', Pathfinder, 0.05, lambda: self.map], ['fog_of_war', FogOfWar, 0.15], ['spawner', GameObjectsSpawner, 0.05], ['explosions_pool', ExplosionsPool, 0.10], ['mini_map', MiniMap, 0.15, ((SCREEN_WIDTH, SCREEN_HEIGHT), (MINIMAP_WIDTH, MINIMAP_HEIGHT), (TILE_WIDTH, TILE_HEIGHT), ROWS)], ['debugger', GameDebugger if self.settings.debug else None, 0.10] ] if self.loader is None else [] def assign_reference_to_self_for_all_classes(self): game = self.__class__.__name__.lower() for _class in (c for c in globals().values() if hasattr(c, game)): setattr(_class, game, self) Game.instance = self.window.cursor.game = self def create_user_interface(self) -> UiSpriteList: ui_x, ui_y = SCREEN_WIDTH * 0.9, SCREEN_Y ui_size = SCREEN_WIDTH // 5, SCREEN_HEIGHT frame = Frame('ui_right_panel.png', ui_x, ui_y, *ui_size) options_panel = UiElementsBundle( name=BASIC_UI, index=0, elements=[ frame, Button('game_button_menu.png', ui_x + 100, 120, functions=partial(self.window.show_view, self.window.menu_view), parent=frame), Button('game_button_save.png', ui_x, 120, functions=self.window.open_saving_menu, parent=frame), Button('game_button_pause.png', ui_x - 100, 120, functions=partial(self.toggle_pause), parent=frame) ], register_to=self ) units_panel = UiElementsBundle( name=UNITS_PANEL, index=1, elements=[ Button('game_button_stop.png', ui_x - 100, 800, functions=self.stop_all_units), Button('game_button_attack.png', ui_x, 800, functions=partial(self.window.cursor.force_cursor, 2)) ], register_to=self ) buildings_panel = UiElementsBundle( name=BUILDINGS_PANEL, index=2, elements=[], register_to=self ) return self.ui_elements_spritelist # UiBundlesHandler attribute def update_interface_position(self, right, top): diff_x = right - self.interface[0].right diff_y = top - self.interface[0].top self.interface.move(diff_x, diff_y) self.update_not_displayed_bundles_positions(diff_x, diff_y) self.mini_map.update_position(diff_x, diff_y) def update_interface_content(self, context=None): """ Change elements displayed in interface to proper for currently selected gameobjects giving player access to context-options. """ self._unload_all(exceptions=[BASIC_UI, EDITOR]) if context: if isinstance(context, Building): self.configure_building_interface(context) else: self.configure_units_interface(context) def configure_building_interface(self, context_building: Building): self.load_bundle(name=BUILDINGS_PANEL) if context_building.is_units_producer: for i, produced in enumerate(context_building.produced_units): print(produced) @ignore_in_editor_mode def configure_units_interface(self, context_units: List[Unit]): self.load_bundle(name=UNITS_PANEL) def create_effect(self, effect_type: Any, name: str, x, y): """ Add animated sprite to the self.effects spritelist to display e.g.: explosions. """ if effect_type == Explosion: effect = self.explosions_pool.get(name, x, y) else: return self.effects.append(effect) effect.play() def on_show_view(self): super().on_show_view() self.load_timer(self.timer) self.window.toggle_mouse_and_keyboard(True) self.window.sound_player.play_playlist('game') self.update_interface_content() def generate_random_map_objects(self): if self.generate_random_entities: self.test_scheduling_events() self.test_factions_and_players_creation() self.test_buildings_spawning() self.test_units_spawning() self.test_missions() if self.settings.editor_mode: self.scenario_editor = ScenarioEditor(SCREEN_WIDTH * 0.9, SCREEN_Y) position = average_position_of_points_group( [u.position for u in self.local_human_player.units] ) self.window.move_viewport_to_the_position(*position) self.update_interface_position(self.viewport[1], self.viewport[-1]) def test_scheduling_events(self): event = ScheduledEvent(self, 5, self.scheduling_test, repeat=True) self.schedule_event(event) def test_factions_and_players_creation(self): faction = Faction(name='Freemen') player = Player(id=2, color=RED, faction=faction) cpu_player = CpuPlayer(color=GREEN) self.local_human_player: Optional[Player] = self.players[2] player.start_war_with(cpu_player) def test_buildings_spawning(self): self.buildings.append(self.spawn( 'medium_factory.png', self.players[2], (400, 600), )) def spawn(self, object_name: str, player: Union[Player, int], position: Point, id: Optional[int] = None) -> Optional[GameObject]: if (player := self.get_player_instance(player)) is not None: return self.spawner.spawn(object_name, player, position, id=id) return None
class Player(arcade.Sprite): ''' Player Class ''' def __init__(self): # Set up parent class super().__init__() self.name = 'Player' self.goto_x = 0 self.goto_y = 0 # Default to face-right self.character_face_direction = RIGHT_FACING # Used for flipping between image sequences self.cur_texture = 0 self.scale = SPRITE_SCALING self.Z_INDEX = 0 # --- Load Textures --- # Images from Kenney.nl's Asset Pack 3 # kenney_path = ":resources:images/animated_characters/" # main_path = f"{kenney_path}female_adventurer/femaleAdventurer" # main_path = f"{kenney_path}female_person/femalePerson" # main_path = f"{kenney_path}male_person/malePerson" # main_path = f"{kenney_path}male_adventurer/maleAdventurer" # main_path = f"{kenney_path}zombie/zombie" # main_path = f"{kenney_path}robot/robot" # Load textures for idle standing self.run_texture_pair = load_texture_pair(path['img'] / "6.png") # Load textures for walking self.run_textures = [] for i in range(1, 15): texture = load_texture_pair(path['img'] / f"{i}.png") self.run_textures.append(texture) # Set the initial texture self.texture = self.run_texture_pair[0] # Hit box will be set based on the first image used. # If you want to specify # a different hit box, you can do it like the code below. # self.set_hit_box([[-22, -64], [22, -64], [22, 28], [-22, 28]]) # self.set_hit_box(self.texture.hit_box_points) def update_animation(self, delta_time): # Figure out if we need to flip face left or right if self.change_x < 0 and self.character_face_direction == RIGHT_FACING: self.character_face_direction = LEFT_FACING elif ( self.change_x > 0 and self.character_face_direction == LEFT_FACING ): self.character_face_direction = RIGHT_FACING # Idle animation if self.change_x == 0 and self.change_y == 0: self.texture = self.run_texture_pair[self.character_face_direction] return # Walking animation self.cur_texture += 1 if self.cur_texture > 13 * UPDATES_PER_FRAME: self.cur_texture = 0 frames = self.cur_texture // UPDATES_PER_FRAME self.texture = self.run_textures[frames][self.character_face_direction] def on_update(self, delta_time): self.center_x += self.change_x*delta_time self.center_y += self.change_y*delta_time # THIS CODE PREVENTS MOVING OFF SCREEN # if self.left < 50: # self.left = 50 # elif self.right > SCREEN_WIDTH - 50: # self.right = SCREEN_WIDTH - 50 if self.bottom < 150: self.bottom = 150 # elif self.top > SCREEN_HEIGHT - 50: # self.top = SCREEN_HEIGHT - 50 pad = 5 # Padding to detect player close to the goto position if ( self.goto_x in range( int(self.center_x-pad), int(self.center_x+pad)) and self.goto_y in range( int(self.bottom-pad), int(self.bottom)+pad) ): # If character near the goto position, stop the character self.change_x = 0 self.change_y = 0 if DEBUG: print( f"goto:{self.goto_x, self.goto_y} " f"center:{int(self.center_x),int(self.center_y)}\n" f"x:{self.change_x} y:{self.change_y}" ) def draw(self, **kwargs): """ Draw the sprite. """ if self._sprite_list is None: from arcade import SpriteList self._sprite_list = SpriteList() self._sprite_list.append(self) self._sprite_list.draw(**kwargs)
class SpriteManager(object): def __init__(self): self.player_ships = None self.enemy_ships = None self.player_base = None self.enemy_base = None self.explosions_list = None self.player_benefit = 0 self.enemy_benefit = 0 self.player_idle = 0 self.explosion_texture = load_texture(EXPLOSION_PIC) def setup(self): self.player_ships = SpriteList() self.enemy_ships = SpriteList() self.explosions_list = SpriteList() self.player_base = Base(PLAYER_BASE_POSITION_X, PLAYER_BASE_POSITION_Y, PLAYER_BAR_POSITION_X, PLAYER_BAR_POSITION_Y) self.enemy_base = Base(ENEMY_BASE_POSITION_X, ENEMY_BASE_POSITION_Y, ENEMY_BAR_POSITION_X, ENEMY_BAR_POSITION_Y) def draw_sprites(self): self.explosions_list.draw() self.player_ships.draw() self.enemy_ships.draw() self.player_base.draw() self.enemy_base.draw() def add_ship(self, fighter): self.player_idle = 0 self.player_ships.append(fighter) def update(self, delta_time): self.player_idle += delta_time self.explosions_list.update() self.player_ships.update() self.enemy_ships.update() self.player_base.update() self.enemy_base.update() self.check_ships(self.player_ships) self.check_ships(self.enemy_ships) self.check_collisions(self.player_ships, self.enemy_base) self.check_collisions(self.enemy_ships, self.player_base) self.make_fights() def player_fight_benefit(self) -> int: player_benefit = self.player_benefit self.player_benefit = 0 return player_benefit def enemy_fight_benefit(self) -> int: enemy_benefit = self.enemy_benefit self.enemy_benefit = 0 return enemy_benefit def make_fights(self): for player_ship in self.player_ships: enemy_ships = check_for_collision_with_list( player_ship, self.enemy_ships) for enemy_ship in enemy_ships: while player_ship.get_hp() > 0 and enemy_ship.get_hp() > 0: player_ship.get_damage(player_ship.blow_damage + enemy_ship.make_damage()) enemy_ship.get_damage(enemy_ship.blow_damage + player_ship.make_damage()) explosion = Explosion(self.explosion_texture) explosion.center_x = (player_ship.center_x + enemy_ship.center_x) / 2 explosion.center_y = player_ship.center_y explosion.update() self.explosions_list.append(explosion) if player_ship.get_hp() <= 0: player_ship.remove_from_sprite_lists() if enemy_ship.get_hp() <= 0: enemy_ship.remove_from_sprite_lists() if enemy_ship.get_hp() < player_ship.get_hp(): self.player_benefit += (1.5 * MONEY_COEFFICIENT - player_ship.cost) /\ MONEY_COEFFICIENT * enemy_ship.cost else: self.enemy_benefit += (1.5 * MONEY_COEFFICIENT - enemy_ship.cost) /\ MONEY_COEFFICIENT * player_ship.cost def check_collisions(self, ships, base: Sprite): for ship in ships: if check_for_collision(ship, base): base.damage(ship.make_damage()) explosion = Explosion(self.explosion_texture) explosion.center_x = base.center_x explosion.center_y = base.center_y explosion.update() self.explosions_list.append(explosion) ship.remove_from_sprite_lists() def check_ships(self, ships): for ship in ships: if ship.get_hp() <= 0: explosion = Explosion(ship.dying_sprite) explosion.center_x = ship.center_x explosion.center_y = ship.center_y explosion.update() self.explosions_list.append(explosion) ship.remove_from_sprite_lists() def add_enemy_ship(self, ship): ship.side = 'enemy' ship.center_x = ENEMY_LOCATION_X ship.center_y = ENEMY_LOCATION_Y ship.change_x = -FIGHTERS_SPEED self.enemy_ships.append(ship) def game_state(self): if self.player_idle > PLAYER_IDLE: return PLAYER_IDLE_NUMBER diff = self.enemy_base.hp - self.player_base.hp return diff + self.estimate_force( self.enemy_ships) - self.estimate_force(self.player_ships) def estimate_force(self, ships): result = 0 for ship in ships: result += ship.cost / COST_COEFFICIENT + ship.get_hp( ) / HP_COEFFICIENT return result def check_end_game(self): if self.player_base.hp <= 0: return 1 elif self.enemy_base.hp <= 0: return 2 return 0
class MyGame(arcade.View): """ Main application class. """ def __init__(self, level: int = 1): super().__init__() self.score: int = 0 self.level = level # These are 'lists' that keep track of our sprites. Each sprite should # go into a list. self.wall_list = None self.wall_counter = 0 self.bg_list = None self.answer_sprites = None self.sky_scraper_sprites = None # Separate variable that holds the player sprite self.player_sprite = None self.ui_manager = UIManager() # Our physics engine self.physics_engine = None # Used to keep track of our scrolling self.view_bottom = 0 self.view_left = 0 self.is_dead = False self.won = False self.sound = arcade.Sound("sound_files/dying2.mp3", True) # keeps track of the player sprite's location from previous frame self.player_last_x = 0 # Initialize equations self.equations: List[Equation] = None # First is current # Load sounds self.collect_coin_sound = arcade.load_sound( ":resources:sounds/coin1.wav") self.jump_sound = arcade.load_sound(":resources:sounds/jump1.wav") self.courage_sound = arcade.load_sound( "sound_files/courage screech.mp3") self.dying_sound_1 = arcade.load_sound("sound_files/dying1.mp3") self.dying_sound_2 = arcade.load_sound("sound_files/dying2.mp3") self.music1 = arcade.load_sound("sound_files/music1.mp3") arcade.set_background_color(arcade.csscolor.CORNFLOWER_BLUE) self.setup() def setup(self): self.is_dead = False """ Set up the game here. Call this function to restart the game. """ self.sky_scraper_sprites = SpriteList() self.answer_sprites = SpriteList() self.equations = [] for i in range(3): self.equations.append(Equation(self.level)) # Used to keep track of our scrolling self.view_bottom = 0 self.view_left = 0 # Create the Sprite lists self.wall_list = arcade.SpriteList() self.bg_list = Background(PLAYER_MOVEMENT_SPEED, self.level) # Set up the player, specifically placing it at these coordinates. image_source = "assets-target/pixelbird2/" self.player_sprite = Bird(image_source, CHARACTER_SCALING) self.player_sprite.center_x = 250 self.player_sprite.center_y = SCREEN_HEIGHT // 2 self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED # Load in walls (invisible) self.wall_list = SpriteList() wall_offset = STARTING_X_OFFSET + 830 create_wall_list = lambda x_offset=0: [ Sprite("stoneMid.png", scale=TILE_SCALING, center_x=wall_offset + x_offset, center_y=SCREEN_HEIGHT // 2 - 100), Sprite("stoneMid.png", scale=TILE_SCALING, center_x=wall_offset + x_offset, center_y=SCREEN_HEIGHT // 2 + 100), ] self.wall_list.extend(create_wall_list()) self.wall_list.extend(create_wall_list(1250)) ys = [116, 316, 516] values = self.equations[0].answers for i in range(3): answer = Answer(COIN_SCALING) answer.center_x = 920 + STARTING_X_OFFSET answer.center_y = ys[i] answer.set_number(values[i]) self.answer_sprites.append(answer) # create the sky scrapers center_x = STARTING_X_OFFSET + 920 - 1250 * 2 center_y = SCREEN_HEIGHT // 2 print([e.answers for e in self.equations]) for i in range(3): values = self.equations[(i - 1) % len(self.equations)].answers sky_scraper = SkyScraper(values, id=self.wall_counter) self.wall_counter += 1 sky_scraper.center_x = center_x sky_scraper.center_y = center_y center_x = sky_scraper.move_forward() print("hello!") self.sky_scraper_sprites.append(sky_scraper) print("sky_scraper_sprites", len(self.sky_scraper_sprites)) if i == 0: # make the first invisible temporarily so it doesn't get in the way sky_scraper.scale = 0 # Create the 'physics engine' self.physics_engine = arcade.PhysicsEnginePlatformer( self.player_sprite, self.wall_list, 0) def on_draw(self): """ Render the screen. """ # Clear the screen to the background color arcade.start_render() # Draw our sprites # self.wall_list.draw() # invisible # self.answer_sprites.draw() # invisible self.bg_list.draw() self.sky_scraper_sprites.draw() self.player_sprite.draw() self.draw_stats() w = 200 h = 60 arcade.draw_xywh_rectangle_filled(SCREEN_WIDTH // 2 - w // 2 + self.view_left, SCREEN_HEIGHT - h, width=w, height=h, color=arcade.color.BLACK) arcade.draw_text(self.equations[0].equationUnsolved(), self.view_left + SCREEN_WIDTH // 2, 600 + self.view_bottom, arcade.csscolor.WHITE, 18, anchor_x="center") def on_key_press(self, key, modifiers): """Called whenever a key is pressed. """ if key == arcade.key.UP or key == arcade.key.W: self.player_sprite.change_y = PLAYER_MOVEMENT_SPEED elif key == arcade.key.DOWN or key == arcade.key.S: self.player_sprite.change_y = -PLAYER_MOVEMENT_SPEED # elif key == arcade.key.LEFT: # self.player_sprite.change_x = -PLAYER_MOVEMENT_SPEED # elif key == arcade.key.RIGHT: # self.player_sprite.change_x = PLAYER_MOVEMENT_SPEED def on_key_release(self, key, modifiers): """Called when the user releases a key. """ if key == arcade.key.UP or key == arcade.key.W: self.player_sprite.change_y = 0 elif key == arcade.key.DOWN or key == arcade.key.S: self.player_sprite.change_y = 0 # elif key == arcade.key.LEFT: # self.player_sprite.change_x = 0 # elif key == arcade.key.RIGHT: # self.player_sprite.change_x = 0 def on_update(self, delta_time: float): # --- Manage Animations --- self.player_sprite.on_update(delta_time) def update(self, delta_time): if self.is_dead: print("CANCEELED") return """ Movement and game logic """ # Stop the player from leaving the screen if self.player_sprite.center_y > 600: self.player_sprite.change_y = 0 self.player_sprite.center_y = 599 elif self.player_sprite.center_y < 25: self.player_sprite.change_y = 0 self.player_sprite.center_y = 26 # record the player's last location to get their true speed self.player_last_x = self.player_sprite.center_x # Move the player with the physics engine self.physics_engine.update() # get player's speed and update backgrounds player_speed = self.player_sprite.center_x - self.player_last_x self.bg_list.update(player_speed, self.player_sprite.center_x) # --- Manage Scrolling --- changed = False # Scroll left left_boundary = self.view_left + LEFT_VIEWPORT_MARGIN if self.player_sprite.left < left_boundary: self.view_left -= left_boundary - self.player_sprite.left changed = True # Scroll right right_boundary = self.view_left + SCREEN_WIDTH - RIGHT_VIEWPORT_MARGIN if self.player_sprite.right > right_boundary: self.view_left += self.player_sprite.right - right_boundary changed = True if changed: # Only scroll to integers. Otherwise we end up with pixels that # don't line up on the screen self.view_bottom = int(self.view_bottom) self.view_left = int(self.view_left) # Do the scrolling arcade.set_viewport(self.view_left, SCREEN_WIDTH + self.view_left, self.view_bottom, SCREEN_HEIGHT + self.view_bottom) for wall in self.wall_list: if wall.center_x < self.player_sprite.center_x - 500: wall.center_x += 1250 # if self.won: # arcade.play_sound(self.courage_sound) # time.sleep(1) # new_view = game_won.GameWon() # self.window.show_view(new_view) # if wall.center_x < self.player_sprite.center_x - 500: # wall.center_x += 2500 # manage threads for i in range(len(self.sky_scraper_sprites)): ss: SkyScraper = self.sky_scraper_sprites[i] if not ss.thread.is_alive() and not ss.loaded: ss.load_image() current_equation = self.equations[0] closest_sprite: Sprite = arcade.get_closest_sprite( self.player_sprite, self.answer_sprites)[0] if type(closest_sprite ) == Answer and self.player_sprite.left > closest_sprite.left: answer: Answer = closest_sprite # player hit the correct answer if answer.get_number() == current_equation.answer: self.score += 1 # Reset the equation and answers self.get_new_equation() current_equation = self.equations[0] else: self.kill_bird() # move answers values = current_equation.answers for i in range(len(self.answer_sprites)): a: Answer = self.answer_sprites[i] a.center_x += 1250 value = values[i] a.set_number(value) a.is_correct = current_equation.answer == value if len(self.sky_scraper_sprites) == 3: sprite: SkyScraper = self.sky_scraper_sprites.pop(0) center = (sprite.center_x, sprite.center_y) print("reloading", [e.answers for e in self.equations]) new_sprite = SkyScraper(self.equations[1].answers, id=self.wall_counter) self.wall_counter += 1 new_sprite.center_x = center[0] new_sprite.center_y = center[1] new_sprite.move_forward(how_many=3) self.sky_scraper_sprites.append(new_sprite) # bird death detection if player_speed == 0: print("Bird hit the wall") self.kill_bird() def kill_bird(self): self.is_dead = True print("Bird died") arcade.play_sound(self.dying_sound_2) self.tear_down(self.sky_scraper_sprites) self.tear_down(self.answer_sprites) self.tear_down(self.wall_list) new_view = game_over.GameOver(self, self.score) self.window.show_view(new_view) def tear_down(self, sprite_list: SpriteList): for i in range(len(sprite_list)): sprite = sprite_list.pop() sprite.scale = 0 def draw_stats(self): start_x = SCREEN_WIDTH + self.view_left start_y = SCREEN_HEIGHT font_size = 20 if self.score > 0: number_width = math.floor(math.log10(self.score) + 1) * font_size else: number_width = 1 * font_size arcade.draw_xywh_rectangle_filled(start_x - number_width, start_y - 100, width=100, height=100, color=arcade.color.BLACK) arcade.draw_text(str(self.score), start_x, start_y, arcade.color.WHITE, font_size, anchor_x="right", anchor_y="top") def get_new_equation(self): self.equations.pop(0) self.equations.append(Equation(self.level)) print("get_new_equation", [e.answers for e in self.equations])
class UIManager(EventDispatcher): def __init__(self, window: Window, *args, **kwargs): super().__init__() self.window: Window = window self._focused_element: Optional[UIElement] = None self._hovered_element: Optional[UIElement] = None self._ui_elements: SpriteList = SpriteList(use_spatial_hash=True) self._id_cache: Dict[str, UIElement] = {} self.register_event_type('on_ui_event') # self.window.push_handlers(self) # Not as explicit as following self.window.push_handlers( self.on_draw, self.on_mouse_press, self.on_mouse_release, self.on_mouse_scroll, self.on_mouse_motion, self.on_key_press, self.on_key_release, self.on_text, self.on_text_motion, self.on_text_motion_select, ) @property def focused_element(self): return self._focused_element @focused_element.setter def focused_element(self, new_focus: UIElement): if self._focused_element is not None: self._focused_element.on_unfocus() self._focused_element = None if new_focus is not None: new_focus.on_focus() self._focused_element = new_focus @property def hovered_element(self): return self._hovered_element @hovered_element.setter def hovered_element(self, new_hover: UIElement): if self._hovered_element is not None: self._hovered_element.on_unhover() self._hovered_element = None if new_hover is not None: new_hover.on_hover() self._hovered_element = new_hover def purge_ui_elements(self): self._ui_elements = SpriteList() self._id_cache = {} def add_ui_element(self, ui_element: UIElement): if not hasattr(ui_element, 'id'): raise UIException( 'UIElement seems not to be properly setup, please check if you' ' overwrite the constructor and forgot "super().__init__(**kwargs)"' ) self._ui_elements.append(ui_element) ui_element.mng = self # Add elements with id to lookup if ui_element.id is not None: if ui_element.id in self._id_cache: raise UIException(f'duplicate id "{ui_element.id}"') self._id_cache[ui_element.id] = ui_element def find_by_id(self, ui_element_id: str) -> Optional[UIElement]: return self._id_cache.get(ui_element_id) def on_draw(self): self._ui_elements.draw() def disptach_ui_event(self, event: UIEvent): self.dispatch_event('on_ui_event', event) def on_ui_event(self, event: UIEvent): """ Processes UIEvents, forward events to registered elements and manages focused element """ for ui_element in self._ui_elements: ui_element = cast(UIElement, ui_element) if event.type == MOUSE_PRESS: if ui_element.collides_with_point( (event.get('x'), event.get('y'))): self.focused_element = ui_element elif ui_element is self.focused_element: # TODO does this work like expected? self.focused_element = None if event.type == MOUSE_MOTION: if ui_element.collides_with_point( (event.get('x'), event.get('y'))): self.hovered_element = ui_element elif ui_element is self.hovered_element: self.hovered_element = None ui_element.on_ui_event(event) def on_mouse_press(self, x: float, y: float, button: int, modifiers: int): self.disptach_ui_event( UIEvent(MOUSE_PRESS, x=x, y=y, button=button, modifiers=modifiers)) def on_mouse_release(self, x: float, y: float, button: int, modifiers: int): self.disptach_ui_event( UIEvent(MOUSE_RELEASE, x=x, y=y, button=button, modifiers=modifiers)) def on_mouse_scroll(self, x: int, y: int, scroll_x: int, scroll_y: int): self.disptach_ui_event( UIEvent( MOUSE_SCROLL, x=x, y=y, scroll_x=scroll_x, scroll_y=scroll_y, )) def on_mouse_motion(self, x: float, y: float, dx: float, dy: float): self.disptach_ui_event(UIEvent( MOUSE_MOTION, x=x, y=y, dx=dx, dy=dy, )) def on_key_press(self, symbol: int, modifiers: int): self.disptach_ui_event( UIEvent(KEY_PRESS, symbol=symbol, modifiers=modifiers)) def on_key_release(self, symbol: int, modifiers: int): self.disptach_ui_event( UIEvent(KEY_RELEASE, symbol=symbol, modifiers=modifiers)) def on_text(self, text): self.disptach_ui_event(UIEvent( TEXT_INPUT, text=text, )) def on_text_motion(self, motion): self.disptach_ui_event(UIEvent( TEXT_MOTION, motion=motion, )) def on_text_motion_select(self, selection): self.disptach_ui_event( UIEvent( TEXT_MOTION_SELECTION, selection=selection, ))
def __init__(self,pos: Tuple[float,float],sprite_list_owner:arcade.SpriteList,angle :float = 0): self.pos = np.array(pos,dtype=float) self.angle = angle self.sprite = self.make_sprite() sprite_list_owner.append(self.sprite)
class Game(ge.Platformer): """ Simple platformer example """ title = 'KiJogão' player_initial_tile = 4 , 1 player_class = Player game_over = False score = 0 life = 0 output_timer = 0.0 timer = 0.0 def init_world(self): self.world_color = 'yellow' self.player_initial_position = (5, 1.5) self.create_tower(12, 2, coords=(0, 1)) self.create_ground(10, coords=(0, 0), smooth_ends=False) self.create_platform(3, coords=(12,3)) self.create_platform(2, coords=(17,6)) self.create_platform(5, coords=(20,2)) self.create_platform(2, coords=(25,5)) self.create_platform(3, coords=(28,2)) self.create_platform(2, coords=(32,4)) self.create_ground(33, coords=(38, 0), smooth_ends=False) self.create_ground(2, coords=(42, 1)) #inimigo self.create_ground(2, coords=(52, 1)) self.create_ramp('up', 6, coords=(65, 1)) #self.create_platform(2, coords=(69,9)) self.create_platform(1, coords=(72,5)) self.create_platform(10, coords=(75,2)) self.create_ground(10, coords=(90, 0)) #inimigo self.create_tower(12, coords=(100, 0)) def init_enemies(self): self.enemies_list = SpriteList(is_static=True) def create_enemy(x,y): enemy = self.create_object('other/spikes/spikes-high',(x,y)) self.enemies_list.append(enemy) create_enemy(7,1) create_enemy(45,1) create_enemy(48,1) create_enemy(22,2.9) create_enemy(54,1) create_enemy(57,1) create_enemy(60,1) create_enemy(63,1) create_enemy(77,2.9) create_enemy(80,2.9) create_enemy(83,2.9) for i in range(100): create_enemy(i,-3) def init_flag(self): self.flags_list = SpriteList(is_static=True) def create_flag(x,y): flag = self.create_object('other/flag/flagRed_up',(x,y)) self.flags_list.append(flag) create_flag(94,1) def init_coins(self): self.coins_list = SpriteList() def create_coin(x,y): coin = self.create_object('other/items/yellowJewel',(x,y)) self.coins_list.append(coin) create_coin(7,4) create_coin(20,8) create_coin(12,7) create_coin(23,8) create_coin(35,7) create_coin(46,4) create_coin(49,5) create_coin(42,5) create_coin(50,5) create_coin(55,2) create_coin(57,4) create_coin(60,3) create_coin(63,5) create_coin(75,5) create_coin(77,4) create_coin(80,7) create_coin(81,3) def draw_elements(self): super().draw_elements() self.enemies_list.draw() posicaox = self.viewport_horizontal_start + 615 posicaoy = self.viewport_vertical_start +540 output = f"Pontos: {self.score}" arcade.draw_text(output,posicaox ,posicaoy - 20,arcade.color.BLACK,20) minutes = int(self.timer) // 60 seconds = int(self.timer) % 60 self.output_timer = f"Tempo: {minutes:02d}:{seconds:02d}" arcade.draw_text(self.output_timer,posicaox,posicaoy,arcade.color.BLACK,20) output_life = f"Vidas: {self.life}" arcade.draw_text(output_life,posicaox,posicaoy + 20,arcade.color.BLACK,20) if self.game_over: output_game_over = "Game Over" arcade.draw_text(output_game_over,posicaox - 240,posicaoy -300,arcade.color.BLACK,20) def update_collision(self,dt): if not self.game_over: self.enemies_list.update() if len(check_for_collision_with_list(self.player, self.enemies_list)) > 0: if self.life > 0: self.score = 0 self.life -= 1 super().player.player_initial_tile = 4, 1 super().physics_engine else: self.game_over = True self.timerend = self.output_timer arcade.draw_text(self.timerend, self.viewport_horizontal_start - 240,self.viewport_vertical_start -200 ,arcade.color.BLACK,20) print(self.timerend) if len(check_for_collision_with_list(self.player, self.flags_list)) > 0: self.timerend = self.output_timer output_win = "You Win" arcade.draw_text(output_win, self.viewport_horizontal_start - 240,self.viewport_vertical_start -200 ,arcade.color.BLACK,20) #aparecer timer, com o tempo e as vidas o timer tambem arcade.draw_text(self.timerend, self.viewport_horizontal_start - 240,self.viewport_vertical_start - 200,arcade.color.BLACK,20) print(self.timerend) if self.life == 3 : arcade.draw_text("SS", self.viewport_horizontal_start - 240,self.viewport_vertical_start - 200,arcade.color.BLACK,20) elif self.life == 2: arcade.draw_text("Ms", self.viewport_horizontal_start - 240,self.viewport_vertical_start - 200,arcade.color.BLACK,20) elif self.life <= 1: arcade.draw_text("MM", self.viewport_horizontal_start - 240,self.viewport_vertical_start - 200,arcade.color.BLACK,20) hit_coin = check_for_collision_with_list(self.player, self.coins_list) for coin in hit_coin: coin.remove_from_sprite_lists() self.score += 1 if self.score % 5 == 0: self.life += 1 if self.game_over: self.draw_elements() def update(self, dt): super().update(dt) self.update_collision(dt) self.timer += dt def init(self): self.init_world() self.init_flag() self.init_enemies() self.init_coins()
class Canvas(arcade.Window): def __init__(self, world_state: Dict[Vector, int], queue: Queue): super().__init__() self.world_state = world_state self.key_queue = queue self._sprites = SpriteList() self._obj_sprite = dict() self.score = 0 self.SCALE = 64 # shoul_update self.UPS = 60 self._last_update = 0 def create_new_sprite(self, obj): sprite = Sprite('wall.png', scale=0.5) sprite.append_texture(load_texture('box.png', scale=0.5)) sprite.append_texture(load_texture('paddle.png', scale=2)) sprite.append_texture(load_texture('ball.png', scale=0.5)) return sprite def on_key_press(self, symbol: int, modifiers: int): if symbol == arcade.key.LEFT: self.key_queue.put(-1) elif symbol == arcade.key.RIGHT: self.key_queue.put(1) elif symbol == arcade.key.DOWN: self.key_queue.put(0) elif symbol == arcade.key.SPACE: # auto play self.auto_turn() def auto_turn(self): ball = None paddle = None for vec, kind in self.world_state.items(): if kind == 4: ball = vec if kind == 3: paddle = vec if None not in (ball, paddle): break else: self.key_queue.put(0) return if paddle.x < ball.x: self.key_queue.put(1) elif paddle.x > ball.x: self.key_queue.put(-1) else: self.key_queue.put(0) def on_update(self, delta_time: float): if self.should_update(delta_time): self.auto_turn() # Update sprites and viewport for vec, kind in list(self.world_state.items()): sprite = self._obj_sprite.get(vec) if sprite is None: sprite = self.create_new_sprite(vec) self._obj_sprite[vec] = sprite self._sprites.append(sprite) if kind == 0: sprite.alpha = 0 else: sprite.alpha = 255 if kind == 1: sprite.set_texture(0) elif kind == 2: sprite.set_texture(1) elif kind == 3: sprite.set_texture(2) elif kind == 4: sprite.set_texture(3) sprite.center_x = vec.x * self.SCALE sprite.center_y = vec.y * self.SCALE self.apply_margine() def should_update(self, dt): self._last_update += dt if self._last_update > 1 / self.UPS: self._last_update = 0 return True else: return False def apply_margine(self): min_x, max_x = 0, 0 min_y, max_y = 0, 0 for sprite in self._sprites: min_x = min(sprite.center_x, min_x) max_x = max(sprite.center_x, max_x) min_y = min(sprite.center_y, min_y) max_y = max(sprite.center_y, max_y) margine = 100 self.set_viewport(min_x - margine, max_x + margine, max_y + margine, min_y - margine) def on_draw(self): arcade.start_render() self._sprites.draw()