# The basic game selector. from constants import * from interface import * from pygame.font import Font import ui import endless, courseselect, songselect GS_HELP = [ "Up / Down: Change game, mode, or interface", "Enter / Up Right: Advance your choice", "Escape / Up Left: Back up or exit", "F11: Toggles fullscreen", "Enjoy pydance %s!" % VERSION, ] # The game, type, and interfaces available on the screen. GAMES = ["4 panel", "5 panel", "6 panel", "8 panel", "9 panel", "Parapara", "DMX", "EZ2", "EZ2 Real", "3 panel"] TYPES = ["Single", "Versus", "Double", "Couple"] SS = ["Normal", "Nonstop", "Endless"] VALUES = [GAMES, TYPES, SS] # Shrink and put two of the same image, staggered . def make_versus(oldimage): surf = pygame.Surface([350, 300], SRCALPHA, 32) surf.fill([0, 0, 0, 0]) newimage = pygame.transform.rotozoom(oldimage, 0, 0.714286) surf.blit(newimage, [0, 0]) surf.blit(newimage, [100, 100]) return surf # Shrink and put two of the same image, in a line. def make_double(oldimage): surf = pygame.Surface([350, 300], SRCALPHA, 32) surf.fill([0, 0, 0, 0]) newimage = pygame.transform.rotozoom(oldimage, 0, 0.5) surf.blit(newimage, [0, 80]) surf.blit(newimage, [175, 80]) return surf # Put the two images staggered and slightly rotated in different directions. def make_couple(oldimage): surf = pygame.Surface([350, 300], SRCALPHA, 32) surf.fill([0, 0, 0, 0]) image1 = pygame.transform.rotozoom(oldimage, -30, 0.714286) image2 = pygame.transform.rotozoom(oldimage, 30, 0.714286) surf.blit(image1, [-30, -40]) surf.blit(image2, [60, 20]) return surf # Filenames for each mode, or functions to call with the previous image # to construct the new image. IMAGES = { "3 panel": "select-3p.png", "4 panel": "select-4p.png", "5 panel": "select-5p.png", "6 panel": "select-6p.png", "8 panel": "select-8p.png", "9 panel": "select-9p.png", "Parapara": "select-para.png", "EZ2 Real": "select-ez2real.png", "EZ2": "select-ez2.png", "DMX": "select-dmx.png", "Single": (lambda x: x), "Versus": make_versus, "Double": make_double, "Couple": make_couple, "Normal": "select-normal.png", "Nonstop": "select-nonstop.png", "Endless": "select-endless.png", } # Constructors for the different interfaces. SELECTORS = { "Endless": endless.Endless, "Nonstop": courseselect.CourseSelector, "Normal": songselect.SongSelect, } # Map the game and type onto an internal name for SongItem.difficulty. MODES = { ("4 panel", "Single"): "SINGLE", ("4 panel", "Versus"): "VERSUS", ("4 panel", "Couple"): "COUPLE", ("4 panel", "Double"): "DOUBLE", ("3 panel", "Single"): "3PANEL", ("3 panel", "Versus"): "3VERSUS", ("3 panel", "Couple"): "3COUPLE", ("3 panel", "Double"): "3DOUBLE", ("5 panel", "Single"): "5PANEL", ("5 panel", "Versus"): "5VERSUS", ("5 panel", "Couple"): "5COUPLE", ("5 panel", "Double"): "5DOUBLE", ("6 panel", "Single"): "6PANEL", ("6 panel", "Versus"): "6VERSUS", ("6 panel", "Couple"): "6COUPLE", ("6 panel", "Double"): "6DOUBLE", ("8 panel", "Single"): "8PANEL", ("8 panel", "Versus"): "8VERSUS", ("8 panel", "Couple"): "8COUPLE", ("8 panel", "Double"): "8DOUBLE", ("9 panel", "Single"): "9PANEL", ("9 panel", "Versus"): "9VERSUS", ("9 panel", "Couple"): "9COUPLE", ("9 panel", "Double"): "9DOUBLE", ("Parapara", "Single"): "PARAPARA", ("Parapara", "Versus"): "PARAVERSUS", ("Parapara", "Couple"): "PARACOUPLE", ("Parapara", "Double"): "PARADOUBLE", ("DMX", "Single"): "DMX", ("DMX", "Versus"): "DMXVERSUS", ("DMX", "Couple"): "DMXCOUPLE", ("DMX", "Double"): "DMXDOUBLE", ("EZ2", "Single"): "EZ2SINGLE", ("EZ2", "Versus"): "EZ2VERSUS", ("EZ2", "Couple"): "EZ2COUPLE", ("EZ2", "Double"): "EZ2DOUBLE", ("EZ2 Real", "Single"): "EZ2REAL", ("EZ2 Real", "Versus"): "REALVERSUS", ("EZ2 Real", "Couple"): "REALCOUPLE", ("EZ2 Real", "Double"): "REALDOUBLE", } DESCRIPTIONS = { "4 panel": ("The standard up, down, left and right arrows " + "like Dance Dance Revolution)"), "3 panel": "Practice using up left and up right with easier steps.", "5 panel": "Diagonal arrows and the center (like Pump It Up)", "6 panel": "Four panel plus the upper diagonal arrows (like DDR Solo)", "8 panel": "Everything but the center (like Technomotion)", "9 panel": "Everything! (like Pop'n'Stage)", "Parapara": "Wave your arms (or feet) around", "DMX": ("Crazy kung-fu action (like Dance ManiaX / Freaks). " + "Use left, up left, up right, and right."), "EZ2": "Three panels, two sensors, using left and right.", "EZ2 Real": "Three panels and four sensors.", "Single": "Play by yourself.", "Versus": "Challenge an opponent to the same steps.", "Couple": "Two people dance different steps to the same song.", "Double": "Try playing on both sides at once.", "Normal": "Play one song at a time.", "Endless": "Keep dancing until you fail.", "Nonstop": "Play several songs in a row.", } class MainWindow(InterfaceWindow): def __init__(self, songs, courses, screen): InterfaceWindow.__init__(self, screen, "gameselect-bg.png") self._songs = songs self._courses = courses self._indicator_y = [152, 322, 414] # Displayed in the upper right. self._message = ["Select a Game", "Select a Mode", "Select Type"] font = Font(None, 26) # Three lists, one for each type of selection. self._lists = [ListBox(font, [255, 255, 255], 26, 9, 220, [408, 53]), ListBox(font, [255, 255, 255], 26, 3, 220, [408, 300]), ListBox(font, [255, 255, 255], 26, 3, 220, [408, 393])] self._lists[0].set_items(GAMES) self._lists[1].set_items(TYPES) self._lists[2].set_items(SS) # Title in the upper right (from self._message). self._title = TextDisplay(24, [210, 28], [414, 26]) # Currently selected object. self._selected = TextDisplay(48, [400, 28], [15, 380]) # Description of the currently selected object. self._description = WrapTextDisplay(30, 360, [25, 396]) self._title.set_text(self._message[0]) self._selected.set_text("4 panel") self._description.set_text(DESCRIPTIONS["4 panel"]) self._sprites.add([self._title, self._selected, self._description]) self._indicator = ActiveIndicator([405, 152], width = 230) self._sprites.add(self._indicator) self._sprites.add(HelpText(GS_HELP, [255, 255, 255], [0, 0, 0], Font(None, 22), [206, 20])) self._sprites.add(self._lists) # The image displayed on the main part of the screen. self._image = FlipImageDisplay(IMAGES.get("4 panel"), [200, 200]) self._sprites.add(self._image) self._screen.blit(self._bg, [0, 0]) self._sprites.update(pygame.time.get_ticks()) self._sprites.draw(self._screen) pygame.display.update() self.loop() def loop(self): active = 0 # 0 = game select, 1 = type select, 2 = ui select indices = [0, 0, 0] # currently selected indices pid, ev = ui.ui.poll() while not (ev == ui.CANCEL and active == 0): if ev == ui.UP: indices[active] -= 1 elif ev == ui.DOWN: indices[active] += 1 elif ev == ui.FULLSCREEN: mainconfig["fullscreen"] ^= 1 pygame.display.toggle_fullscreen() elif ev == ui.CANCEL: active -= 1 elif ev in [ui.CONFIRM, ui.START]: if active == 2: # Start the selected UI, and clean up afterwards SELECTORS[SS[indices[2]]](self._songs, self._courses, self._screen, MODES.get((VALUES[0][indices[0]], VALUES[1][indices[1]]))) active = 0 self._screen.blit(self._bg, [0, 0]) pygame.display.update() else: active += 1 if active == 1: self._oldimage = self._image._image # FIXME indices[active] %= len(VALUES[active]) if ev in [ui.UP, ui.DOWN]: if ev == ui.UP: self._lists[active].set_index(indices[active], -1) else: self._lists[active].set_index(indices[active], 1) text = VALUES[active][indices[active]] self._selected.set_text(text) self._description.set_text(DESCRIPTIONS[text]) img = IMAGES.get(text) if callable(img): self._image.set_image(img(self._oldimage)) else: self._image.set_image(IMAGES.get(text)) if ev in [ui.CONFIRM, ui.START, ui.CANCEL]: self._indicator.move([405, self._indicator_y[active]]) self._title.set_text(self._message[active]) text = VALUES[active][indices[active]] self._selected.set_text(text) self._description.set_text(DESCRIPTIONS[text]) img = IMAGES.get(text) if callable(img): self._image.set_image(img(self._oldimage)) else: self._image.set_image(IMAGES.get(text)) self.update() pid, ev = ui.ui.poll()