Exemplo n.º 1
0
    def __init__(self, level=None):
        '''Create a `LevelScene` object.

        '''

        # Ensure we have an appropriate level.
        if level is None:
            if app.settings.level < 0:
                level = applib.model.level.TestLevel
            else:
                level = applib.model.level.default_level
                for _ in range(app.settings.level - 1):
                    level = level.next_level
        self.level = level()
        applib.model.scenery.Counter(self.level)
        self.level.background_scenery(self.level)

        self.level.push_handlers(self)

        # Create the root interface panel.
        self.interface = applib.engine.panel.Panel(
            aspect=(16, 9),
            background_color=(255, 255, 255, 255),
        )

        self._score_ratio = self.level.get_score_ratio()

        self.bg_player = {
            applib.model.scenery.BackgroundVillage:
            applib.engine.sound.bg_mix_village,
            applib.model.scenery.BackgroundHill:
            applib.engine.sound.bg_mix_hill,
        }[self.level.background_scenery]()
        self.bg_player.volume = 0.0
        self.bg_animation = animation.AttributeAnimation(
            self.bg_player, 'volume',
            app.settings.sound_volume * app.settings.volume, 5.0).start()

        self.overlay = self.interface.add(draw_function=self.draw_overlay, )

        self.scene_fade = 1.0
        self.fade_animation = animation.ParallelAnimation(
            animation.AttributeAnimation(self, 'scene_fade', 0.0,
                                         2.0), ).start()
        self.dialogue_animation = None
        app.music.switch(None)

        self.load_level_sprites()

        self.load_dialogue_overlay()
        self.on_tick()
        self.start_scene(self.level.opening_scene)
        self.paw_animations = {}
Exemplo n.º 2
0
 def start_scene(self, name, slowly=None):
     if name is not None:
         self._stop_device_sounds()
         self.name_left.text_update(None)
         self.name_right.text_update(None)
         self.name_left.visible = False
         self.name_right.visible = False
         self.character_left.image_texture = None
         self.character_right.image_texture = None
         self.message_container.visible = False
         self.message_area.text_update(None)
         self.scene_lines = pyglet.resource.file(f'scenes/{name}.txt',
                                                 'r').readlines()
         self.dialogue_overlay.visible = True
         self.scene_ready = False
         self.scene_sound_player = None
         if slowly is not None:
             self.dialogue_overlay.background_opacity = 0.0
             self.dialogue_animation = animation.QueuedAnimation(
                 animation.AttributeAnimation(self.dialogue_overlay,
                                              'background_opacity', 0.8,
                                              slowly, 'symmetric'),
                 animation.WaitAnimation(0.3, self.advance_scene),
             ).start()
         else:
             self.advance_scene()
Exemplo n.º 3
0
 def do_show_poem(self):
     self.fade_poem = 0.05
     self.fade_width = 0.1
     self.poem_animation = animation.QueuedAnimation(
             animation.ParallelAnimation(
                 SpiralAnimation(self, 'interface_x', 'interface_y', self.interface.get_content_size()[0], 0.5 * self.interface.get_content_size()[1], 0.25 * math.pi, 1.0),
                 animation.AttributeAnimation(self, 'fade_poem', 1.0, 20.0),
             ),
             animation.WaitAnimation(10.0, self.do_start),
     ).start()
Exemplo n.º 4
0
    def __init__(self, level=None):
        
        self.interface = applib.engine.panel.Panel(
            aspect = (16, 9),
            background_color = (255, 255, 255, 0),
        )

        self.bg_textures = [
            pyglet.resource.texture('scenery/background_village.png'),
            pyglet.resource.texture('scenery/counter.png'),
        ]
        
        make_dialogue_interface(self)
        self.dialogue_overlay.visible = True

        self.scene_fade = 1.0
        animation.QueuedAnimation(
            animation.AttributeAnimation(self, 'scene_fade', 0.0, 1.0),
        ).start()
        app.music.switch(pyglet.resource.media('music/badoink_digitaldonut.mp3'))

        app.window.set_mouse_cursor(None)
        self.start_scene('credits')
