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()
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()
def end_logo(self): if self.rawr_player: self.rawr_player.pause() self.logo_animation.stop() self.logo_sprite.visible = False self.interface.visible = True width, height = self.interface.get_content_size() animations = [] animation.ParallelAnimation( animation.WaitAnimation(0.0, app.music.switch, pyglet.resource.media('music/scott_gratton_rocket_boat.mp3')), SpiralAnimation(self, 'interface_x', 'interface_y', 0.0, 0.0, 0.85 * math.pi, 2.0), ).start()
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()
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()
def do_button_quit(self): animation.QueuedAnimation( animation.AttributeAnimation(self, 'scene_fade', 1.0, 0.3), animation.WaitAnimation(0.1, pyglet.app.exit), ).start()
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
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
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()