def add_artifact(self, area, x, y): # Artifact self.artifact = Artifact(area, 1) area.main_layer.add(self.artifact) self.artifact.move_to(x - self.artifact.rect.width / 2, y - self.artifact.rect.height - 50) self.artifact.grab_changed.connect(self.on_artifact_grabbed)
class Level(object): CROSSOVER_TIME_INTERVAL = (4000, 10000) MAX_CROSSOVERS = 3 def __init__(self, engine): self.engine = engine self.time_periods = [] self.active_area = None self.music = None self.crossover_timer = None self.crossovers = [] self.pending_crossovers = {} self.next_crossover_id = 0 self.engine.tick.connect(self.on_tick) # Signals self.area_changed = Signal() self.time_period_changed = Signal() def add(self, time_period): self.time_periods.append(time_period) def add_artifact(self, area, x, y): # Artifact self.artifact = Artifact(area, 1) area.main_layer.add(self.artifact) self.artifact.move_to(x - self.artifact.rect.width / 2, y - self.artifact.rect.height - 50) self.artifact.grab_changed.connect(self.on_artifact_grabbed) def reset(self): self.active_area = None self.active_time_period = None self.time_periods = [] self._setup() def setup(self): pass def _setup(self): self.setup() for time_period in self.time_periods: time_period.setup() def switch_area(self, area): if area == self.active_area: return player = self.engine.player if self.active_area: self.active_area.main_layer.remove(player) self.active_area = area self.active_area.main_layer.add(player) self.area_changed.emit() player.reset_gravity() for crossover, timer in self.crossovers: timer.stop() crossover.remove() for pending_timer in self.pending_crossovers.itervalues(): pending_timer.stop() self.crossovers = [] self.pending_crossovers = {} def switch_time_period(self, num): time_period = self.time_periods[num] if self.active_area: key = self.active_area.key area = time_period.areas.get(key, None) else: area = time_period.default_area player = self.engine.player if (area and (not self.active_area or not list(player.get_collisions(tree=area.main_layer.quad_tree)))): self.active_time_period = time_period self.time_period_changed.emit() self.switch_area(area) def draw(self, screen): self.active_area.draw(screen) def on_artifact_grabbed(self): if self.artifact.grabbed: player = self.engine.player player.block_events = True player.velocity = (0, 0) player.fall() timer = Timer(1000, self.engine.next_level, one_shot=True) timer.start() def on_tick(self): if not self.engine.paused and self.engine.active_level == self: self.active_area.tick() if (len(self.time_periods) > 1 and len(self.crossovers) + len(self.pending_crossovers) < self.MAX_CROSSOVERS): crossover_id = self.next_crossover_id self.next_crossover_id += 1 timer = Timer( random.randint(*self.CROSSOVER_TIME_INTERVAL), lambda: self.show_crossover(crossover_id), one_shot=True) self.pending_crossovers[crossover_id] = timer def show_crossover(self, crossover_id): def hide_crossover(): crossover_sprite.remove() self.crossovers.remove((crossover_sprite, timer)) self.pending_crossovers[crossover_id].stop() del self.pending_crossovers[crossover_id] key = self.active_area.key time_periods = [ time_period.areas[key] for time_period in self.time_periods if (time_period != self.active_time_period and key in time_period.areas) ] if len(time_periods) - 1 <= 0: return i = random.randint(0, len(time_periods) - 1) crossover_sprite = Crossover(time_periods[i]) crossover_sprite.rect = self.engine.camera.rect if random.randint(0, 5) <= 3: layer = self.active_area.bg_layer else: layer = self.active_area.main_layer layer.add(crossover_sprite) timer = Timer(500, hide_crossover, one_shot=True) timer.start() self.crossovers.append((crossover_sprite, timer))