Exemplo n.º 5
0
    def __init__(self):

        self.overlay = pyglet.resource.texture('overlays/burlap_256.png')

        self.logo_image = pyglet.resource.image('logos/paper_dragon_large.png')
        self.logo_image.anchor_x = self.logo_image.width // 2
        self.logo_image.anchor_y = self.logo_image.height // 2
        self.logo_sprite = pyglet.sprite.Sprite(self.logo_image)
        self.logo_sprite.x = app.window.width // 2
        self.logo_sprite.y = app.window.height // 2
        self.logo_sprite.scale = (app.window.width // 2) / self.logo_image.width
        self.logo_sprite.opacity = 0.0

        self.logo_animation = animation.QueuedAnimation(
            animation.WaitAnimation(1.0, self.do_rawr),
            animation.AttributeAnimation(self.logo_sprite, 'opacity', 255.0, 2.0, 'symmetric'),
            animation.WaitAnimation(2.0),
            animation.AttributeAnimation(self.logo_sprite, 'opacity', 0.0, 2.0),
            animation.WaitAnimation(1.0, self.end_logo),
        ).start()

        self.apple_tex = pyglet.resource.texture('items/apple.png')

        self.interface = applib.engine.panel.Panel(
            aspect = (16, 9),
            background_color = (225, 208, 183, 255),
            visible = False,
            draw_function = self.draw_apple_overlay,
        )

        self.title_image = self.interface.add(
            width = 0.4,
            height = 0.9,
            align_x = 0.25,
            align_y = 0.5,
            anchor_x = 0.5,
            anchor_y = 0.5,
            image_texture = pyglet.resource.texture('interface/title.png'),
        )

        self.title_box = self.interface.add(
            width = 0.45,
            height = 0.25,
            align_x = 0.70,
            align_y = 0.7,
            anchor_x = 0.5,
            anchor_y = 0.0,
            text = 'Copcake Caper',
            text_color = (0, 0, 0, 255),
            text_bold = True,
            font_size = 0.07,
        )

        self.play_button = self.interface.add(
            align_x = 0.70,
            align_y = 0.6,
            anchor_x = 0.5,
            anchor_y = 1.0,
            height = 0.1,
            text = 'Story',
            text_color = (0, 0, 0, 255),
            text_bold = True,
            font_size = 0.06,
        )

        self.endless_button = self.interface.add(
            align_x = 0.70,
            align_y = 0.45,
            anchor_x = 0.5,
            anchor_y = 1.0,
            height = 0.1,
            text = 'Endless',
            text_color = (0, 0, 0, 255),
            text_bold = True,
            font_size = 0.06,
        )

        self.quit_button = self.interface.add(
            align_x = 0.70,
            align_y = 0.3,
            anchor_x = 0.5,
            anchor_y = 1.0,
            height = 0.1,
            text = 'Quit',
            text_bold = True,
            text_color = (0, 0, 0, 255),
            font_size = 0.06,
        )

        self.interface_x = self.interface.get_content_size()[0] * 1.5
        self.interface_y = -self.interface.get_content_size()[1]

        self.poem = self.interface.add(
            align_x = -1.0,
            align_y = -0.5,
            anchor_x = 0.0,
            anchor_y = 0.0,
        )

        self.poem_text = self.poem.add(
            text = POEM_TEXT,
            text_color = (0, 0, 0, 255),
            font_size = 0.03,
            draw_function = self.draw_poem_overlay,
        )

        self.scene_fade = 1.0
        animation.QueuedAnimation(
            animation.AttributeAnimation(self, 'scene_fade', 0.0, 1.0),
        ).start()
Exemplo n.º 6
0
 def do_button_endless(self):
     self.scene_fade = 0.0
     animation.QueuedAnimation(
         animation.AttributeAnimation(self, 'scene_fade', 1.0, 1.0),
         animation.WaitAnimation(0.2, app.controller.switch_scene, applib.scenes.level.LevelScene, applib.model.level.EndlessLevel),
     ).start()
Exemplo n.º 7
0
 def do_button_quit(self):
     animation.QueuedAnimation(
         animation.AttributeAnimation(self, 'scene_fade', 1.0, 0.3),
         animation.WaitAnimation(0.1, pyglet.app.exit),
     ).start()
Exemplo n.º 8
0
    def advance_scene(self):
        while len(self.scene_lines) > 0:
            line = self.scene_lines.pop(0).strip()
            if len(line) == 0:
                continue
            command, value = map(str.strip, line.split(':', 1))

            if command == 'set_left_image':
                if len(value) > 0:
                    self.character_left.image_texture = pyglet.resource.texture(f'characters/{value}.png')
                else:
                    self.character_left.image_texture = None
            if command == 'set_right_image':
                if len(value) > 0:
                    self.character_right.image_texture = pyglet.resource.texture(f'characters/{value}.png')
                else:
                    self.character_right.image_texture = None

            if command == 'set_left_name':
                self.name_left.text_update(value or None)
            if command == 'set_right_name':
                self.name_right.text_update(value or None)

            if command == 'say_left':
                self.message_container.visible = bool(value)
                self.message_area.text_update(value)
                self.name_left.visible = bool(self.name_left.text)
                self.name_right.visible = False
                self.character_left.image_color = (255, 255, 255, 255)
                self.character_right.image_color = (75, 75, 75, 255)
                break
            if command == 'say_right':
                self.message_container.visible = bool(value)
                self.message_area.text_update(value)
                self.name_right.visible = bool(self.name_right.text)
                self.name_left.visible = False
                self.character_right.image_color = (255, 255, 255, 255)
                self.character_left.image_color = (75, 75, 75, 255)
                break
            if command == 'say_both':
                self.message_container.visible = bool(value)
                self.message_area.text_update(value)
                self.name_left.visible = bool(self.name_left.text)
                self.name_right.visible = bool(self.name_right.text)
                self.character_right.image_color = (255, 255, 255, 255)
                self.character_right.image_color = (255, 255, 255, 255)
                break

            if command == 'show_image':
                self.image_centre.visible = bool(value)
                self.image_centre.image_texture = pyglet.resource.texture(f'{value}.png')
                self.name_left.visible = False
                self.name_right.visible = False
                self.message_container.visible = False
                break

            if command == 'end_game':
                animation.QueuedAnimation(
                    animation.WaitAnimation(0.0, app.music.switch, None, app.music.volume / 8.0),
                    animation.AttributeAnimation(self, 'scene_fade', 1.0, 8.0),
                    animation.WaitAnimation(0.5, app.controller.switch_scene, applib.scenes.menu.MenuScene),
                ).start()
                break
Exemplo n.º 9
0
    def advance_scene(self):
        self.scene_ready = True
        format_vars = dict(sold_cakes=self.level.sold_cakes, )
        while len(self.scene_lines) > 0:
            line = self.scene_lines.pop(0).strip()
            if len(line) == 0:
                continue
            command, value = map(str.strip, line.split(':', 1))

            if command == 'set_left_image':
                if len(value) > 0:
                    self.character_left.image_texture = pyglet.resource.texture(
                        f'characters/{value}.png')
                else:
                    self.character_left.image_texture = None
            if command == 'set_right_image':
                if len(value) > 0:
                    self.character_right.image_texture = pyglet.resource.texture(
                        f'characters/{value}.png')
                else:
                    self.character_right.image_texture = None

            if command == 'set_left_name':
                self.name_left.text_update(value or None)

            if command == 'set_right_name':
                self.name_right.text_update(value or None)

            if command == 'play_sound':
                if self.scene_sound_player:
                    self.scene_sound_player.next_source()
                self.scene_sound_player = getattr(applib.engine.sound, value)()

            if command == 'say_left':
                self.message_container.visible = True
                self.message_area.text_update(value.format(**format_vars))
                self.name_left.visible = bool(self.name_left.text)
                self.name_right.visible = False
                self.character_left.image_color = (255, 255, 255, 255)
                self.character_right.image_color = (75, 75, 75, 255)
                break
            if command == 'say_right':
                self.message_container.visible = True
                self.message_area.text_update(value.format(**format_vars))
                self.name_right.visible = bool(self.name_right.text)
                self.name_left.visible = False
                self.character_right.image_color = (255, 255, 255, 255)
                self.character_left.image_color = (75, 75, 75, 255)
                break
            if command == 'say_both':
                self.message_container.visible = True
                self.message_area.text_update(value.format(**format_vars))
                self.name_left.visible = bool(self.name_left.text)
                self.name_right.visible = bool(self.name_right.text)
                self.character_right.image_color = (255, 255, 255, 255)
                self.character_right.image_color = (255, 255, 255, 255)
                break

            if command == 'next_level':
                if value:
                    next_level = getattr(applib.model.level, value)
                else:
                    next_level = self.level.next_level
                self.fade_animation = animation.QueuedAnimation(
                    animation.ParallelAnimation(
                        animation.AttributeAnimation(self.bg_player, 'volume',
                                                     0.0, 2.0),
                        animation.AttributeAnimation(self, 'scene_fade', 1.0,
                                                     2.0),
                    ),
                    animation.WaitAnimation(0.5, app.controller.switch_scene,
                                            type(self), next_level)).start()
                self.scene_ready = False
                break

            if command == 'repeat_level':
                self.fade_animation = animation.QueuedAnimation(
                    animation.ParallelAnimation(
                        animation.AttributeAnimation(self.bg_player, 'volume',
                                                     0.0, 2.0),
                        animation.AttributeAnimation(self, 'scene_fade', 1.0,
                                                     2.0),
                    ),
                    animation.WaitAnimation(0.5, app.controller.switch_scene,
                                            type(self), type(self.level)),
                ).start()
                self.scene_ready = False
                break

            if command == 'win_game':
                self.fade_animation = animation.QueuedAnimation(
                    animation.ParallelAnimation(
                        animation.AttributeAnimation(self.bg_player, 'volume',
                                                     0.0, 2.0),
                        animation.AttributeAnimation(self, 'scene_fade', 1.0,
                                                     2.0),
                    ),
                    animation.WaitAnimation(
                        0.5, app.controller.switch_scene,
                        applib.scenes.victory.VictoryScene),
                ).start()
                self.scene_ready = False
                break

            if command == 'end_game':
                self.fade_animation = animation.QueuedAnimation(
                    animation.ParallelAnimation(
                        animation.AttributeAnimation(self.bg_player, 'volume',
                                                     0.0, 2.0),
                        animation.AttributeAnimation(self, 'scene_fade', 1.0,
                                                     2.0),
                    ),
                    animation.WaitAnimation(0.5, app.controller.switch_scene,
                                            applib.scenes.menu.MenuScene),
                ).start()
                self.scene_ready = False
                break

        else:
            self.scene_lines = None
            self.dialogue_overlay.visible = False
Exemplo n.º 10
0
    def on_tick(self):

        score_ratio = self.level.get_score_ratio()
        self._score_ratio += (score_ratio - self._score_ratio) * 0.03

        if self.dialogue_overlay.visible:
            # Do dialogue things here.
            pass
        elif self.scene_fade:
            pass
        else:
            # Update the level first.
            self.level.tick()

        view_width, view_height = self.interface.get_content_size()

        # Update the sprites for all entities in the level.
        for entity in self.level.entities:
            self.update_sprite(entity)

        # Depersist any persisting sprites whose check passes.
        for sprite, persist_check in list(self.persisting_sprites.items()):
            if persist_check():
                del self.persisting_sprites[sprite]

        # Remove sprites for missing entities from the scene.
        found_sprites = set(entity.sprite
                            for entity in self.level.entities) | set(
                                self.persisting_sprites)
        for sprite in list(self.interface.sprites):
            if sprite not in found_sprites:
                sprite.stop_animation()
                self.interface.sprites.remove(sprite)
                if sprite in self.entities_by_sprite:
                    entity = self.entities_by_sprite[sprite]
                    del self.entities_by_sprite[sprite]
                    del self.sprites_by_entity[entity]

        # Update remaining sprites.
        processed_items = []
        for sprite, entity in self.entities_by_sprite.items():

            # Move order sprites to follow their customer.
            if isinstance(entity, applib.model.level.Customer):
                entity.sprite.overlay_function = self.draw_customer_overlay
                order_count = len(entity.order.items)
                for index, item in enumerate(entity.order.items):
                    processed_items.append(item)
                    order_arc_angle = CUSTOMER_ORDER_POSITIONS[order_count][
                        index]
                    order_arc_radius = CUSTOMER_ORDER_HEIGHT * view_height + sprite.height / 2
                    relative_position_x = order_arc_radius * math.sin(
                        math.radians(order_arc_angle))
                    relative_position_y = order_arc_radius * math.cos(
                        math.radians(order_arc_angle))
                    customer_center = sprite.x + sprite.animation_offset_x
                    position_x = customer_center + relative_position_x
                    position_y = sprite.y + relative_position_y
                    item.sprite.layer = sprite.layer + 0.2
                    item.sprite.update(
                        x=position_x,
                        y=position_y,
                        scale=0.7,
                        rotation=order_arc_angle,
                    )
                    bubble = pyglet.resource.texture('interface/bubble.png')
                    item.sprite.set_background_sprite(bubble)
                    item.sprite.update_background_sprite()

                # Paw animation
                paw_name = f'customers/{entity.name}_paw.png'
                if paw_name in pyglet.resource._default_loader._index:
                    if not sprite.foreground_sprite:
                        texture = pyglet.resource.texture(paw_name)
                        sprite.set_foreground_sprite(texture)
                        fg = sprite.foreground_sprite
                        fg.visible = False
                        fg.layer = sprite.layer
                        self.persisting_sprites[fg] = (lambda c=entity: abs(
                            c.sprite.animation_offset_x) > view_width / 2)
                        self.interface.sprites.append(fg)
                    sprite.update_foreground_sprite()
                    fg = sprite.foreground_sprite

                    customer_is_moving = (sprite._animation_offset_x !=
                                          sprite._target_offset_x)
                    paws_on_counter = (fg.animation_offset_y == 0.0
                                       and fg.layer == 0.1)
                    paws_are_animating = (entity in self.paw_animations) and (
                        self.paw_animations[entity] in app.animation)
                    customer_is_on_right = (
                        entity in self.level.customers) and (
                            self.level.customers.index(entity) > 2)

                    if not paws_are_animating:
                        if customer_is_moving and paws_on_counter:
                            # Animate off counter
                            fg.visible = True
                            fg.animation_offset_y = 0.0
                            fg.layer = 0.1
                            self.paw_animations[
                                entity] = animation.QueuedAnimation(
                                    animation.AttributeAnimation(
                                        fg, 'animation_offset_y',
                                        0.03 * fg.height, 0.4, 'symmetric'),
                                    animation.WaitAnimation(
                                        0.0,
                                        lambda fg=fg, sp=sprite: setattr(
                                            fg, 'layer', sp.layer + 0.1)),
                                    animation.AttributeAnimation(
                                        fg, 'animation_offset_y',
                                        -0.1 * fg.height, 0.8, 'symmetric'),
                                ).start()
                        elif not customer_is_moving and not paws_on_counter and not customer_is_on_right:
                            # Animate on counter
                            fg.visible = True
                            fg.animation_offset_y = -0.1 * fg.height
                            fg.layer = sprite.layer + 0.1
                            self.paw_animations[
                                entity] = animation.QueuedAnimation(
                                    animation.AttributeAnimation(
                                        fg, 'animation_offset_y',
                                        0.03 * fg.height, 0.8, 'symmetric'),
                                    animation.WaitAnimation(
                                        0.0,
                                        lambda fg=fg: setattr(
                                            fg, 'layer', 0.1)),
                                    animation.AttributeAnimation(
                                        fg, 'animation_offset_y', 0.0, 0.4,
                                        'symmetric'),
                                ).start()

            # Move current item sprites to their device.
            if isinstance(entity, applib.model.device.Device):

                # Set alternative texture
                has_alt_sprite = False
                if type(entity.current_item) in entity.alt_sprites:
                    alt_index = int(time.time() * 5) % len(
                        entity.alt_sprites[type(entity.current_item)])
                    alt_texture_path = entity.alt_sprites[type(
                        entity.current_item)][alt_index]
                    texture = pyglet.resource.texture(alt_texture_path)
                    sprite._texture.anchor_x = sprite._texture.width // 2
                    sprite._texture.anchor_y = sprite._texture.height // 2
                    if texture not in self._texture_data:
                        texture_data = texture.get_image_data().get_data()
                        self._texture_data[texture] = texture_data
                    has_alt_sprite = True
                else:
                    texture = entity.texture
                if texture != sprite._texture:
                    sprite._set_texture(texture)
                    sprite._update_position()

                if entity.sprite.x > view_width / 2 and entity.sprite.scale_x > 0:
                    entity.sprite.scale_x *= -1
                if entity.current_item is not None:
                    processed_items.append(entity.current_item)
                    flipped = (entity.sprite.x > view_width / 2)
                    item_x, item_y = entity.item_position
                    entity.current_item.sprite.layer = sprite.layer + 0.2
                    entity.current_item.sprite.visible = not has_alt_sprite
                    entity.current_item.sprite.update(
                        x=sprite.x + item_x * sprite.width *
                        (-1 if flipped else 1),
                        y=sprite.y + item_y * sprite.height,
                    )

        # Postprocessing for items.
        for sprite, entity in self.entities_by_sprite.items():
            if isinstance(entity, applib.model.item.Item):
                if entity.holds is not None:
                    processed_items.append(entity.holds)
                    hold_sprite = entity.holds.sprite
                    item_x, item_y = entity.holds_position
                    entity.holds.sprite.layer = sprite.layer + 0.2
                    entity.holds.sprite.visible = (entity
                                                   is not self.level.held_item)
                    entity.holds.sprite.update(
                        x=sprite.x + item_x * sprite.width,
                        y=sprite.y + item_y * sprite.height,
                    )

        # Postpostprocessing for items.
        for sprite, entity in self.entities_by_sprite.items():
            if isinstance(entity, applib.model.item.Item):
                if entity not in processed_items:
                    sprite.visible = True
                    if entity is self.level.held_item:
                        sprite.visible = False
                    elif DEBUG:
                        self.level.debug_print()