class Outro(State): def __init__(self): State.__init__(self) self.fps = 40 #animation checkpoints and flags self.opening = 0 self.closing = 0 self.door_timer = Timer(15) #open slowly, then faster self.maelstrom_timer = Timer(30) #open doors a bit.. then pull self.nanji_command = None #generate pseudo-map screen_size = GLOBALS["screen_size"] self.bg_image = pygame.Surface(screen_size) self.top_layer = pygame.Surface(screen_size) self.top_layer.set_colorkey((255, 0, 255)) self.top_layer.fill((255, 0, 255)) #draw map background bg = GLOBALS["backgrounds"]["fuji.png"] self.bg_image.blit(bg, (0, 0)) #draw grass tsize = GLOBALS["tile_size"] grass_tile = GLOBALS["ts_tileset"][1, 0] x = -tsize y = screen_size[1] - tsize for i in xrange(22): self.top_layer.blit(grass_tile, (x, y)) x += tsize #draw mysterious myst = GLOBALS["ui_stuff"]["mysterious.png"] #draw full signet board on mysterious board = GLOBALS["ui_stuff"]["board_filled.png"] x, y = 66, 197 myst.blit(board, (x, y)) x = 5 * tsize y = screen_size[1] - myst.get_size()[1] - tsize self.myst = StaticWidget(myst.get_size()) self.myst.set_colorkey((255, 0, 255)) self.myst.fill((255, 0, 255)) self.myst.blit(myst, (0, 0)) self.myst.set_pos((x, y)) self.myst.pos = (x, y) self.myst.draw(self.top_layer) myst_centerx = x + myst.get_size()[0] / 2 myst_top = y + 30 #init doors self.door_speed = 1 door_left_image = GLOBALS["ui_stuff"]["door_left.png"] door_right_image = GLOBALS["ui_stuff"]["door_right.png"] self.door_left = StaticWidget(door_left_image.get_size()) self.door_left.blit(door_left_image, (0, 0)) self.door_left.set_pos((self.myst.pos[0] + 99, self.myst.pos[1] + 63)) self.door_right = StaticWidget(door_right_image.get_size()) self.door_right.blit(door_right_image, (0, 0)) self.door_right.set_pos( (self.myst.pos[0] + 177, self.myst.pos[1] + 63)) #init whirling vortex self.vortex = Vortex(centerpos=(myst_centerx, myst_top)) #init Nanji self.nanji = Nanji(cam=None) self.nanji.status = 0 self.nanji.set_pos((205, 401)) self.nanji_angle = 0 self.nanji_fly_img = self.nanji.all_images["landing"][0] self.nanji_shrink = 1 self.sprites.add(self.nanji) self.nanji_do("throw") def main_start(self): pygame.mouse.set_visible(0) State.main_start(self) def update_doors(self): if self.opening: lx, ly = self.door_left.get_pos() rx, ry = self.door_right.get_pos() self.door_left.set_pos((lx - self.door_speed, ly)) self.door_right.set_pos((rx + self.door_speed, ry)) if self.door_timer.update(): self.door_speed = 2 self.opening = lx > 165 elif self.closing: self.door_speed = 1 lx, ly = self.door_left.get_pos() rx, ry = self.door_right.get_pos() self.door_left.set_pos((lx + 1, ly)) self.door_right.set_pos((rx - 1, ry)) self.closing = lx < 258 if not self.closing: self.maelstrom_timer.set_interval(50) self.nanji_do("waitquit") self.door_left.draw(self.background) self.door_right.draw(self.background) def nanji_do(self, do="throw"): self.nanji_command = do if do == "throw": #lift paw self.nanji.change_images("throwing") self.nanji.anim_timer.set_interval(5) self.nanji.play() elif do == "unthrow": #put paw down images = self.nanji.images[:] images.reverse() self.nanji.set_images(images) self.nanji.play() elif do == "wait_door": self.nanji.change_images("idle") self.opening = 1 self.nanji.pause() elif do == "walk" or do == "walk2": self.nanji.look = -1 self.nanji.change_images("walking") self.nanji.anim_timer.set_interval(8) self.nanji.play() elif do == "sprint" or do == "sprint2": self.nanji.change_images("sprinting") self.nanji.anim_timer.set_interval(8) self.nanji.play() elif do == "duck": self.nanji.change_images("ducking") self.nanji.pause() elif do == "lift": self.nanji.change_images("landing") self.nanji.pause() def update_nanji(self): if self.nanji_command is None: return #update old command cmd = self.nanji_command x, y = self.nanji.pos #get pulled if cmd == "throw" and self.nanji.cur_image >= 3: #paw up self.nanji_do("unthrow") elif cmd == "unthrow" and self.nanji.cur_image >= 3: #paw down self.nanji_do("wait_door") elif cmd == "wait_door" and self.maelstrom_timer.update(): #wait self.nanji_do("walk") elif cmd == "walk": if x > 150: #walk left self.nanji.set_pos((x - 1, y)) else: self.nanji_do("walk2") elif cmd == "walk2": if x < 190: self.nanji.set_pos((x + 1, y)) else: self.nanji_do("sprint") elif cmd == "sprint": #try to sprint if x > 170: self.nanji.set_pos((x - 1, y)) else: self.nanji_do("sprint2") elif cmd == "sprint2": self.nanji.set_pos((x + 1, y)) if self.maelstrom_timer.update(): self.nanji_do("duck") elif cmd == "duck" and self.maelstrom_timer.update(): self.nanji_do("duckpull") elif cmd == "duckpull": if x < 250: self.nanji.set_pos((x + 1, y)) else: self.nanji_do("lift") elif cmd == "lift": if x < 280: self.nanji.set_pos((x + 1, y)) else: self.nanji_do("liftoff") self.maelstrom_timer.set_interval(10) elif cmd == "liftoff": self.nanji.set_pos((x, y - 1)) if self.maelstrom_timer.update(): self.nanji_do("whirl") elif cmd == "whirl": img = self.nanji_fly_img.copy() sx, sy = img.get_size() img = pygame.transform.scale( img, (sx - self.nanji_shrink, sy - self.nanji_shrink)) self.nanji_shrink += 1 if sx - self.nanji_shrink < 0 or sy - self.nanji_shrink < 0: self.nanji_do("done") self.nanji_angle += 10 if self.nanji_angle > 360: self.nanji_angle = self.nanji_angle - 360 img = pygame.transform.rotate(img, self.nanji_angle) center = self.nanji.rect.center self.nanji.set_image(img) self.nanji.rect.center = center if y > 350: y -= 1 if x < 350: x += 1 self.nanji.set_pos((x, y)) elif cmd == "done": self.nanji_do(None) self.closing = 1 elif cmd == "waitquit" and self.maelstrom_timer.update(): self.next = TheEnd() self.quit() def update_screen(self): self.background.blit(self.bg_image, (0, 0)) #update and draw vortex self.vortex.update() self.background.blit(self.vortex.image, self.vortex.pos) #update and draw doors self.update_doors() #draw grass, building self.background.blit(self.top_layer, (0, 0)) #draw nanji self.update_nanji() State.update_screen(self)
class LevelSelection(State): def __init__(self, new=True): State.__init__(self) self.success = False self.new = new #start tutorial before showing level selection! self.signet_pos = { "wood": (83, 181), "day": (158, 75), "fire": (284, 34), "life": (410, 75), "earth": (485, 181), "night": (456, 307), "metal": (348, 368), "water": (220, 368), "death": (112, 307) } self.light_pos = { "wood": (239, 225), "day": (261, 173), "fire": (315, 155), "life": (369, 173), "earth": (391, 225), "night": (383, 271), "metal": (345, 307), "water": (285, 307), "death": (247, 271) } self.cur_blinking = None self.cur_blending = None self.cur_clan = None self.blink_timer = Timer(50) self.blink_count = 0 self.blink_max = 10 self.light = GLOBALS["ui_stuff"]["green_light"] r = pygame.Rect([281, 203, 78, 77]) r.inflate(-10, -10) bigredbutton = ClickArea(r, self.bigred_pressed) self.widgets.append(bigredbutton) self.donotpress = pygame.Rect([267, 188, 106, 95]) self.signets = GLOBALS["signets"] self.bg_image = GLOBALS["backgrounds"]["gameboard.png"].copy() self.ui_layer = pygame.Surface(GLOBALS["screen_size"]) self.ui_layer.fill((255, 0, 255)) self.ui_layer.set_colorkey((255, 0, 255)) self.tooltip_layer = pygame.Surface(GLOBALS["screen_size"]) self.tooltip_layer.fill((255, 0, 255)) self.tooltip_layer.set_colorkey((255, 0, 255)) self.tooltip = StaticWidget((80, 20)) self.dnp_tooltip = GLOBALS["ui_stuff"]["donotpress"] #level selection buttons self.signet_buttons = [] levels = GLOBALS["clan_levels"] for k in self.signet_pos.keys(): if self.signets.has_key(k) and levels.has_key(k): btn = ImgButton(self.signets[k][0], self.start_level, \ clan=k, level=levels[k]) btn.set_pos(self.signet_pos[k]) btn.rect = pygame.Rect([self.signet_pos[k], btn.get_size()]) btn.rect.inflate(-20, -20) btn.clan = k self.widgets.append(btn) self.signet_buttons.append(btn) #show savegame progress self.show_signet(player_data["unlocked"]) #keyboard events self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit) self.background.blit(self.bg_image, (0, 0)) self.background.blit(self.tooltip_layer, (0, 0)) self.background.blit(self.ui_layer, (0, 0)) self.tooltip_layer.fill((255, 0, 255)) def main_start(self): if pygame.mixer.music.get_busy(): pygame.mixer.music.fadeout(300) pygame.mouse.set_visible(1) if self.new is True: self.new = "somewhere in between" self.cur_clan = None self.next = Level("tutorial.map", prev=self) self.pause() self.quit() elif self.new == "somewhere in between": self.new = False self.update_screen() self.next = ShowDialog("donotpress", self.screen) self.pause() self.quit() def start_level(self, clan, level): if clan in player_data[ "unlocked"] or self.cur_blending or self.cur_blinking: #do not start finished maps and wait while blending new signet in return self.success = False self.cur_clan = clan self.next = Level(level, prev=self) self.pause() self.quit() def unpause(self): if self.success: if self.cur_clan: self.show_signet([self.cur_clan]) player_data["unlocked"].append(self.cur_clan) #track progress self.cur_clan = None self.autosave() #save progress State.unpause(self) def autosave(self): try: save_object(player_data, "save.dat") except: print "Autosave failed. Uh.. guess you need to keep playing?" def show_signet(self, clans): #show recently gained signet(s) self.cur_blending = [] self.cur_blinking = [] for clan in clans: #signet signet = self.signets[clan][0] blend = StaticWidget(signet.get_size()) blend.fill((255, 0, 255)) blend.set_colorkey((255, 0, 255)) blend.blit(signet, (0, 0)) blend.set_pos(self.signet_pos[clan]) blend.set_alpha(0) self.cur_blending.append(blend) #green light img = self.light blink = StaticWidget(img.get_size()) blink.fill((255, 0, 255)) blink.set_colorkey((255, 0, 255)) blink.blit(img, (0, 0)) blink.set_pos(self.light_pos[clan]) self.cur_blinking.append(blink) self.blink_timer.set_interval(3) def update_other(self): if self.cur_blending: #fancy alpha blending effect for new signet alpha = self.cur_blending[0].get_alpha() + 5 if alpha > 100: #stop blending for blend in self.cur_blending: blend.set_alpha(None) blend.draw(self.bg_image) self.cur_blending = None else: #keep blending for blend in self.cur_blending: blend.set_alpha(alpha) blend.draw(self.bg_image) elif self.cur_blinking: if not self.blink_timer.update(): return #fancy blinking light o/ self.blink_count += 1 b = self.blink_count #simulate irregular flickering if b == 1: self.blink_timer.set_interval(2) elif b == 3: self.blink_timer.set_interval(3) elif b == 6: self.blink_timer.set_interval(1) #to draw or not to draw... if self.blink_count % 2: for blink in self.cur_blinking: blink.draw(self.ui_layer) else: self.ui_layer.fill((255, 0, 255)) #ok, stop flickering. if self.blink_count > self.blink_max: for blink in self.cur_blinking: blink.draw(self.bg_image) self.ui_layer.fill((255, 0, 255)) self.blink_count = 0 self.cur_blinking = None else: self.check_mouseover() def check_mouseover(self): #check if mouse hovers signet and show tooltip mpos = pygame.mouse.get_pos() for b in self.signet_buttons: if b.rect.collidepoint(mpos): self.tooltip.fill((255, 255, 255)) self.tooltip.draw_border((0, 0, 0)) self.tooltip.blit(GLOBALS["kanji"]["clan"], (10, 3)) self.tooltip.blit(GLOBALS["kanji"][b.clan], (60, 4)) pos = (mpos[0] + 10, mpos[1] + 20) x = (b.rect.centerx - self.tooltip.get_size()[0] / 2) y = b.rect.top pos = (x, y) self.tooltip_layer.blit(self.tooltip, pos) break dnp = self.donotpress if dnp.collidepoint(mpos): pos = (dnp.left - 60, dnp.top - 22) self.tooltip_layer.blit(self.dnp_tooltip, pos) def bigred_pressed(self): if self.cur_blending or self.cur_blinking: return if len(player_data["unlocked"]) < 9: self.next = ShowDialog("nothinghappened", self.screen) self.pause() self.quit() else: self.next = Outro() self.quit() def update_screen(self): self.background.blit(self.bg_image, (0, 0)) self.background.blit(self.tooltip_layer, (0, 0)) self.background.blit(self.ui_layer, (0, 0)) self.tooltip_layer.fill((255, 0, 255)) State.update_screen(self)