class TermBox(GameEngineElement): def __init__(self, x,y,width,height,lines): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.max_lines = lines self.x = x self.y = y surf = pygame.Surface((int(width),int(height))) surf.fill([0,0,0]) self.box = DrawableObject([surf],"") self.box.setPosition(int(x),int(y)) self.font = pygame.font.Font(None, 28) self.__lines = [] for i in range(lines): self.__lines.append(DrawableFontObject('', self.font)) self.add_to_scene([self.box]) self.add_to_scene(self.__lines) self.add_to_engine() def add_line(self, line): for i in range(0, self.max_lines, 1): if i == self.max_lines-1: self.__lines[i].changeText(line, [255,255,255]) else: self.__lines[i].changeText(self.__lines[i+1].getText(), [255,255,255]) def draw(self): i=0 for line in self.__lines: line.setPosition(int(self.x), int(self.y + i*self.font.get_height())) i+=1
class TermBox(GameEngineElement): def __init__(self, x, y, width, height, lines): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.max_lines = lines self.x = x self.y = y surf = pygame.Surface((int(width), int(height))) surf.fill([0, 0, 0]) self.box = DrawableObject([surf], "") self.box.setPosition(int(x), int(y)) self.font = pygame.font.Font(None, 28) self.__lines = [] for i in range(lines): self.__lines.append(DrawableFontObject('', self.font)) self.add_to_scene([self.box]) self.add_to_scene(self.__lines) self.add_to_engine() def add_line(self, line): for i in range(0, self.max_lines, 1): if i == self.max_lines - 1: self.__lines[i].changeText(line, [255, 255, 255]) else: self.__lines[i].changeText(self.__lines[i + 1].getText(), [255, 255, 255]) def draw(self): i = 0 for line in self.__lines: line.setPosition(int(self.x), int(self.y + i * self.font.get_height())) i += 1
def __init__(self, options, cols, scene, x=237, y=375): """Initialize the EzMenu! options should be a sequence of lists in the format of [option_name, option_function]""" self.options = options self.scene = scene self.x = x self.y = y self.cols = cols self.font = pygame.font.SysFont("cmr10", 18, False, False) self.option = 0 self.width = 1 self.color = [0, 0, 0] self.hcolor = [255, 0, 0] self.height = len(self.options) * self.font.get_height() self.font_list = [] self.rect_list = [] for o in self.options: self.font_list.append(DrawableFontObject(o[0], self.font)) ren = self.font.render(o[0], 1, [0, 0, 0]) if ren.get_width() > self.width: self.width = ren.get_width() i = 0 # Row Spacing h = 0 # Selection Spacing j = 0 # Col Spacing for o in self.options: newX = self.x + 45 * j newY = self.y + i * 45 surf = pygame.Surface((o[2], 44)) surf.fill((0, 74, 94)) tempDO = DrawableObject([surf], "") tempDO.setPosition(newX, newY) self.rect_list.append(tempDO) surf = pygame.Surface((o[2] - 4, 40)) surf.fill((4, 119, 152)) tempDO = DrawableObject([surf], "") tempDO.setPosition(newX + 2, newY + 2) self.rect_list.append(tempDO) j += o[3] h += 1 if j >= self.cols: i += 1 j = 0 self.scene.addObjects(self.rect_list) self.scene.addObjects(self.font_list)
def __init__(self, options, cols, scene, x=237, y=375): """Initialize the EzMenu! options should be a sequence of lists in the format of [option_name, option_function]""" self.options = options self.scene = scene self.x = x self.y = y self.cols = cols self.font = pygame.font.SysFont("cmr10",18,False,False) self.option = 0 self.width = 1 self.color = [0, 0, 0] self.hcolor = [255, 0, 0] self.height = len(self.options)*self.font.get_height() self.font_list = [] self.rect_list = [] for o in self.options: self.font_list.append(DrawableFontObject(o[0], self.font)) ren = self.font.render(o[0], 1, [0,0,0]) if ren.get_width() > self.width: self.width = ren.get_width() i=0 # Row Spacing h=0 # Selection Spacing j=0 # Col Spacing for o in self.options: newX = self.x + 45 * j newY = self.y + i * 45 surf = pygame.Surface((o[2],44)) surf.fill((0, 74, 94)) tempDO = DrawableObject([surf], "") tempDO.setPosition(newX,newY) self.rect_list.append(tempDO) surf = pygame.Surface((o[2]-4, 40)) surf.fill((4, 119, 152)) tempDO = DrawableObject([surf], "") tempDO.setPosition(newX+2, newY+2) self.rect_list.append(tempDO) j+=o[3] h+=1 if j >= self.cols: i+=1 j=0 self.scene.addObjects(self.rect_list) self.scene.addObjects(self.font_list)
class Profile(GameEngineElement): def __init__(self, recall_string=None, name_entry_cb=None): GameEngineElement.__init__(self) self.name = "" self.dungeon_id = "al1.txt" self.position = (-1, -1) self.playerFacing = NORTH self.hero = Hero() # 4 types of stats and difficulties self.problem_stats = {} self.difficulty = {} for stat in ["mult", "div", "geo", "shop"]: # Each type of stat has 3 "levels" easy, medium, hard # Shop uses level for too much, too little, exact self.problem_stats[stat] = [(0, 0), (0, 0), (0, 0)] # Difficulty: 1=Easy 2=Meduim(default) 3=Hard self.difficulty[stat] = 2 self.puzzlesSolved = 0 self.inventory = [] bg = pygame.image.load(MENU_PATH + "mafh_splash.gif").convert() self.background = DrawableObject([bg], "") self.background.scale(self.game_engine.width, self.game_engine.height) self.add_to_scene([self.background]) # create background rect draw_width = self.game_engine.width / 4 draw_height = self.game_engine.height / 4 surf = pygame.Surface((draw_width + 60, draw_height + 60)) surf.fill((150, 150, 255)) self.blueRect = DrawableObject([surf], "") self.add_to_scene([self.blueRect]) font = pygame.font.Font(None, 16) self.text_list = [] self.text_list.append(DrawableFontObject("1", font)) self.text_list.append(DrawableFontObject("2", font)) self.text_list.append(DrawableFontObject("name", font)) self.add_to_scene(self.text_list) if recall_string: self.load_from_json_string(recall_string) if self.name == "": self.name_cb = name_entry_cb self.add_to_engine() def reload_dungeon(self): self.__load_dungeon(self.game_engine.get_object("dungeon").id) # restore HP self.hero.setHealth(self.hero.maxHealthPoints()) def next_dungeon(self): self.__load_dungeon(self.game_engine.get_object("dungeon").next) def __load_dungeon(self, id): self.position = (-1, -1) self.playerFacing = NORTH d = self.game_engine.get_object("dungeon") self.dungeon_id = id d.remove_from_engine() self.game_engine.remove_object("dungeon") self.game_engine.add_object("dungeon", Dungeon(self.dungeon_id)) self.remove_keys() def load_from_json_string(self, recall_string): print "TO BE IMPLEMENTED" def dump_to_json_string(self): print "TO BE IMPLEMENTED" def update_problem_stat(self, p_type, level, correct): assert p_type in self.problem_stats assert level >= 0 and level < len(self.problem_stats) - 1 correct, wrong = self.problem_stats[p_type][level] if correct: self.problem_stats[p_type][level] = (correct + 1, wrong) else: self.problem_stats[p_type][level] = (correct, wrong + 1) def move_to(self, x, y): self.position = (x, y) def turn(self, dir): if dir == RIGHT: self.playerFacing = (self.playerFacing - 1) % 4 elif dir == LEFT: self.playerFacing = (self.playerFacing + 1) % 4 def give_item(self, item): self.inventory.append(item) def remove_keys(self): i = 0 new_inv = [] for item in self.inventory: if not isinstance(item, Key): new_inv.append(item) self.inventory = new_inv def add_to_engine(self): super(Profile, self).add_to_engine() def remove_from_engine(self): super(Profile, self).remove_from_engine() def event_handler(self, event): """ Handles user input (used only for name entry) """ if event.type == pygame.KEYDOWN: if pygame.key.name(event.key) == "backspace": self.name = self.name[0:-1] return True elif pygame.key.name(event.key) == "return": self.remove_from_engine() self.name_cb() return True else: self.name += event.unicode return True def draw(self): """ Draws user input for name to the screen """ width = self.game_engine.width height = self.game_engine.height draw_width = width / 4 draw_height = height / 4 self.background.setPosition(0, 0) self.blueRect.setPosition(draw_width, draw_height) # name self.text_list[0].changeText(self.name, (0, 0, 0)) self.text_list[0].setPosition(draw_width + 60, draw_height + 60) # text1 self.text_list[1].changeText(_("Enter Name:"), (0, 0, 0)) self.text_list[1].setPosition(draw_width, draw_height) # text2 self.text_list[2].changeText(_("Return to continue"), (0, 0, 0)) self.text_list[2].setPosition(draw_width + 20, draw_height + 20)
class BattleMenuHolder(GameEngineElement): def __init__(self, callback): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.menu = None self.callback = callback self.background = DrawableObject( [pygame.image.load(MENU_PATH + "battleMenubackground.gif")], '') self.font = pygame.font.SysFont("cmr10", 18, False, False) self.disp = DrawableFontObject("", self.font) self.sec_disp = DrawableFontObject("", self.font) self.add_to_scene([self.background]) self.add_to_scene([self.disp]) self.add_to_scene([self.sec_disp]) def set_disp(self, msg): self.disp.changeText(msg, (0, 0, 0)) def set_sec_disp(self, msg): self.sec_disp.changeText(msg, (0, 0, 0)) def remove_from_engine(self): super(BattleMenuHolder, self).remove_from_engine() self.clear_menu() def draw(self): self.background.setPosition(0, 286) self.disp.setPosition(250, 340) self.sec_disp.setPosition(237, 375) def menu_called(self, id): self.callback(id, self) def clear_menu(self): if self.menu: self.menu.clear() self.menu.remove_from_engine() self.menu = None def show_menu(self, id): if self.is_in_engine(): self.clear_menu() else: self.add_to_engine() y_offset = 0 if id == "selection": menu_type = NORMAL_MENU menu_options = [ [_("Attack"), lambda: self.menu_called("attack_show"), 140, 1], [_('Special'), lambda: self.show_menu("special"), 140, 1], [_('Magic'), lambda: self.show_menu("magic"), 140, 1], [_('Scan'), lambda: self.menu_called("scan"), 140, 1], ] elif id == "attack": y_offset = 50 menu_type = GRID_MENU menu_options = [ ['1', lambda: self.menu_called('1'), 44, 1], ['2', lambda: self.menu_called('2'), 44, 1], ['3', lambda: self.menu_called('3'), 44, 1], ['4', lambda: self.menu_called('4'), 44, 1], ['5', lambda: self.menu_called('5'), 44, 1], ['6', lambda: self.menu_called('6'), 44, 1], ['7', lambda: self.menu_called('7'), 44, 1], ['8', lambda: self.menu_called('8'), 44, 1], ['9', lambda: self.menu_called('9'), 44, 1], [_("C"), lambda: self.menu_called('clear'), 44, 1], ['0', lambda: self.menu_called('0'), 44, 1], [_("E"), lambda: self.menu_called('enter'), 44, 1], ] elif id == "special": menu_type = NORMAL_MENU menu_options = [[ _("Back"), lambda: self.show_menu("selection"), 140, 1 ]] elif id == "magic": menu_type = NORMAL_MENU menu_options = [ [_("Fire"), lambda: self.menu_called("fire"), 140, 1], [ _("Lightning"), lambda: self.menu_called("lightning"), 140, 1 ], [_("Missile"), lambda: self.menu_called("missile"), 140, 1], [_("Heal"), lambda: self.menu_called("heal"), 140, 1], [_("Back"), lambda: self.show_menu("selection"), 140, 1] ] else: print "Invalid Menu", id return self.menu = BattleMenu(menu_options, 237, 375 + y_offset, menu_type)
class Map(GameEngineElement): def __init__(self, dgn): GameEngineElement.__init__(self, has_draw=True, has_event=True) self.draw_macro_set = False #A boolean value to determine whether the large map should draw self.sizeX = dgn.sizeX #A variable that represents the number of rooms wide the dungeon is self.sizeY = dgn.sizeY #A variable that represents the number of rooms tall the dungeon is self.rectSizeX = 38 #A variable representing the X size of a given room on the mini map self.rectSizeY = 38 #A variable representing the Y size of a given room on the mini map self.rects = { } #A dictionary of rectangles that represent the rooms on the map self.fullRooms = {} #A dictionary representing nothing? self.totalSurface = pygame.Surface( (self.sizeX * 40, self.sizeY * 40)) #A rect representing the size of the map as a whole #A Two dimensional For Loop that goes through all of the positions on the map. for y in range(self.sizeY): for x in range(self.sizeX): curRect = pygame.Rect( x * 40, y * 40, self.rectSizeX, self.rectSizeX ) #Creating a rectangle for the current position on the map. self.rects[( x, y )] = curRect #Adds the rectangle associated with the current position to the dictionary using the position on the map as the key. #Each 'if' tests whether there is a door in a given direction at the current position. #If there is a door in the given direction, it fills the square associated with themeans that the position has a room and fills it accordingly. if dgn.rooms.get((x, y)).get_door('N') != '0': self.fullRooms[(x, y)] = True self.totalSurface.fill((255, 255, 255), curRect, 0) elif dgn.rooms.get((x, y)).get_door('S') != '0': self.fullRooms[(x, y)] = True self.totalSurface.fill((255, 255, 255), curRect, 0) elif dgn.rooms.get((x, y)).get_door('E') != '0': self.fullRooms[(x, y)] = True self.totalSurface.fill((255, 255, 255), curRect, 0) elif dgn.rooms.get((x, y)).get_door('W') != '0': self.fullRooms[(x, y)] = True self.totalSurface.fill((255, 255, 255), curRect, 0) self.add_to_engine() #Adds itself and all callbacks to the engine self.myDrawableObject = DrawableObject([pygame.Surface((0, 0))], '') self.add_to_scene([self.myDrawableObject]) def event_handler(self, event): if event.type == pygame.KEYDOWN: newKey = pygame.key.name(event.key) if newKey == 'm' or newKey == '[7]': self.draw_macro_set = not self.draw_macro_set return True #Disable other events if macro-map set if self.draw_macro_set: return True def draw(self): profile = self.game_engine.get_object( 'profile') #Creates a copy of the profile object x, y = profile.position #Grabs the position of the player from the profiler playerFacing = profile.playerFacing #Grabs the direction the player is facing from the profiler mapView = pygame.transform.chop(self.totalSurface, (0, 0, 0, 0)) mapView.fill((255, 0, 0), (x * 40, y * 40, 38, 38)) angle = 0 if playerFacing == NORTH: angle = 0 mapView = pygame.transform.rotate(mapView, angle) angle = 90 elif playerFacing == SOUTH: angle = 180 mapView = pygame.transform.rotate(mapView, angle) angle = 270 elif playerFacing == EAST: angle = 90 mapView = pygame.transform.rotate(mapView, angle) angle = 0 elif playerFacing == WEST: angle = 270 mapView = pygame.transform.rotate(mapView, angle) angle = 180 sideDifference = self.sizeX - self.sizeY #Getting the difference between the height and width of the dungeon angle = angle * (math.pi / 180 ) #Getting the angle the dungeon is rotated to curSect = pygame.Rect(0, 0, 200, 200) #Creating the rectangle for the mini-map #Sets the position of the mini-map rectangle curSect.top += ((x * 40 - 81) * math.cos(angle)) - ( (y * 40 - 81) * math.sin(angle)) curSect.left -= ((x * 40 - 81) * math.sin(angle)) + ( (y * 40 - 81) * math.cos(angle)) if playerFacing == EAST: curSect.top += sideDifference * (40 - 81) elif playerFacing == SOUTH: curSect.left += sideDifference * (40 - 81) map_area = (0, 700, 200, 350) mini_map = pygame.Surface((200, 200)) mini_map.blit(mapView, curSect) self.myDrawableObject.repopulateImages([mini_map]) self.myDrawableObject.setPosition(0, 700) if self.draw_macro_set: self.draw_macro(self) def draw_macro(self, player): #DRAW LEGEND font = pygame.font.SysFont("cmr10", 24, False, False) macroMap = pygame.transform.scale(self.totalSurface, (self.sizeX * 100, self.sizeY * 100)) tempScreen = pygame.Surface((800, 700)) tempScreen.fill((0, 0, 0)) #screen.fill((0,0,0),(200,0,800,700)) legend = pygame.Surface((200, 300)) legend.fill((255, 0, 0), (0, 0, 40, 15)) legend.blit(font.render(_("LOCKED"), True, (255, 0, 0)), (45, 0, 30, 5)) legend.fill((150, 255, 150), (0, 25, 40, 15)) legend.blit(font.render(_("OPEN"), True, (150, 255, 150)), (45, 25, 30, 5)) legend.fill((255, 0, 255), (0, 50, 40, 15)) legend.blit(font.render(_("PUZZLE"), True, (255, 0, 255)), (45, 50, 30, 5)) legend.fill((255, 255, 255), (0, 75, 40, 15)) legend.blit(font.render(_("EXIT"), True, (255, 255, 255)), (45, 75, 30, 5)) legend.fill((50, 50, 50), (0, 100, 40, 15)) legend.blit(font.render(_("ENTRANCE"), True, (50, 50, 50)), (45, 100, 30, 5)) tempScreen.blit(macroMap, (0, 0)) tempScreen.blit(legend, (600, 0)) self.myDrawableObject.repopulateImages([tempScreen]) self.myDrawableObject.setPosition(200, 0) def update_macro(self): profile = self.game_engine.get_object('profile') x, y = profile.position playerFacing = profile.playerFacing self.totalSurface.fill((0, 255, 0), (x * 40, y * 40, 38, 38)) current_room = self.game_engine.get_object('dungeon').rooms[ profile.position] map_filler = [('N', (x * 40 + 5, y * 40, 30, 5)), ('S', (x * 40 + 5, y * 40 + 35, 30, 5)), ('E', (x * 40 + 35, y * 40 + 5, 5, 30)), ('W', (x * 40, y * 40 + 5, 5, 30))] for dir, filldata in map_filler: door_flag = current_room.get_door(dir) if door_flag == LOCKED_DOOR or door_flag == LOCKED_PUZZLE_DOOR: self.totalSurface.fill((255, 0, 0), filldata) elif door_flag == UNLOCKED_DOOR: self.totalSurface.fill((150, 255, 150), filldata) elif door_flag == PUZZLE_DOOR: self.totalSurface.fill((255, 0, 255), filldata) elif door_flag == EXIT_DOOR: self.totalSurface.fill((255, 255, 255), filldata) elif door_flag == ENTRANCE_DOOR: self.totalSurface.fill((0, 0, 0), filldata)
class GameMenuHolder( GameEngineElement ): def __init__(self, callback, background=None, width=1200, height=900): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.menu = None self.callback = callback self.background = DrawableObject([pygame.image.load(background).convert()], '') self.background.scale(width, height) self.add_to_scene([self.background]) self.width = width self.height = height def remove_from_engine(self): super( GameMenuHolder, self ).remove_from_engine() self.clear_menu() def draw(self): if self.background: self.background.setPosition(0,0) else: screen.fill((0, 0, 255)) def menu_called(self, id): self.callback(id, self) def clear_menu(self): if self.menu: self.menu.clear_menu() self.menu.remove_from_engine() self.menu = None def show_menu(self,id): if self.is_in_engine(): self.clear_menu() else: self.add_to_engine() if id == "title": menu_options = [ ["Adventure Play", lambda: self.show_menu("adventure"), "Begin a new game, create a new profile, or continue from a saved profile game"], #['Creative Play', lambda: self.show_menu("creative"), "Play custom maps and learn how to create them"], #['Network', lambda: self.show_menu("network"), "Play games with special rules or see the scoreboard"], #['Extras', lambda: self.show_menu("extras"), "View special information for the loaded player profile"], #['Options', lambda: self.menu_called("options"), "Change controls, language, difficulty, and other game settings"], #['Options', lambda: self.show_menu("options"), "Change controls, language, difficulty, and other game settings"], ['Exit Game', lambda: self.game_engine.stop_event_loop(), "Exit the game"] ] elif id == "adventure": menu_options = [ #["Continue", lambda: self.menu_called("continue"), "Continue loaded game from the latest save"], #["Level Select", lambda: self.menu_called("level"), "Play completed levels from loaded game"], #["Load Game", lambda: self.menu_called("load"), "Load player profile game data"], ["New Game", lambda: self.menu_called("new"), "Play story mode from the beginning"], #["New Player Profile", lambda: self.menu_called("newpro"), "Create a new player profile"], ["Return to Title", lambda: self.show_menu("title"), "Return to the title menu"] ] elif id == "creative": menu_options = [ ["Play Custom Map", lambda: self.menu_called("playcustom"), "NOT AVAILABLE-Play a custom made map"], ["New Custom Map", lambda: self.menu_called("newcustom"), "NOT AVAILABLE-Learn how to create your own custom map"], ["Share Map", lambda: self.menu_called("sharecustom"), "NOT AVAILABLE-Share created maps with friends"], ["Return to Title", lambda: self.show_menu("title"), "Return to the title menu"] ] elif id == "network": menu_options = [ ["Local Treasure Trekkers Play", lambda: self.menu_called("networktreasure"), "NOT AVAILABLE-Play a special time trial version of Fortune Hunter"], ["View Scoreboard", lambda: self.menu_called("networkscore"), "NOT AVAILABLE-View the scoreboard for your team"], ["Return to Title", lambda: self.show_menu("title"), "Return to the title menu"] ] elif id == "extras": menu_options = [ ["View Bestiary", lambda: self.menu_called("viewbestiary"), "NOT AVAILABLE-View monster information"], ["View Treasures", lambda: self.menu_called("viewtreasures"), "NOT AVAILABLE-View collected treasures"], ["View Awards", lambda: self.menu_called("viewawards"), "NOT AVAILABLE-View awards"], ["View Statistics", lambda: self.menu_called("viewstats"), "NOT AVAILABLE-View statistics"], ["Return to Title", lambda: self.show_menu("title"), "Return to the title menu"] ] elif id == "options": menu_options = [ ["Controls", lambda: self.menu_called("controls"), "NOT AVAILABLE-Change control scheme"], ["Language", lambda: self.menu_called("language"), "NOT AVAILABLE-Change language setting"], ["Audio", lambda: self.menu_called("audiu"), "NOT AVAILABLE-Toggle audio on or off"], ["Subtitles", lambda: self.menu_called("subtitles"), "NOT AVAILABLE-Toggle subtitles on or off"], ["FMCs", lambda: self.menu_called("fmcs"), "NOT AVAILABLE-Toggle FMCs on or off"], ["Cooperative Play", lambda: self.menu_called("coop"), "NOT AVAILABLE-Toggle coop mode on or off"], ["Game Difficulty", lambda: self.menu_called("difficulty"), "NOT AVAILABLE-Change the game difficulty setting"], ["Merchant Difficulty", lambda: self.menu_called("merchant"), "NOT AVAILABLE-Change the merchant difficulty setting"], ["Credits", lambda: self.menu_called("credits"), "NOT AVAILABLE-Watch the credits reel"], ["About", lambda: self.menu_called("about"), "NOT AVAILABLE-Information on game and version"], ["Return to Title", lambda: self.show_menu("title"), "Return to the title menu"] ] else: print "Invalid Menu", id return self.menu = GameMenu(menu_options, self.width, self.height)
class Menu(object): def __init__(self, options, spelltype, magic_list, scene): """Initialize the EzMenu! options should be a sequence of lists in the format of [option_name, option_function]""" self.scene = scene self.buttons = [] self.options = options self.x = 0 self.y = 0 self.cols = 2 self.option = 0 self.width = 2 self.spelltype = spelltype self.magic_list = magic_list self.reference = [] lightning = [] fire = [] missile = [] heal = [] fire = Spritesheet(PUZZLE_PATH + "FireGlyph.gif").img_extract( 2, 2, 150, 150, (255, 0, 255)) lightning = Spritesheet(PUZZLE_PATH + "LightningGlyph.gif").img_extract( 2, 2, 150, 150, (255, 0, 255)) missile = Spritesheet(PUZZLE_PATH + "MissileGlyph.gif").img_extract( 2, 2, 150, 150, (255, 0, 255)) heal = Spritesheet(PUZZLE_PATH + "HealGlyph.gif").img_extract( 2, 2, 150, 150, (255, 0, 255)) if (spelltype == 0): #fire attack for i in range(4): self.buttons.append( DrawableObject([pygame.transform.scale(fire[i], (60, 60))], "")) #filler buttons for i in range(0, 2): self.buttons.append( DrawableObject( [pygame.transform.scale(lightning[i], (60, 60))], "")) random.seed() self.buttons.append( DrawableObject([ pygame.transform.scale(heal[random.randint(0, 3)], (60, 60)) ], "")) self.buttons.append( DrawableObject([ pygame.transform.scale(missile[random.randint(0, 3)], (60, 60)) ], "")) self.mainGlyph = pygame.image.load( PUZZLE_PATH + "FireGlyph.gif").convert_alpha() self.glyphs = fire elif (spelltype == 1): #lightning attack for i in range(4): self.buttons.append( DrawableObject( [pygame.transform.scale(lightning[i], (60, 60))], "")) #filler buttons for i in range(0, 2): self.buttons.append( DrawableObject([pygame.transform.scale(fire[i], (60, 60))], "")) random.seed() self.buttons.append( DrawableObject([ pygame.transform.scale(heal[random.randint(0, 3)], (60, 60)) ], "")) self.buttons.append( DrawableObject([ pygame.transform.scale(missile[random.randint(0, 3)], (60, 60)) ], "")) self.mainGlyph = pygame.image.load( PUZZLE_PATH + "LightningGlyph.gif").convert_alpha() self.glyphs = lightning elif (spelltype == 2): #missile attack for i in range(4): self.buttons.append( DrawableObject( [pygame.transform.scale(missile[i], (60, 60))], "")) #filler buttons for i in range(0, 2): self.buttons.append( DrawableObject( [pygame.transform.scale(lightning[i], (60, 60))], "")) random.seed() self.buttons.append( DrawableObject([ pygame.transform.scale(heal[random.randint(0, 3)], (60, 60)) ], "")) self.buttons.append( DrawableObject([ pygame.transform.scale(fire[random.randint(0, 3)], (60, 60)) ], "")) self.mainGlyph = pygame.image.load( PUZZLE_PATH + "MissileGlyph.gif").convert_alpha() self.glyphs = missile elif (spelltype == 3): #heal for i in range(4): self.buttons.append( DrawableObject([pygame.transform.scale(heal[i], (60, 60))], "")) #filler buttons for i in range(0, 2): self.buttons.append( DrawableObject( [pygame.transform.scale(lightning[i], (60, 60))], "")) random.seed() self.buttons.append( DrawableObject([ pygame.transform.scale(missile[random.randint(0, 3)], (60, 60)) ], "")) self.buttons.append( DrawableObject([ pygame.transform.scale(fire[random.randint(0, 3)], (60, 60)) ], "")) self.mainGlyph = pygame.image.load( PUZZLE_PATH + "HealGlyph.gif").convert_alpha() self.glyphs = heal deck = [0, 1, 2, 3, 4, 5, 6, 7] random.seed() random.shuffle(deck) tOptions = [] tButtons = [] for i in range(8): tOptions.append(self.options[deck[i]]) tButtons.append(self.buttons[deck[i]]) self.buttons = tButtons self.options = tOptions surf = pygame.Surface((60, 60)) surf.fill((4, 119, 152)) self.selectRect = DynamicDrawableObject([surf], "") self.selectRect.setPosition(297, 435) self.scene.addObject(self.selectRect) self.scene.addObjects(self.buttons) self.mainGlyph.set_colorkey((255, 0, 255), pygame.RLEACCEL) self.mainGlyphDO = DrawableObject([self.mainGlyph], "") self.mainGlyphDO.setPosition(485, 350) for image in self.glyphs: tempDO = DrawableObject([image], "", True) #tempDO.makeTransparent(True) self.reference.append(tempDO) self.scene.addObjects(self.reference) self.scene.addObject(self.mainGlyphDO) self.height = (len(self.options) * self.buttons[1].getYSize()) / self.cols def draw(self): """Draw the menu to the surface.""" i = 0 # Row Spacing h = 0 # Selection Spacing j = 0 # Col Spacing index = 0 #current spot in buttons list height = 60 width = 60 for o in self.options: newX = self.x + width * j newY = self.y + i * height if h == self.option: self.selectRect.setPosition(newX, newY) self.buttons[index].setPosition(newX, newY) j += 1 h += 1 index += 1 if j >= self.cols: i += 1 j = 0 # Draw reference glyphs for i in range(4): if i in self.magic_list: self.reference[i].makeTransparent(False) self.reference[i].setPosition(800 + ((i % 2) * 150), 350 + (i / 2 * 150)) def update(self, event): """Update the menu and get input for the menu.""" return_val = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_DOWN: if self.cols != 1: self.option += self.cols else: self.option += 1 return_val = True elif event.key == pygame.K_UP: if self.cols != 1: self.option -= self.cols else: self.option -= 1 return_val = True elif event.key == pygame.K_RIGHT: if self.cols != 1: self.option += 1 return_val = True elif event.key == pygame.K_LEFT: if self.cols != 1: self.option -= 1 return_val = True elif event.key == pygame.K_RETURN: self.options[self.option][1]() return_val = True self.option = self.option % len(self.options) return return_val def clear(self): for object in self.buttons: self.scene.removeObject(object) for object in self.reference: self.scene.removeObject(object) self.scene.removeObject(self.mainGlyphDO) self.scene.removeObject(self.selectRect) def set_pos(self, x, y): """Set the topleft of the menu at x,y""" self.x = x self.y = y
class MagicMenuHolder(GameEngineElement): def __init__(self, callback): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.menu = None self.callback = callback self.background = DrawableObject( [pygame.image.load(MENU_PATH + "battleMenubackground.gif")], '') self.background.setPosition(0, 286) self.add_to_scene([self.background]) def remove_from_engine(self): #self.game_engine.get_scene().removeObject(self.background) super(MagicMenuHolder, self).remove_from_engine() self.clear_menu() def draw(self): pass def menu_called(self, id): self.callback(id, self) def clear_menu(self): if self.menu: self.menu.clear() self.menu.remove_from_engine() self.menu = None def show_menu(self, id): if self.is_in_engine(): self.clear_menu() else: self.add_to_engine() if id == "fire": spell_type = 0 menu_options = [ [_('1'), lambda: self.menu_called("fire1"), 140], [_('2'), lambda: self.menu_called("fire2"), 140], [_('3'), lambda: self.menu_called("fire3"), 140], [_('4'), lambda: self.menu_called("fire4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] elif id == "lightning": spell_type = 1 menu_options = [ [_('1'), lambda: self.menu_called("lig1"), 140], [_('2'), lambda: self.menu_called("lig2"), 140], [_('3'), lambda: self.menu_called("lig3"), 140], [_('4'), lambda: self.menu_called("lig4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] elif id == "missile": spell_type = 2 menu_options = [ [_('1'), lambda: self.menu_called("miss1"), 140], [_('2'), lambda: self.menu_called("miss2"), 140], [_('3'), lambda: self.menu_called("miss3"), 140], [_('4'), lambda: self.menu_called("miss4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] elif id == "heal": spell_type = 3 menu_options = [ [_('1'), lambda: self.menu_called("heal1"), 140], [_('2'), lambda: self.menu_called("heal2"), 140], [_('3'), lambda: self.menu_called("heal3"), 140], [_('4'), lambda: self.menu_called("heal4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] self.menu = MagicMenu(menu_options, 237, 375, spell_type)
class BattleMenuHolder( GameEngineElement ): def __init__(self, callback): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.menu = None self.callback = callback self.background = DrawableObject([pygame.image.load( MENU_PATH + "battleMenubackground.gif")], '') self.font = pygame.font.SysFont("cmr10",18,False,False) self.disp = DrawableFontObject("", self.font) self.sec_disp = DrawableFontObject("", self.font) self.add_to_scene([self.background]) self.add_to_scene([self.disp]) self.add_to_scene([self.sec_disp]) def set_disp(self, msg): self.disp.changeText(msg, (0,0,0)) def set_sec_disp(self, msg): self.sec_disp.changeText(msg, (0,0,0)) def remove_from_engine(self): super( BattleMenuHolder, self ).remove_from_engine() self.clear_menu() def draw(self): self.background.setPosition(0,286) self.disp.setPosition(250,340) self.sec_disp.setPosition(237, 375) def menu_called(self, id): self.callback(id, self) def clear_menu(self): if self.menu: self.menu.clear() self.menu.remove_from_engine() self.menu = None def show_menu(self,id): if self.is_in_engine(): self.clear_menu() else: self.add_to_engine() y_offset = 0 if id == "selection": menu_type = NORMAL_MENU menu_options = [ [_("Attack"), lambda: self.menu_called("attack_show"), 140,1], [_('Special'), lambda: self.show_menu("special"), 140,1], [_('Magic'), lambda: self.show_menu("magic"), 140,1], [_('Scan'), lambda: self.menu_called("scan"), 140,1], ] elif id == "attack": y_offset = 50 menu_type = GRID_MENU menu_options = [ ['1', lambda: self.menu_called('1'),44,1], ['2', lambda: self.menu_called('2'),44,1], ['3', lambda: self.menu_called('3'),44,1], ['4', lambda: self.menu_called('4'),44,1], ['5', lambda: self.menu_called('5'),44,1], ['6', lambda: self.menu_called('6'),44,1], ['7', lambda: self.menu_called('7'),44,1], ['8', lambda: self.menu_called('8'),44,1], ['9', lambda: self.menu_called('9'),44,1], [_("C"), lambda: self.menu_called('clear'),44,1], ['0', lambda: self.menu_called('0'),44,1], [_("E"), lambda: self.menu_called('enter'),44,1], ] elif id == "special": menu_type = NORMAL_MENU menu_options = [ [_("Back"), lambda: self.show_menu("selection"),140,1] ] elif id == "magic": menu_type = NORMAL_MENU menu_options = [ [_("Fire"), lambda: self.menu_called("fire"), 140, 1], [_("Lightning"), lambda: self.menu_called("lightning"), 140, 1], [_("Missile"), lambda: self.menu_called("missile"), 140, 1], [_("Heal"), lambda: self.menu_called("heal"), 140, 1], [_("Back"), lambda: self.show_menu("selection"), 140, 1] ] else: print "Invalid Menu", id return self.menu = BattleMenu(menu_options, 237, 375+y_offset, menu_type)
class Profile(GameEngineElement): def __init__(self, recall_string=None, name_entry_cb=None): GameEngineElement.__init__(self) self.name = "" self.dungeon_id = "al1.txt" self.position = (-1, -1) self.playerFacing = NORTH self.hero = Hero() # 4 types of stats and difficulties self.problem_stats = {} self.difficulty = {} for stat in ['mult', 'div', 'geo', 'shop']: # Each type of stat has 3 "levels" easy, medium, hard # Shop uses level for too much, too little, exact self.problem_stats[stat] = [(0, 0), (0, 0), (0, 0)] #Difficulty: 1=Easy 2=Meduim(default) 3=Hard self.difficulty[stat] = 2 self.puzzlesSolved = 0 self.inventory = [] bg = pygame.image.load(MENU_PATH + "mafh_splash.gif").convert() self.background = DrawableObject([bg], '') self.background.scale(self.game_engine.width, self.game_engine.height) self.add_to_scene([self.background]) #create background rect draw_width = self.game_engine.width / 4 draw_height = self.game_engine.height / 4 surf = pygame.Surface((draw_width + 60, draw_height + 60)) surf.fill((150, 150, 255)) self.blueRect = DrawableObject([surf], "") self.add_to_scene([self.blueRect]) font = pygame.font.Font(None, 16) self.text_list = [] self.text_list.append(DrawableFontObject("1", font)) self.text_list.append(DrawableFontObject("2", font)) self.text_list.append(DrawableFontObject("name", font)) self.add_to_scene(self.text_list) if recall_string: self.load_from_json_string(recall_string) if self.name == "": self.name_cb = name_entry_cb self.add_to_engine() def reload_dungeon(self): self.__load_dungeon(self.game_engine.get_object('dungeon').id) #restore HP self.hero.setHealth(self.hero.maxHealthPoints()) def next_dungeon(self): self.__load_dungeon(self.game_engine.get_object('dungeon').next) def __load_dungeon(self, id): self.position = (-1, -1) self.playerFacing = NORTH d = self.game_engine.get_object('dungeon') self.dungeon_id = id d.remove_from_engine() self.game_engine.remove_object('dungeon') self.game_engine.add_object('dungeon', Dungeon(self.dungeon_id)) self.remove_keys() def load_from_json_string(self, recall_string): print "TO BE IMPLEMENTED" def dump_to_json_string(self): print "TO BE IMPLEMENTED" def update_problem_stat(self, p_type, level, correct): assert (p_type in self.problem_stats) assert (level >= 0 and level < len(self.problem_stats) - 1) correct, wrong = self.problem_stats[p_type][level] if correct: self.problem_stats[p_type][level] = (correct + 1, wrong) else: self.problem_stats[p_type][level] = (correct, wrong + 1) def move_to(self, x, y): self.position = (x, y) def turn(self, dir): if dir == RIGHT: self.playerFacing = (self.playerFacing - 1) % 4 elif dir == LEFT: self.playerFacing = (self.playerFacing + 1) % 4 def give_item(self, item): self.inventory.append(item) def remove_keys(self): i = 0 new_inv = [] for item in self.inventory: if not isinstance(item, Key): new_inv.append(item) self.inventory = new_inv def add_to_engine(self): super(Profile, self).add_to_engine() def remove_from_engine(self): super(Profile, self).remove_from_engine() def event_handler(self, event): """ Handles user input (used only for name entry) """ if event.type == pygame.KEYDOWN: if pygame.key.name(event.key) == 'backspace': self.name = self.name[0:-1] return True elif pygame.key.name(event.key) == 'return': self.remove_from_engine() self.name_cb() return True else: self.name += event.unicode return True def draw(self): """ Draws user input for name to the screen """ width = self.game_engine.width height = self.game_engine.height draw_width = width / 4 draw_height = height / 4 self.background.setPosition(0, 0) self.blueRect.setPosition(draw_width, draw_height) #name self.text_list[0].changeText(self.name, (0, 0, 0)) self.text_list[0].setPosition(draw_width + 60, draw_height + 60) #text1 self.text_list[1].changeText(_("Enter Name:"), (0, 0, 0)) self.text_list[1].setPosition(draw_width, draw_height) #text2 self.text_list[2].changeText(_("Return to continue"), (0, 0, 0)) self.text_list[2].setPosition(draw_width + 20, draw_height + 20)
class GameMenuHolder(GameEngineElement): def __init__(self, callback, background=None, width=1200, height=900): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.menu = None self.callback = callback self.background = DrawableObject( [pygame.image.load(background).convert()], '') self.background.scale(width, height) self.add_to_scene([self.background]) self.width = width self.height = height def remove_from_engine(self): super(GameMenuHolder, self).remove_from_engine() self.clear_menu() def draw(self): if self.background: self.background.setPosition(0, 0) else: screen.fill((0, 0, 255)) def menu_called(self, id): self.callback(id, self) def clear_menu(self): if self.menu: self.menu.clear_menu() self.menu.remove_from_engine() self.menu = None def show_menu(self, id): if self.is_in_engine(): self.clear_menu() else: self.add_to_engine() if id == "title": menu_options = [ [ "Adventure Play", lambda: self.show_menu("adventure"), "Begin a new game, create a new profile, or continue from a saved profile game" ], #['Creative Play', lambda: self.show_menu("creative"), "Play custom maps and learn how to create them"], #['Network', lambda: self.show_menu("network"), "Play games with special rules or see the scoreboard"], #['Extras', lambda: self.show_menu("extras"), "View special information for the loaded player profile"], #['Options', lambda: self.menu_called("options"), "Change controls, language, difficulty, and other game settings"], #['Options', lambda: self.show_menu("options"), "Change controls, language, difficulty, and other game settings"], [ 'Exit Game', lambda: self.game_engine.stop_event_loop(), "Exit the game" ] ] elif id == "adventure": menu_options = [ #["Continue", lambda: self.menu_called("continue"), "Continue loaded game from the latest save"], #["Level Select", lambda: self.menu_called("level"), "Play completed levels from loaded game"], #["Load Game", lambda: self.menu_called("load"), "Load player profile game data"], [ "New Game", lambda: self.menu_called("new"), "Play story mode from the beginning" ], #["New Player Profile", lambda: self.menu_called("newpro"), "Create a new player profile"], [ "Return to Title", lambda: self.show_menu("title"), "Return to the title menu" ] ] elif id == "creative": menu_options = [ [ "Play Custom Map", lambda: self.menu_called("playcustom"), "NOT AVAILABLE-Play a custom made map" ], [ "New Custom Map", lambda: self.menu_called("newcustom"), "NOT AVAILABLE-Learn how to create your own custom map" ], [ "Share Map", lambda: self.menu_called("sharecustom"), "NOT AVAILABLE-Share created maps with friends" ], [ "Return to Title", lambda: self.show_menu("title"), "Return to the title menu" ] ] elif id == "network": menu_options = [[ "Local Treasure Trekkers Play", lambda: self.menu_called("networktreasure"), "NOT AVAILABLE-Play a special time trial version of Fortune Hunter" ], [ "View Scoreboard", lambda: self.menu_called("networkscore"), "NOT AVAILABLE-View the scoreboard for your team" ], [ "Return to Title", lambda: self.show_menu("title"), "Return to the title menu" ]] elif id == "extras": menu_options = [[ "View Bestiary", lambda: self.menu_called("viewbestiary"), "NOT AVAILABLE-View monster information" ], [ "View Treasures", lambda: self.menu_called("viewtreasures"), "NOT AVAILABLE-View collected treasures" ], [ "View Awards", lambda: self.menu_called("viewawards"), "NOT AVAILABLE-View awards" ], [ "View Statistics", lambda: self.menu_called("viewstats"), "NOT AVAILABLE-View statistics" ], [ "Return to Title", lambda: self.show_menu("title"), "Return to the title menu" ]] elif id == "options": menu_options = [ [ "Controls", lambda: self.menu_called("controls"), "NOT AVAILABLE-Change control scheme" ], [ "Language", lambda: self.menu_called("language"), "NOT AVAILABLE-Change language setting" ], [ "Audio", lambda: self.menu_called("audiu"), "NOT AVAILABLE-Toggle audio on or off" ], [ "Subtitles", lambda: self.menu_called("subtitles"), "NOT AVAILABLE-Toggle subtitles on or off" ], [ "FMCs", lambda: self.menu_called("fmcs"), "NOT AVAILABLE-Toggle FMCs on or off" ], [ "Cooperative Play", lambda: self.menu_called("coop"), "NOT AVAILABLE-Toggle coop mode on or off" ], [ "Game Difficulty", lambda: self.menu_called("difficulty"), "NOT AVAILABLE-Change the game difficulty setting" ], [ "Merchant Difficulty", lambda: self.menu_called("merchant"), "NOT AVAILABLE-Change the merchant difficulty setting" ], [ "Credits", lambda: self.menu_called("credits"), "NOT AVAILABLE-Watch the credits reel" ], [ "About", lambda: self.menu_called("about"), "NOT AVAILABLE-Information on game and version" ], [ "Return to Title", lambda: self.show_menu("title"), "Return to the title menu" ] ] else: print "Invalid Menu", id return self.menu = GameMenu(menu_options, self.width, self.height)
class Map(GameEngineElement): def __init__(self, dgn): GameEngineElement.__init__(self, has_draw=True, has_event=True) self.draw_macro_set = False #A boolean value to determine whether the large map should draw self.sizeX=dgn.sizeX #A variable that represents the number of rooms wide the dungeon is self.sizeY=dgn.sizeY #A variable that represents the number of rooms tall the dungeon is self.rectSizeX=38 #A variable representing the X size of a given room on the mini map self.rectSizeY=38 #A variable representing the Y size of a given room on the mini map self.rects={} #A dictionary of rectangles that represent the rooms on the map self.fullRooms={} #A dictionary representing nothing? self.totalSurface=pygame.Surface((self.sizeX*40,self.sizeY*40)) #A rect representing the size of the map as a whole #A Two dimensional For Loop that goes through all of the positions on the map. for y in range(self.sizeY): for x in range(self.sizeX): curRect=pygame.Rect(x*40,y*40,self.rectSizeX,self.rectSizeX) #Creating a rectangle for the current position on the map. self.rects[(x,y)]=curRect #Adds the rectangle associated with the current position to the dictionary using the position on the map as the key. #Each 'if' tests whether there is a door in a given direction at the current position. #If there is a door in the given direction, it fills the square associated with themeans that the position has a room and fills it accordingly. if dgn.rooms.get((x,y)).get_door('N') != '0': self.fullRooms[(x,y)]=True self.totalSurface.fill((255,255,255),curRect,0) elif dgn.rooms.get((x,y)).get_door('S') != '0': self.fullRooms[(x,y)]=True self.totalSurface.fill((255,255,255),curRect,0) elif dgn.rooms.get((x,y)).get_door('E') != '0': self.fullRooms[(x,y)]=True self.totalSurface.fill((255,255,255),curRect,0) elif dgn.rooms.get((x,y)).get_door('W') != '0': self.fullRooms[(x,y)]=True self.totalSurface.fill((255,255,255),curRect,0) self.add_to_engine() #Adds itself and all callbacks to the engine self.myDrawableObject = DrawableObject([pygame.Surface((0,0))], '') self.add_to_scene([self.myDrawableObject]) def event_handler(self, event): if event.type == pygame.KEYDOWN: newKey=pygame.key.name(event.key) if newKey=='m' or newKey=='[7]': self.draw_macro_set = not self.draw_macro_set return True #Disable other events if macro-map set if self.draw_macro_set: return True def draw(self): profile = self.game_engine.get_object('profile') #Creates a copy of the profile object x, y = profile.position #Grabs the position of the player from the profiler playerFacing = profile.playerFacing #Grabs the direction the player is facing from the profiler mapView=pygame.transform.chop(self.totalSurface,(0,0,0,0)) mapView.fill((255,0,0),( x * 40, y * 40,38,38)) angle = 0 if playerFacing==NORTH: angle=0 mapView=pygame.transform.rotate(mapView,angle) angle=90 elif playerFacing==SOUTH: angle=180 mapView=pygame.transform.rotate(mapView,angle) angle=270 elif playerFacing==EAST: angle=90 mapView=pygame.transform.rotate(mapView,angle) angle=0 elif playerFacing==WEST: angle=270 mapView=pygame.transform.rotate(mapView,angle) angle=180 sideDifference=self.sizeX-self.sizeY #Getting the difference between the height and width of the dungeon angle=angle*(math.pi/180) #Getting the angle the dungeon is rotated to curSect=pygame.Rect(0,0,200,200) #Creating the rectangle for the mini-map #Sets the position of the mini-map rectangle curSect.top+=((x*40-81)*math.cos(angle))-((y*40-81)*math.sin(angle)) curSect.left-=((x*40-81)*math.sin(angle))+((y*40-81)*math.cos(angle)) if playerFacing==EAST: curSect.top+=sideDifference*(40-81) elif playerFacing==SOUTH: curSect.left+=sideDifference*(40-81) map_area = (0,700,200,350) mini_map = pygame.Surface( (200,200) ) mini_map.blit( mapView, curSect ) self.myDrawableObject.repopulateImages([mini_map]) self.myDrawableObject.setPosition(0,700) if self.draw_macro_set: self.draw_macro(self) def draw_macro(self,player): #DRAW LEGEND font=pygame.font.SysFont("cmr10",24,False,False) macroMap=pygame.transform.scale(self.totalSurface,(self.sizeX*100,self.sizeY*100)) tempScreen = pygame.Surface((800,700)) tempScreen.fill((0,0,0)) #screen.fill((0,0,0),(200,0,800,700)) legend=pygame.Surface((200,300)) legend.fill((255,0,0),(0,0,40,15)) legend.blit(font.render(_("LOCKED"),True,(255,0,0)),(45,0,30,5)) legend.fill((150,255,150),(0,25,40,15)) legend.blit(font.render(_("OPEN"),True,(150,255,150)),(45,25,30,5)) legend.fill((255,0,255),(0,50,40,15)) legend.blit(font.render(_("PUZZLE"),True,(255,0,255)),(45,50,30,5)) legend.fill((255,255,255),(0,75,40,15)) legend.blit(font.render(_("EXIT"),True,(255,255,255)),(45,75,30,5)) legend.fill((50,50,50),(0,100,40,15)) legend.blit(font.render(_("ENTRANCE"),True,(50,50,50)),(45,100,30,5)) tempScreen.blit(macroMap, (0,0)) tempScreen.blit(legend, (600,0)) self.myDrawableObject.repopulateImages([tempScreen]) self.myDrawableObject.setPosition(200,0) def update_macro(self): profile = self.game_engine.get_object('profile') x, y = profile.position playerFacing = profile.playerFacing self.totalSurface.fill((0,255,0),( x * 40, y * 40,38,38)) current_room = self.game_engine.get_object('dungeon').rooms[profile.position] map_filler = [ ('N',(x * 40+5, y * 40,30,5) ), ('S',(x * 40+5, y * 40+35,30,5) ), ('E',(x * 40+35, y * 40+5,5,30) ), ('W',(x * 40, y * 40+5,5,30) ) ] for dir, filldata in map_filler: door_flag = current_room.get_door( dir ) if door_flag == LOCKED_DOOR or door_flag == LOCKED_PUZZLE_DOOR: self.totalSurface.fill( (255,0,0), filldata) elif door_flag == UNLOCKED_DOOR: self.totalSurface.fill((150,255,150), filldata) elif door_flag == PUZZLE_DOOR: self.totalSurface.fill((255,0,255), filldata) elif door_flag == EXIT_DOOR: self.totalSurface.fill((255,255,255), filldata) elif door_flag == ENTRANCE_DOOR: self.totalSurface.fill((0,0,0), filldata)
class Menu(object): def __init__(self, options, spelltype, magic_list, scene): """Initialize the EzMenu! options should be a sequence of lists in the format of [option_name, option_function]""" self.scene = scene self.buttons = [] self.options = options self.x = 0 self.y = 0 self.cols = 2 self.option = 0 self.width = 2 self.spelltype = spelltype self.magic_list = magic_list self.reference = [] lightning = [] fire = [] missile = [] heal = [] fire = Spritesheet(PUZZLE_PATH + "FireGlyph.gif").img_extract(2,2,150,150,(255,0,255)) lightning = Spritesheet(PUZZLE_PATH + "LightningGlyph.gif").img_extract(2,2,150,150,(255,0,255)) missile = Spritesheet(PUZZLE_PATH + "MissileGlyph.gif").img_extract(2,2,150,150,(255,0,255)) heal = Spritesheet(PUZZLE_PATH + "HealGlyph.gif").img_extract(2,2,150,150,(255,0,255)) if(spelltype == 0): #fire attack for i in range(4): self.buttons.append(DrawableObject([pygame.transform.scale(fire[i] , (60,60))], "")) #filler buttons for i in range(0,2): self.buttons.append(DrawableObject([pygame.transform.scale(lightning[i] , (60,60))], "")) random.seed() self.buttons.append(DrawableObject([pygame.transform.scale(heal[random.randint(0,3)] , (60,60))], "")) self.buttons.append(DrawableObject([pygame.transform.scale(missile[random.randint(0,3)] , (60,60))], "")) self.mainGlyph = pygame.image.load(PUZZLE_PATH + "FireGlyph.gif").convert_alpha() self.glyphs = fire elif(spelltype == 1): #lightning attack for i in range(4): self.buttons.append(DrawableObject([pygame.transform.scale(lightning[i] , (60,60))], "")) #filler buttons for i in range(0,2): self.buttons.append(DrawableObject([pygame.transform.scale(fire[i] , (60,60))], "")) random.seed() self.buttons.append(DrawableObject([pygame.transform.scale(heal[random.randint(0,3)] , (60,60))], "")) self.buttons.append(DrawableObject([pygame.transform.scale(missile[random.randint(0,3)] , (60,60))], "")) self.mainGlyph = pygame.image.load(PUZZLE_PATH + "LightningGlyph.gif").convert_alpha() self.glyphs = lightning elif(spelltype == 2): #missile attack for i in range(4): self.buttons.append(DrawableObject([pygame.transform.scale(missile[i] , (60,60))], "")) #filler buttons for i in range(0,2): self.buttons.append(DrawableObject([pygame.transform.scale(lightning[i] , (60,60))], "")) random.seed() self.buttons.append(DrawableObject([pygame.transform.scale(heal[random.randint(0,3)] , (60,60))], "")) self.buttons.append(DrawableObject([pygame.transform.scale(fire[random.randint(0,3)] , (60,60))], "")) self.mainGlyph = pygame.image.load(PUZZLE_PATH + "MissileGlyph.gif").convert_alpha() self.glyphs = missile elif(spelltype == 3): #heal for i in range(4): self.buttons.append(DrawableObject([pygame.transform.scale(heal[i] , (60,60))], "")) #filler buttons for i in range(0,2): self.buttons.append(DrawableObject([pygame.transform.scale(lightning[i] , (60,60))], "")) random.seed() self.buttons.append(DrawableObject([pygame.transform.scale(missile[random.randint(0,3)] , (60,60))], "")) self.buttons.append(DrawableObject([pygame.transform.scale(fire[random.randint(0,3)] , (60,60))], "")) self.mainGlyph = pygame.image.load(PUZZLE_PATH + "HealGlyph.gif").convert_alpha() self.glyphs = heal deck = [0,1,2,3,4,5,6,7] random.seed() random.shuffle(deck) tOptions = [] tButtons = [] for i in range(8): tOptions.append(self.options[deck[i]]) tButtons.append(self.buttons[deck[i]]) self.buttons = tButtons self.options = tOptions surf = pygame.Surface((60,60)) surf.fill((4, 119, 152)) self.selectRect = DynamicDrawableObject([surf],"") self.selectRect.setPosition(297, 435) self.scene.addObject(self.selectRect) self.scene.addObjects(self.buttons) self.mainGlyph.set_colorkey((255,0,255), pygame.RLEACCEL) self.mainGlyphDO = DrawableObject([self.mainGlyph],"") self.mainGlyphDO.setPosition(485,350) for image in self.glyphs: tempDO = DrawableObject([image],"",True) #tempDO.makeTransparent(True) self.reference.append(tempDO) self.scene.addObjects(self.reference) self.scene.addObject(self.mainGlyphDO) self.height = (len(self.options)*self.buttons[1].getYSize()) / self.cols def draw(self): """Draw the menu to the surface.""" i=0 # Row Spacing h=0 # Selection Spacing j=0 # Col Spacing index=0 #current spot in buttons list height = 60 width = 60 for o in self.options: newX = self.x + width * j newY = self.y + i * height if h==self.option: self.selectRect.setPosition(newX, newY) self.buttons[index].setPosition(newX, newY) j+=1 h+=1 index+=1 if j >= self.cols: i+=1 j=0 # Draw reference glyphs for i in range(4): if i in self.magic_list: self.reference[i].makeTransparent(False) self.reference[i].setPosition(800+((i%2) * 150), 350+(i/2 * 150)) def update(self, event): """Update the menu and get input for the menu.""" return_val = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_DOWN: if self.cols != 1: self.option += self.cols else: self.option += 1 return_val = True elif event.key == pygame.K_UP: if self.cols != 1: self.option -= self.cols else: self.option -= 1 return_val = True elif event.key == pygame.K_RIGHT: if self.cols != 1: self.option += 1 return_val = True elif event.key == pygame.K_LEFT: if self.cols != 1: self.option -= 1 return_val = True elif event.key == pygame.K_RETURN: self.options[self.option][1]() return_val = True self.option = self.option % len(self.options) return return_val def clear(self): for object in self.buttons: self.scene.removeObject(object) for object in self.reference: self.scene.removeObject(object) self.scene.removeObject(self.mainGlyphDO) self.scene.removeObject(self.selectRect) def set_pos(self, x, y): """Set the topleft of the menu at x,y""" self.x = x self.y = y
class MagicMenuHolder( GameEngineElement ): def __init__(self, callback): GameEngineElement.__init__(self, has_draw=True, has_event=False) self.menu = None self.callback = callback self.background = DrawableObject([pygame.image.load( MENU_PATH + "battleMenubackground.gif")], '') self.background.setPosition(0,286) self.add_to_scene([self.background]) def remove_from_engine(self): #self.game_engine.get_scene().removeObject(self.background) super( MagicMenuHolder, self ).remove_from_engine() self.clear_menu() def draw(self): pass def menu_called(self, id): self.callback(id, self) def clear_menu(self): if self.menu: self.menu.clear() self.menu.remove_from_engine() self.menu = None def show_menu(self,id): if self.is_in_engine(): self.clear_menu() else: self.add_to_engine() if id == "fire": spell_type = 0 menu_options = [ [_('1'), lambda: self.menu_called("fire1"), 140], [_('2'), lambda: self.menu_called("fire2"), 140], [_('3'), lambda: self.menu_called("fire3"), 140], [_('4'), lambda: self.menu_called("fire4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] elif id == "lightning": spell_type = 1 menu_options = [ [_('1'), lambda: self.menu_called("lig1"), 140], [_('2'), lambda: self.menu_called("lig2"), 140], [_('3'), lambda: self.menu_called("lig3"), 140], [_('4'), lambda: self.menu_called("lig4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] elif id == "missile": spell_type = 2 menu_options = [ [_('1'), lambda: self.menu_called("miss1"), 140], [_('2'), lambda: self.menu_called("miss2"), 140], [_('3'), lambda: self.menu_called("miss3"), 140], [_('4'), lambda: self.menu_called("miss4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] elif id == "heal": spell_type = 3 menu_options = [ [_('1'), lambda: self.menu_called("heal1"), 140], [_('2'), lambda: self.menu_called("heal2"), 140], [_('3'), lambda: self.menu_called("heal3"), 140], [_('4'), lambda: self.menu_called("heal4"), 140], [_('5'), lambda: self.menu_called("wrongchoice"), 140], [_('6'), lambda: self.menu_called("wrongchoice"), 140], [_('7'), lambda: self.menu_called("wrongchoice"), 140], [_('8'), lambda: self.menu_called("wrongchoice"), 140] ] self.menu = MagicMenu(menu_options, 237, 375, spell_type)