Ejemplo n.º 1
0
    def load(self):
        from tuxemon.core import prepare
        self.dpad["surface"] = graphics.load_and_scale("gfx/d-pad.png")
        self.dpad["position"] = (0, prepare.SCREEN_SIZE[1] -
                                 self.dpad["surface"].get_height())

        # Create the collision rectangle objects for the dpad so we can see if we're pressing a button
        self.dpad["rect"] = {}
        self.dpad["rect"]["up"] = Rect(
            self.dpad["position"][0] + (self.dpad["surface"].get_width() / 3),
            self.dpad["position"][1],  # Rectangle position_y
            self.dpad["surface"].get_width() / 3,  # Rectangle size_x
            self.dpad["surface"].get_height() / 2)  # Rectangle size_y
        self.dpad["rect"]["down"] = Rect(
            self.dpad["position"][0] + (self.dpad["surface"].get_width() / 3),
            self.dpad["position"][1] + (self.dpad["surface"].get_height() / 2),
            self.dpad["surface"].get_width() / 3,
            self.dpad["surface"].get_height() / 2)
        self.dpad["rect"]["left"] = Rect(
            self.dpad["position"][0],
            self.dpad["position"][1] + (self.dpad["surface"].get_height() / 3),
            self.dpad["surface"].get_width() / 2,
            self.dpad["surface"].get_height() / 3)
        self.dpad["rect"]["right"] = Rect(
            self.dpad["position"][0] + (self.dpad["surface"].get_width() / 2),
            self.dpad["position"][1] + (self.dpad["surface"].get_height() / 3),
            self.dpad["surface"].get_width() / 2,
            self.dpad["surface"].get_height() / 3)

        # Create the buttons
        self.a_button = {}
        self.a_button["surface"] = graphics.load_and_scale("gfx/a-button.png")
        self.a_button["position"] = (
            prepare.SCREEN_SIZE[0] -
            int(self.a_button["surface"].get_width() * 1.0),
            (self.dpad["position"][1] +
             (self.dpad["surface"].get_height() / 2) -
             (self.a_button["surface"].get_height() / 2)))
        self.a_button["rect"] = Rect(self.a_button["position"][0],
                                     self.a_button["position"][1],
                                     self.a_button["surface"].get_width(),
                                     self.a_button["surface"].get_height())

        self.b_button = {}
        self.b_button["surface"] = graphics.load_and_scale("gfx/b-button.png")
        self.b_button["position"] = (
            prepare.SCREEN_SIZE[0] -
            int(self.b_button["surface"].get_width() * 2.1),
            (self.dpad["position"][1] +
             (self.dpad["surface"].get_height() / 2) -
             (self.b_button["surface"].get_height() / 2)))
        self.b_button["rect"] = Rect(self.b_button["position"][0],
                                     self.b_button["position"][1],
                                     self.b_button["surface"].get_width(),
                                     self.b_button["surface"].get_height())
Ejemplo n.º 2
0
 def __init__(self, **kwargs):
     self.tray = kwargs['tray']
     self.monster = kwargs['monster']
     self.sprite = kwargs['sprite']
     self.state = kwargs['state']
     self.empty = graphics.load_and_scale(
         'gfx/ui/combat/empty_slot_icon.png')
     self.faint = graphics.load_and_scale(
         'gfx/ui/icons/party/party_icon03.png')
     self.alive = graphics.load_and_scale(
         'gfx/ui/icons/party/party_icon01.png')
     self.effected = graphics.load_and_scale(
         'gfx/ui/icons/party/party_icon02.png')
     super().__init__()
Ejemplo n.º 3
0
    def __init__(self,
                 images,
                 position,
                 animation_speed=0.2,
                 animation_loop=False):

        # Check to see what kind of image(s) are being loaded.
        images_type = type(images).__name__

        # Handle loading a single image, multiple images, or surfaces
        if images_type == 'str' or images_type == 'unicode':
            surface = graphics.load_and_scale(images)
            self.images = [(surface, animation_speed)]

        elif images_type == 'list' or images_type == 'tuple':
            self.images = []

            for item in images:
                item_type = type(item).__name__

                if item_type == 'str' or item_type == 'unicode':
                    surface = graphics.load_and_scale(images)
                else:
                    surface = item
                self.images.append((surface, animation_speed))

        else:
            surface = images
            self.images = [(surface, animation_speed)]

        # Create a pyganimation object using our loaded images.
        self.animation = pyganim.PygAnimation(self.images, loop=animation_loop)
        self.animation.play()
        self.animation.pause()

        self.rect = self.images[0][0].get_rect(topleft=position)

        self.visible = True
        self.state = ""

        self.moving = False
        self.move_destination = (0, 0)
        self.move_delta = [0, 0]
        self.move_duration = 0.
        self.move_time = 0.
        self.fading = False
        self.fade_duration = 0.
        self.shaking = False
