def reload_sounds(self): """ Reload sounds :returns: None """ self.menu_select_sound = audio.load_sound( self.menu_select_sound_filename)
def animate_monster_leave(self, monster): """ :type monster: tuxemon.core.monster.Monster :return: """ sprite = self._monster_sprite_map[monster] if self.get_side(sprite.rect) == "left": x_diff = -scale(150) else: x_diff = scale(150) cry = monster.combat_call if monster.current_hp > 0 else monster.faint_call sound = audio.load_sound(cry) sound.play() self.animate(sprite.rect, x=x_diff, relative=True, duration=2)
def startup(self, **kwargs): # this task will skip the splash screen after some time self.task(self.fade_out, self.default_duration) # used to ignore keypresses after fadeout has started self.fading_out = False width, height = prepare.SCREEN_SIZE splash_border = prepare.SCREEN_SIZE[ 0] / 20 # The space between the edge of the screen # Set up the splash screen logos logo = self.load_sprite("gfx/ui/intro/pygame_logo.png") logo.rect.topleft = splash_border, height - splash_border - logo.rect.height # Set up the splash screen logos cc = self.load_sprite("gfx/ui/intro/creative_commons.png") cc.rect.topleft = width - splash_border - cc.rect.width, height - splash_border - cc.rect.height self.ding = audio.load_sound("sound_ding") self.ding.play()
def animate_capture_monster(self, is_captured, num_shakes, monster): """ Animation for capturing monsters. :param is_captured: boolean representing success of capture :param num_shakes: number of shakes before animation ends :param monster: the monster :return: """ monster_sprite = self._monster_sprite_map.get(monster, None) capdev = self.load_sprite('gfx/items/capture_device.png') animate = partial(self.animate, capdev.rect, transition='in_quad', duration=1.0) graphics.scale_sprite(capdev, .4) capdev.rect.center = scale(0), scale(0) animate(x=monster_sprite.rect.centerx) animate(y=monster_sprite.rect.centery) self.task(partial(toggle_visible, monster_sprite), 1.0) # make the monster go away temporarily def kill(): self._monster_sprite_map[monster].kill() self.hud[monster].kill() del self._monster_sprite_map[monster] del self.hud[monster] # TODO: cache this sprite from the first time it's used. # also, should loading animated sprites be more convenient? images = list() for fn in ["capture%02d.png" % i for i in range(1, 10)]: fn = 'animations/technique/' + fn image = graphics.load_and_scale(fn) images.append((image, .07)) tech = PygAnimation(images, False) sprite = Sprite() sprite.image = tech sprite.rect = tech.get_rect() self.task(tech.play, 1.0) self.task(partial(self.sprites.add, sprite), 1.0) sprite.rect.midbottom = monster_sprite.rect.midbottom def shake_ball(initial_delay): animate = partial(self.animate, duration=0.1, transition='linear', delay=initial_delay) animate(capdev.rect, y=scale(3), relative=True) animate = partial(self.animate, duration=0.2, transition='linear', delay=initial_delay + 0.1) animate(capdev.rect, y=-scale(6), relative=True) animate = partial(self.animate, duration=0.1, transition='linear', delay=initial_delay + 0.3) animate(capdev.rect, y=scale(3), relative=True) for i in range(0, num_shakes): shake_ball(1.8 + i * 1.0) # leave a 0.6s wait between each shake if is_captured: self.task(kill, 2 + num_shakes) else: breakout_delay = 1.8 + num_shakes * 1.0 self.task(partial(toggle_visible, monster_sprite), breakout_delay) # make the monster appear again! self.task( audio.load_sound(monster.combat_call).play, breakout_delay) self.task(tech.play, breakout_delay) self.task(capdev.kill, breakout_delay)
def animate_parties_in(self): # TODO: break out functions here for each left_trainer, right_trainer = self.players right_monster = right_trainer.monsters[0] surface = pygame.display.get_surface() x, y, w, h = surface.get_rect() # TODO: not hardcode this player, opponent = self.players player_home = self._layout[player]['home'][0] opp_home = self._layout[opponent]['home'][0] y_mod = scale(50) duration = 3 back_island = self.load_sprite('gfx/ui/combat/' + self.graphics['island_back'], bottom=opp_home.bottom + y_mod, right=0) if self.is_trainer_battle: enemy = self.load_sprite( 'gfx/sprites/player/' + opponent.sprite_name + '_front.png', bottom=back_island.rect.bottom - scale(12), centerx=back_island.rect.centerx) self._monster_sprite_map[opponent] = enemy else: enemy = right_monster.get_sprite("front", bottom=back_island.rect.bottom - scale(12), centerx=back_island.rect.centerx) self._monster_sprite_map[right_monster] = enemy self.monsters_in_play[opponent].append(right_monster) self.sprites.add(enemy) self.build_hud(self._layout[opponent]['hud'][0], right_monster) if self.is_trainer_battle: self.alert( T.format('combat_trainer_appeared', {"name": opponent.name.upper()})) else: self.alert( T.format('combat_wild_appeared', {"name": right_monster.name.upper()})) front_island = self.load_sprite('gfx/ui/combat/' + self.graphics['island_front'], bottom=player_home.bottom - y_mod, left=w) trainer1 = self.load_sprite( 'gfx/sprites/player/' + player.sprite_name + '_back.png', bottom=front_island.rect.centery + scale(6), centerx=front_island.rect.centerx) self._monster_sprite_map[left_trainer] = trainer1 def flip(): enemy.image = pygame.transform.flip(enemy.image, 1, 0) trainer1.image = pygame.transform.flip(trainer1.image, 1, 0) flip() # flip images to opposite self.task(flip, 1.5) # flip the images to proper direction if not self.is_trainer_battle: # the combat call is handled by fill_battlefield_positions for trainer battles self.task(audio.load_sound(right_monster.combat_call).play, 1.5) # play combat call when it turns back animate = partial(self.animate, transition='out_quad', duration=duration) # top trainer animate(enemy.rect, back_island.rect, centerx=opp_home.centerx) animate(enemy.rect, back_island.rect, y=-y_mod, transition='out_back', relative=True) # bottom trainer animate(trainer1.rect, front_island.rect, centerx=player_home.centerx) animate(trainer1.rect, front_island.rect, y=y_mod, transition='out_back', relative=True)
def animate_monster_release(self, npc, monster): """ :type npc: tuxemon.core.npc.Npc :type monster: tuxemon.core.monster.Monster :return: """ feet = list(self._layout[npc]['home'][0].center) feet[1] += tools.scale(11) capdev = self.load_sprite('gfx/items/capture_device.png') graphics.scale_sprite(capdev, .4) capdev.rect.center = feet[0], feet[1] - scale(60) # animate the capdev falling fall_time = .7 animate = partial(self.animate, duration=fall_time, transition='out_quad') animate(capdev.rect, bottom=feet[1], transition='in_back') animate(capdev, rotation=720, initial=0) # animate the capdev fading away delay = fall_time + .6 fade_duration = .9 h = capdev.rect.height animate = partial(self.animate, duration=fade_duration, delay=delay) animate(capdev, width=1, height=h * 1.5) animate(capdev.rect, y=-scale(14), relative=True) # convert the capdev sprite so we can fade it easily def func(): capdev.image = graphics.convert_alpha_to_colorkey(capdev.image) self.animate(capdev.image, set_alpha=0, initial=255, duration=fade_duration) self.task(func, delay) self.task(capdev.kill, fall_time + delay + fade_duration) # load monster and set in final position monster_sprite = monster.get_sprite( "back" if npc.isplayer else "front", midbottom=feet) self.sprites.add(monster_sprite) self._monster_sprite_map[monster] = monster_sprite # position monster_sprite off screen and set animation to move it back to final spot monster_sprite.rect.top = self.client.screen.get_height() self.animate(monster_sprite.rect, bottom=feet[1], transition='out_back', duration=.9, delay=fall_time + .5) # capdev opening animation images = list() for fn in ["capture%02d.png" % i for i in range(1, 10)]: fn = 'animations/technique/' + fn image = graphics.load_and_scale(fn) images.append((image, .07)) delay = 1.3 tech = PygAnimation(images, False) sprite = Sprite() sprite.image = tech sprite.rect = tech.get_rect() sprite.rect.midbottom = feet self.task(tech.play, delay) self.task(partial(self.sprites.add, sprite), delay) # attempt to load and queue up combat_call call_sound = audio.load_sound(monster.combat_call) if call_sound: self.task(call_sound.play, delay) # update tuxemon balls to reflect fainted tuxemon for player, layout in self._layout.items(): self.animate_update_party_hud(player, layout['party'][0])
def perform_action(self, user, technique, target=None): """ Do something with the thing: animated :param user: :param technique: Not a dict: a Technique or Item :param target: :returns: """ technique.advance_round() # This is the time, in seconds, that the animation takes to finish. action_time = 3.0 result = technique.use(user, target) if technique.use_item: # "Monster used move!" context = { "user": getattr(user, "name", ''), "name": technique.name, "target": target.name } message = T.format(technique.use_item, context) else: message = '' try: audio.load_sound(technique.sfx).play() except AttributeError: pass # action is performed, so now use sprites to animate it # this value will be None if the target is off screen target_sprite = self._monster_sprite_map.get(target, None) # slightly delay the monster shake, so technique animation # is synchronized with the damage shake motion hit_delay = 0 if user: # TODO: a real check or some params to test if should tackle, etc if result["should_tackle"]: hit_delay += .5 user_sprite = self._monster_sprite_map[user] self.animate_sprite_tackle(user_sprite) if target_sprite: self.task( partial(self.animate_sprite_take_damage, target_sprite), hit_delay + .2) self.task(partial(self.blink, target_sprite), hit_delay + .6) # TODO: track total damage # Track damage self._damage_map[target].add(user) element_damage_key = MULT_MAP.get(result['element_multiplier']) if element_damage_key: m = T.translate(element_damage_key) message += "\n" + m for status in result.get("statuses", []): m = T.format( status.use_item, { "name": technique.name, "user": status.link.name if status.link else "", "target": status.carrier.name }) message += "\n" + m else: # assume this was an item used # handle the capture device if result["capture"]: message += "\n" + T.translate('attempting_capture') action_time = result["num_shakes"] + 1.8 self.animate_capture_monster(result["success"], result["num_shakes"], target) # TODO: Don't end combat right away; only works with SP, and 1 member parties # end combat right here if result["success"]: self.task(self.end_combat, action_time + 0.5) # Display 'Gotcha!' first. self.task(partial(self.alert, T.translate('gotcha')), action_time) self._animation_in_progress = True return # generic handling of anything else else: msg_type = 'use_success' if result[ 'success'] else 'use_failure' template = getattr(technique, msg_type) if template: message += "\n" + T.translate(template) self.alert(message) self.suppress_phase_change(action_time) else: if result["success"]: self.suppress_phase_change() self.alert( T.format('combat_status_damage', { "name": target.name, "status": technique.name })) if result["success"] and target_sprite and technique.images: tech_sprite = self.get_technique_animation(technique) tech_sprite.rect.center = target_sprite.rect.center self.task(tech_sprite.image.play, hit_delay) self.task(partial(self.sprites.add, tech_sprite, layer=50), hit_delay) self.task(tech_sprite.kill, 3)
def start(self): filename = self.parameters.filename sound = audio.load_sound(filename) sound.play()