def __init__(self): super(Splash, self).__init__() self.animations = pg.sprite.Group() self.animations.add(Task(self.wake_bats, 6000)) self.animations.add(Task(self.fade_out, 9000)) self.timer = 0 with open("bat_spots.json", "r") as f: points = json.load(f) shuffle(points) self.bats = [Bat(point, randint(0, 360)) for point in points] self.web = prepare.GFX["web"] self.web_rect = self.web.get_rect(center=prepare.SCREEN_RECT.center) self.shade = pg.Surface(prepare.SCREEN_SIZE).convert() self.shade.fill(pg.Color("gray1")) self.curtain = self.shade.copy() self.curtain.fill(pg.Color(10, 5, 20)) self.shade_alpha = 255 self.curtain_alpha = 0 self.curtain.set_alpha() self.moon = Moon(20000) self.flash_timer = 0 self.flash_time = 120 self.thunder_sounds = [ prepare.SFX["thunder{}".format(x)] for x in range(1, 5) ] pg.mixer.music.load(prepare.MUSIC["CrEEP"]) pg.mixer.music.play(-1)
def shoot(self, bullets, turkeys, all_sprites, animations): """ Fire a bullet if the player has enough ammo and enough time has passed since the last shot. """ if self.cooldown_timer >= self.cooldown_time: self.stop_walking() if self.shells <= 0: prepare.SFX["gunclick"].play() else: self.shells -= 1 prepare.SFX["gunshot"].play() pos = project(self.pos, (self.angle - .1745) % (2 * pi), 42) #end of rifle at 96x96 bullet = Bullet(pos, self.angle, bullets, all_sprites) distance = 2000. x, y = project(pos, self.angle, distance) ani = Animation(centerx=x, centery=y, duration=distance / bullet.speed, round_values=True) ani.callback = bullet.kill ani.start(bullet.rect) animations.add(ani) scare_rect = self.collider.inflate(1200, 1200) scared_turkeys = [ t for t in turkeys if scare_rect.colliderect(t.collider) ] for scared in scared_turkeys: task = Task(scared.flee, 750, args=(self, )) self.animations.add(task) task = Task(self.flip_state, 120, args=("idle", )) animations.add(task) self.cooldown_timer = 0 self.flip_state("shoot")
def next_press(self): try: self.press(self.buffer.pop(0)) except IndexError: self.next_command() else: if random.randint(0, 20): task = Task(self.next_press, interval=random.randint(200, 400)) else: task = Task(self.next_press, interval=random.randint(800, 1200)) self._animations.add(task)
def shoot(self): self.shoot_sound.play() pitch = uniform(*self.pitch_range) yaw = uniform(*self.yaw_range) delay = randint(*self.delay_range) pos = choice(self.positions) clay = ClayPigeon(pos, pitch, yaw, self.speed, self.world.nighttime) task = Task(self.world.all_sprites.add, 550, args=(clay, )) task2 = Task(self.world.clays.add, 550, args=(clay, )) task3 = Task(self.shoot, delay) self.animations.add(task, task2) if self.active: self.animations.add(task3)
def update(self, dt): self.animations.update(dt) keys = pg.key.get_pressed() self.hunter.update(dt, keys, self.bullets, self.turkeys, self.colliders, self.all_sprites, self.animations, self.world_rect) self.turkeys.update(dt, self.trees) self.bullets.update(dt) self.world_map.update(self.world_surf, self.map_sprites, self.trees) for sprite in self.all_sprites: self.all_sprites.change_layer(sprite, sprite.collider.bottom) for bullet in self.bullets: if not bullet.rect.colliderect(self.get_view_rect()): bullet.kill() tree_hits = pg.sprite.groupcollide(self.bullets, self.trees, True, False, footprint_collide) for bullet in tree_hits: for tree in tree_hits[bullet]: choice(self.rustle_sounds).play() num = randint(3, 9) for spot_info in sample(leaf_spots[tree.trunk], num): self.add_leaf(tree, spot_info) turkey_hits = pg.sprite.groupcollide(self.bullets, self.turkeys, True, True, footprint_collide) for t_bullet in turkey_hits: for turkey in turkey_hits[t_bullet]: roast = Roast(turkey.pos, dt, self.roasts, self.all_sprites) no_blink = Task(roast.blink, 5000) slow_blink = Task(roast.blink, 400, 10, args=(True,)) fast_blink = Task(roast.blink, 100, 10, args=(True,)) gone = Task(roast.kill) fast_blink.chain(gone) slow_blink.chain(fast_blink) no_blink.chain(slow_blink) self.animations.add(no_blink) if self.hunter.shells < self.hunter.max_shells: if self.hunter.collider.colliderect(self.ammo_crate.rect.inflate(16, 16)): prepare.SFX["gunload"].play() self.hunter.shells = self.hunter.max_shells if self.hunter.state == "move": self.scare_turkeys() self.noise_detector.update(dt) self.shell_label.set_text("{}".format(self.hunter.shells)) self.roasts_label.set_text("{}".format(self.hunter.roasts)) roast_collisions = pg.sprite.spritecollide(self.hunter, self.roasts, True, footprint_collide) if roast_collisions: prepare.SFX["knifesharpener"].play() self.hunter.roasts += len(roast_collisions) self.flocks.update(self.hunter)
def add_flock(self): """Add a Flock of birds.""" flock = Flock((self.hunter.collider.centerx, -1500), self.animations, self.all_sprites, self.flocks) next_flock = randint(45000, 150000) #next flock in 45-150 seconds task = Task(self.add_flock, next_flock) self.animations.add(task)
def __init__(self, turkey): super(Idle, self).__init__(turkey) self.name = "idle" self.duration = randint(700, 3000) direction = choice(self.directions) self.turkey.change_direction(self.name, direction) self.animations = pg.sprite.Group() task = Task(self.turkey.flip_image, 30, -1) self.animations.add(task)
def __init__(self, leader_centerpoint, animations, all_sprites, *groups): super(Flock, self).__init__(*groups) x, y = leader_centerpoint for offset in self.offsets: center = x + offset[0], y + offset[1] duck = Duck(center, all_sprites) if offset == (0, 0): self.leader = duck dest = duck.rect.y + (prepare.WORLD_SIZE[1] * 2) ani = Animation(y=dest, duration=self.fly_time, round_values=True) ani.callback = duck.kill ani.start(duck.rect) flap_time = randint(100, 150) task = Task(duck.flap, flap_time, self.fly_time // flap_time) animations.add(ani, task) finish = Task(self.kill, self.fly_time + 100) animations.add(finish) self.honked = False
def press(self, char, sound=80): if char in self.charset: if sound: random.choice(self.sounds['key']).play() task = Task(partial(self.strike, char), sound) elif char == ' ': if sound: random.choice(self.sounds['spacebar']).play() task = Task(self.advance_one, sound) elif char == '\n': if sound: random.choice(self.sounds['key']).play() task = Task(self.cr, sound) else: raise ValueError(char) # don't show character right away b/c sound lag self._animations.add(task)
def __init__(self, turkey): super(Walking, self).__init__(turkey) self.name = "walk" self.duration = randint(1000, 5000) direction = choice(self.directions) self.turkey.change_direction(self.name, direction) self.speed = 100 / 1000. #random.randint(100, 200) / 1000. self.animations = pg.sprite.Group() task = Task(self.turkey.flip_image, 30, -1) self.animations.add(task)
def shatter(self): if self.shattered: return if self.glow: broken_images = self.broken_glow_images else: broken_images = self.broken_images self.animations.empty() size = self.width * 4 images = [pg.transform.smoothscale(img, (size, size)) for img in broken_images] self.images = cycle(images) self.next_image() self.rect = self.image.get_rect(center=self.rect.center) frame_time = 15 duration = frame_time * (len(images) - 1) task = Task(self.next_image, frame_time, -1) finish = Task(self.kill, duration) self.animations.add(task, finish) self.shattered = True
def __init__(self, turkey): super(Fleeing, self).__init__(turkey) self.name = "flee" self.duration = randint(500, 1500) direction = self.turkey.direction self.turkey.change_direction(self.name, direction) self.speed = 200 / 1000. self.animations = pg.sprite.Group() task = Task(self.turkey.flip_image, 15, -1) self.animations.add(task) self.turkey.gobble()
def make_ani(self, minute_length): dest = next(self.ends) x_trans, y_trans = next(self.transitions) duration = minute_length * 60 * 6 ani = Animation(centerx=dest[0], duration=duration, transition=x_trans, round_values=True) ani2 = Animation(centery=dest[1], duration=duration, transition=y_trans, round_values=True) task = Task(self.make_ani, duration, args=(minute_length, )) ani.start(self.rect) ani2.start(self.rect) self.animations.add(ani, ani2, task)
def __init__(self, positions, delay_range, pitch_range, yaw_range, speed, world, active=True): self.positions = positions self.delay_range = delay_range self.pitch_range = pitch_range self.yaw_range = yaw_range self.speed = speed self.animations = pg.sprite.Group() self.world = world self.active = active if active: delay = randint(*self.delay_range) task = Task(self.shoot, delay) self.animations.add(task) self.shoot_sound = prepare.SFX["skeet-machine"]
def next_command(self): try: cmd, text = self.text.pop(0) except IndexError: self.fade_out() return if cmd == 'display': self.display(text) elif cmd == 'type': self.buffer = list(text) self.next_press() elif cmd == 'sound': self.sounds[text].play() self.next_command() elif cmd == 'wait': task = Task(self.next_command, text) self._animations.add(task)
def run(self, context): flip = pygame.display.flip update = self.update draw = self.draw handle_events = self.handle_event screen = pygame.display.get_surface() clock = time.time frame_time = (1 / 60.) * 1000 last_draw = 0 times = deque(maxlen=10) self.sounds['boot'].play() self.sounds['run'].play(-1, fade_ms=200) task = Task(self.next_command, 2500) self._animations.add(task) self.screen_size = screen.get_size() self.running = True last_frame = clock() while self.running: dt = (clock() - last_frame) * 1000 last_frame = clock() times.append(dt) dt = sum(times) / 10 last_draw += dt handle_events() update(dt) if last_draw >= frame_time: draw(screen) if self.fade_buffer: screen.blit(self.fade_buffer, (0, 0)) flip() last_draw = 0
def update(self, delta, events): self.animations.update(delta) if self.pointer.selected_vertex_id is None or self.moving: return try: edge = self.visitor.current_vertex.get_edge_by_to_vertex_id( self.pointer.selected_vertex_id) if edge.can_traverse(self.visitor.context): self.goto_destination(self.pointer.selected_vertex_id) self.pointer.selected_vertex_id = None else: failing = edge.traversal_pre_requisites.get_failing_pre_requisites( self.visitor.context) for f in failing: fail_msg = "Pre-Requisite not met: (Key: {}, Value: {}, Hint: {})".format( f.key, f.value, f.hint) logger.debug(fail_msg) if self.visitor.context['show_clippie']: self.clippie.queue_text( "I see that you are trying to go there.") self.clippie.queue_text("Do you want some help?", 2000) self.clippie.queue_text( "Its just not possible to go there now.", 2000) self.clippie.queue_text( "Are you sure you know what you are doing?") self.visitor.context['gamestate.dialog_text'] = f.hint self.animations.add(Task(self.clear_hint, 5000)) self.pointer.selected_vertex_id = None # to avoid spam in logger break # just show the first hint except InvalidEdgeException: return
def show_current(self, index=0): """Show the current message :return: None """ text, sprite, dismiss_after, sound = self._message_queue[index] # remove old animations and animate the slide in remove_animations_of(sprite, self._animations) ani = self._animate_show_sprite(sprite) self._animations.add(ani) # add the sprite to the group that contains the advisor if sprite not in self._draw_group: sprite.add(self._draw_group) # play sound associated with the message # sound = prepare.SFX['misc_menu_4'] # sound.set_volume(.2) # sound.play() # set timer to dismiss the sprite if dismiss_after: task = Task(partial(self.dismiss, sprite), dismiss_after) self._animations.add(task)
def start_walking(self): """Add a footstep sound with delay depending on player's movement.""" task = Task(self.play_walk_sound, 400 // self.hustle) self.footstep_animations.add(task)
def initialize(self, context): screen = pygame.display.get_surface() adventure_graph = build_graph_from_yaml_data( load_yaml_data(get_data_asset(self.graph_yaml))) self.visitor = Visitor.visit_graph(adventure_graph, context) tmx_data = load_pygame(resources.get_map_asset(self.graph_tmx)) map_data = pyscroll.TiledMapData(tmx_data) map_layer_size = screen.get_width(), int(screen.get_height() * .80) map_layer_rect = Rect((0, 0), map_layer_size) map_layer = pyscroll.BufferedRenderer(map_data, map_layer_size) self.scroll_group = PyscrollGroup(map_layer=map_layer) self.pointer = PointerSprite(self.vertex_group, self.scroll_group) # self.pointer.selected_vertex_id = "START" self.sprites.add(self.pointer, layer=100) sw, sh = screen.get_size() hud_rect = Rect(20, sh * .76, sw * .80, sh * .2) border_image = load_image('border-default.png').convert_alpha() self.hud_group = HUDGroup(hud_rect, border_image) info = VertexInfoSprite(self.visitor) info.rect = Rect(12, 12, hud_rect.width - 250, hud_rect.height - 24) self.hud_group.add(info) self.hud_group.open() self.hud_button = HUDButton(self.hud_group, 850, 70) self.hud_group.add(self.hud_button) edges = list() for vertex in self.visitor.graph.vertex_index.values(): vertex_sprite = VertexSprite(vertex) self.vertex_group.add(vertex_sprite) self.scroll_group.add(vertex_sprite) for edge in vertex.edges: edges.append(edge) edge_sprites = dict() for edge in edges: key = [edge.from_vertex.vertex_id, edge.to_vertex.vertex_id] key.sort() key = tuple(key) if key not in edge_sprites: edge_sprite = EdgeSprite(edge, self.scroll_group) from_vertex_sprite = self.vertex_group[ edge.from_vertex.vertex_id] to_vertex_sprite = self.vertex_group[edge.to_vertex.vertex_id] from_vertex_sprite.edge_sprites.append(edge_sprite) to_vertex_sprite.edge_sprites.append(edge_sprite) edge_sprites[key] = edge_sprite self.visitor_cursor = VisitorCursor(self.visitor, self.pointer, self.vertex_group, self.scroll_group) if context.get('show_clippie', False): c = Clippie(self.sprites, self._animations, context) c.rect.topleft = 1100, 550 self.sprites.add(c) self.visitor_cursor.clippie = c clock = pygame.time.Clock() pygame.display.flip() pygame.mouse.set_visible(False) while True: delta = clock.tick(60) events = pygame.event.get() self.hud_group.update(delta, events) for event in events: if event.type == pygame.QUIT: sys.exit(0) elif event.type == pygame.KEYDOWN or self.hud_button.handle_click: vertex_id = self.visitor_cursor.current_vertex_sprite.vertex_id if self.hud_button.handle_click or pygame.K_SPACE == event.key and vertex_id == self.pointer.selected_vertex_id: self.hud_button.handle_click = False if self.visitor.current_vertex.can_activate( self.visitor.context): activation_dict = self.visitor.activate_current_vertex( ) if activation_dict[ "command"] == "launch-mini-game": r = RunMinigameActivation( activation_dict["command"], activation_dict["activation-keyword-args"]) logger.debug( "Stating game: {} with arguments {}". format(r.mini_game_name, r.mini_game_keyword_args)) unhandled_actions = self.minigame_manager.run_minigame( r.mini_game_name, self.visitor.context, r.post_run_actions, **r.mini_game_keyword_args if r.mini_game_keyword_args is not None else {}) if self.has_exit_action(unhandled_actions): return else: vertex = self.visitor.current_vertex failing = vertex.activation_pre_requisites.get_failing_pre_requisites( self.visitor.context) self.visitor.context[ 'gamestate.dialog_text'] = failing[0].hint self.visitor_cursor.animations.add( Task(self.visitor_cursor.clear_hint, 5000)) self.scroll_group.update(delta, events) # self.hud_group.update(delta, events) self.sprites.update(delta, events) self._animations.update(delta) self._update_edge_colors() x_offset = ( (self.visitor_cursor.rect.x - self.scroll_group.view.x) - self.pointer.rect.x) / 2 self.scroll_group.center( (self.visitor_cursor.rect.x - x_offset, 0)) self.scroll_group.draw(screen, map_layer_rect) screen.fill((200, 200, 200), (0, sh * .75, 1280, 200)) self.hud_group.draw(screen) self.sprites.draw(screen) screen.blit(self.pointer.image, self.pointer.rect) pygame.display.flip()
def wind_gust(self): """Play wind sound and set up next gust.""" prepare.SFX["wind"].play() task = Task(self.wind_gust, randint(15000, 45000)) self.animations.add(task)
def display(self, text): for char in text: self.strike(char, True) task = Task(self.next_command, interval=random.randint(600, 800)) self._animations.add(task)