Ejemplo n.º 4
0
    def startup(self, **kwargs):
        super(MonsterMenuState, self).startup(**kwargs)

        # make a text area to show messages
        self.text_area = TextArea(self.font, self.font_color, (96, 96, 96))
        self.text_area.rect = Rect(tools.scale_sequence([20, 80, 80, 100]))
        self.sprites.add(self.text_area, layer=100)

        # Set up the border images used for the monster slots
        self.monster_slot_border = {}
        self.monster_portrait = pygame.sprite.Sprite()
        self.hp_bar = HpBar()
        self.exp_bar = ExpBar()

        # load and scale the monster slot borders
        root = "gfx/ui/monster/"
        border_types = ["empty", "filled", "active"]
        for border_type in border_types:
            filename = root + border_type + "_monster_slot_border.png"
            border = graphics.load_and_scale(filename)

            filename = root + border_type + "_monster_slot_bg.png"
            background = graphics.load_image(filename)

            window = GraphicBox(border, background, None)
            self.monster_slot_border[border_type] = window

        # TODO: something better than this global, load_sprites stuff
        for monster in local_session.player.monsters:
            monster.load_sprites()
Ejemplo n.º 5
0
    def draw_monster_info(self, surface, monster, rect):
        # position and draw hp bar
        hp_rect = rect.copy()
        left = rect.width * .6
        right = rect.right - tools.scale(4)
        hp_rect.width = right - left
        hp_rect.left = left
        hp_rect.height = tools.scale(8)
        hp_rect.centery = rect.centery

        # draw the hp bar
        self.hp_bar.value = monster.current_hp / monster.hp
        self.hp_bar.draw(surface, hp_rect)

        # draw the name
        text_rect = rect.inflate(-tools.scale(6), -tools.scale(6))
        draw_text(surface, monster.name, text_rect, font=self.font)

        # draw the level info
        text_rect.top = rect.bottom - tools.scale(7)
        draw_text(surface,
                  "  Lv " + str(monster.level),
                  text_rect,
                  font=self.font)

        # draw any status icons
        # TODO: caching or something, idk
        # TODO: not hardcode icon sizes
        for index, status in enumerate(monster.status):
            if status.icon:
                image = graphics.load_and_scale(status.icon)
                pos = (rect.width *
                       .4) + (index * tools.scale(32)), rect.y + tools.scale(5)
                surface.blit(image, pos)
Ejemplo n.º 6
0
    def load(self, slug):
        """Loads and sets this items's attributes from the item.db database. The item is looked up
        in the database by slug.

        :param slug: The item slug to look up in the monster.item database.

        :type slug: String

        :rtype: None
        :returns: None

        **Examples:**

        >>> potion = Item()
        >>> potion.load('potion')    # Load an item by slug.
        >>> pprint.pprint(potion.__dict__)
        {
            'description': u'Heals a monster by 50 HP.',
            'effects': [u'heal'],
            'slug': 'potion',
            'name': u'potion',
            'sprite': u'resources/gfx/items/potion.png',
            'surface': <Surface(66x90x32 SW)>,
            'surface_size_original': (66, 90),
            'type': u'Consumable'
        }
        """

        try:
            results = db.lookup(slug, table="item")
        except KeyError:
            logger.error(msg="Failed to find item with slug {}".format(slug))
            return

        self.slug = results["slug"]  # short English identifier
        self.name = T.translate(self.slug)  # translated name
        self.description = T.translate("{}_description".format(
            self.slug))  # will be locale string

        # item use notifications (translated!)
        self.use_item = T.translate(results["use_item"])
        self.use_success = T.translate(results["use_success"])
        self.use_failure = T.translate(results["use_failure"])

        # misc attributes (not translated!)
        self.sort = results['sort']
        assert self.sort
        self.type = results["type"]
        self.sprite = results["sprite"]
        self.usable_in = results["usable_in"]
        self.target = process_targets(results["target"])
        self.effects = self.parse_effects(results.get("effects", []))
        self.conditions = self.parse_conditions(results.get("conditions", []))
        self.surface = graphics.load_and_scale(self.sprite)
        self.surface_size_original = self.surface.get_size()
Ejemplo n.º 7
0
    def startup(self, *args, **kwargs):
        super().startup(*args, **kwargs)

        # used to determine how player can target techniques
        self.user = kwargs.get("user")
        self.action = kwargs.get("action")
        self.player = kwargs.get("player")

        # load and scale the menu borders
        border = graphics.load_and_scale(self.borders_filename)
        self.border = GraphicBox(border, None, None)
Ejemplo n.º 8
0
    def load_sprites(self):
        """Loads the monster's sprite images as Pygame surfaces.

        :rtype: Boolean
        :returns: True if the sprites are already loaded.

        **Examples:**

        >>> bulbatux.load_sprites()
        >>> bulbatux.sprites

        """
        if len(self.sprites):
            return True

        self.sprites["front"] = graphics.load_and_scale(
            self.front_battle_sprite)
        self.sprites["back"] = graphics.load_and_scale(self.back_battle_sprite)
        self.sprites["menu"] = graphics.load_and_scale(self.menu_sprite_1)
        return False
Ejemplo n.º 9
0
    def load_graphics(self):
        """ Loads all the graphical elements of the menu
            Will load some elements from disk, so needs to be called at least once.
        """
        if not self.transparent:
            # load and scale the _background
            background = None
            if self.background_filename:
                background = graphics.load_image(self.background_filename)

            # load and scale the menu borders
            border = None
            if self.draw_borders:
                border = graphics.load_and_scale(self.borders_filename)

            # set the helper to draw the _background
            self.window = GraphicBox(border, background, self.background_color)

        # handle the arrow cursor
        image = graphics.load_and_scale(self.cursor_filename)
        self.arrow = MenuCursor(image)
Ejemplo n.º 10
0
    def load_sprites(self):
        """ Load sprite graphics

        :return:
        """
        # TODO: refactor animations into renderer
        # Get all of the player's standing animation images.
        self.standing = {}
        for standing_type in facing:
            filename = "{}_{}.png".format(self.sprite_name, standing_type)
            path = os.path.join("sprites", filename)
            self.standing[standing_type] = load_and_scale(path)

        self.playerWidth, self.playerHeight = self.standing["front"].get_size(
        )  # The player's sprite size in pixels

        # avoid cutoff frames when steps don't line up with tile movement
        frames = 3
        frame_duration = (1000 / CONFIG.player_walkrate) / frames / 1000 * 2

        # Load all of the player's sprite animations
        anim_types = ['front_walk', 'back_walk', 'left_walk', 'right_walk']
        for anim_type in anim_types:
            images = [
                'sprites/{}_{}.{}.png'.format(self.sprite_name, anim_type,
                                              str(num).rjust(3, '0'))
                for num in range(4)
            ]

            frames = []
            for image in images:
                surface = load_and_scale(image)
                frames.append((surface, frame_duration))

            self.sprite[anim_type] = pyganim.PygAnimation(frames, loop=True)

        # Have the animation objects managed by a conductor.
        # With the conductor, we can call play() and stop() on all the animation objects
        # at the same time, so that way they'll always be in sync with each other.
        self.moveConductor.add(self.sprite)
Ejemplo n.º 11
0
    def show_combat_dialog(self):
        """ Create and show the area where battle messages are displayed
        """
        # make the border and area at the bottom of the screen for messages
        x, y, w, h = self.client.screen.get_rect()
        rect = Rect(0, 0, w, h // 4)
        rect.bottomright = w, h
        border = graphics.load_and_scale(self.borders_filename)
        self.dialog_box = GraphicBox(border, None, self.background_color)
        self.dialog_box.rect = rect
        self.sprites.add(self.dialog_box, layer=100)

        # make a text area to show messages
        self.text_area = TextArea(self.font, self.font_color)
        self.text_area.rect = self.dialog_box.calc_inner_rect(self.dialog_box.rect)
        self.sprites.add(self.text_area, layer=100)
Ejemplo n.º 12
0
    def load_technique_animation(technique):
        """ Return animated sprite from a technique

        :param tuxemon.core.technique.Technique technique:
        :rtype: tuxemon.core.sprite.Sprite
        """
        if not technique.images:
            return None
        frame_time = .09
        images = list()
        for fn in technique.images:
            image = graphics.load_and_scale(fn)
            images.append((image, frame_time))
        tech = PygAnimation(images, False)
        sprite = Sprite()
        sprite.image = tech
        sprite.rect = tech.get_rect()
        return sprite
Ejemplo n.º 13
0
    def load_technique_animation(technique):
        """

        TODO: move to some generic animation loading thingy

        :param technique:
        :rtype: tuxemon.core.sprite.Sprite
        """
        frame_time = .09
        images = list()
        for fn in technique.images:
            image = graphics.load_and_scale(fn)
            images.append((image, frame_time))

        tech = PygAnimation(images, False)
        sprite = Sprite()
        sprite.image = tech
        sprite.rect = tech.get_rect()
        return sprite
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
    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])
Ejemplo n.º 16
0
 def load_graphics(self):
     """ Image become class attribute, so is shared.
         Eventually, implement some game-wide image caching
     """
     image = graphics.load_and_scale(self.border_filename)
     ExpBar.border = GraphicBox(image)