def __init__(self): super(MapUI, self).__init__() self.config_manager = self.get_main().config_manager self.get_main().fonts.register_font("debug") self.debug_font = self.get_main().fonts["debug"] self.map = DungeonMap(self.config_manager) self.draw_rects = False self.draw_debug = self.config_manager.config_data["subscription_config"]["draw_debug"] self.speedup = self.config_manager.config_data["video_config"]["speedup"] self.demo_mode = self.config_manager.config_data["video_config"]["demo_mode"] self.scrolling = [] self.shaking = 0 self.init_scrolling = False self.event_manager = self.get_main().event_manager self.event_manager.add_subscription_event(self, KeyboardHandler) self.event_manager.subscriber = self.subscription_id self.entity_manager = self.get_main().entity_manager self.entity_list = self.entity_manager.entities self.backdrop_ui = self.entity_list["animated.backdrop"]() self.backdrop_ui.spawn() self.player = self.entity_list["animated.moveable.living.player"](self) self.player.spawn() self.event_funcs = { "move_up": [self.move, (0,-1)], "move_down": [self.move, (0,1)], "move_left": [self.move, (-1,0)], "move_right": [self.move, (1,0)], "use_sword": [self.player.use_sword], "place_bomb": [self.player.place_bomb], "open_doors": [self.open_doors, True], "shake": [lambda:setattr(self, "shaking", 1)], "toggle_rects":[self.toggle_draw_rects], "show_databin":[self.print_databin], "export_dungeon":[self.export_dungeon] } for k,v in self.entity_manager.get_persistant_entities().iteritems(): if k not in ["animated.backdrop", "animated.moveable.living.player", "animated.hud", "animated.hud.map"]: v().spawn() self.clock = Clock() self.load_dungeon()
class MapUI(UI): def __init__(self): super(MapUI, self).__init__() self.config_manager = self.get_main().config_manager self.get_main().fonts.register_font("debug") self.debug_font = self.get_main().fonts["debug"] self.map = DungeonMap(self.config_manager) self.draw_rects = False self.draw_debug = self.config_manager.config_data["subscription_config"]["draw_debug"] self.speedup = self.config_manager.config_data["video_config"]["speedup"] self.demo_mode = self.config_manager.config_data["video_config"]["demo_mode"] self.scrolling = [] self.shaking = 0 self.init_scrolling = False self.event_manager = self.get_main().event_manager self.event_manager.add_subscription_event(self, KeyboardHandler) self.event_manager.subscriber = self.subscription_id self.entity_manager = self.get_main().entity_manager self.entity_list = self.entity_manager.entities self.backdrop_ui = self.entity_list["animated.backdrop"]() self.backdrop_ui.spawn() self.player = self.entity_list["animated.moveable.living.player"](self) self.player.spawn() self.event_funcs = { "move_up": [self.move, (0,-1)], "move_down": [self.move, (0,1)], "move_left": [self.move, (-1,0)], "move_right": [self.move, (1,0)], "use_sword": [self.player.use_sword], "place_bomb": [self.player.place_bomb], "open_doors": [self.open_doors, True], "shake": [lambda:setattr(self, "shaking", 1)], "toggle_rects":[self.toggle_draw_rects], "show_databin":[self.print_databin], "export_dungeon":[self.export_dungeon] } for k,v in self.entity_manager.get_persistant_entities().iteritems(): if k not in ["animated.backdrop", "animated.moveable.living.player", "animated.hud", "animated.hud.map"]: v().spawn() self.clock = Clock() self.load_dungeon() def load_dungeon(self): try: map_entity = self.get_main().databin.entity_data.map.sprites()[0] except TypeError:pass else: map_entity.despawn() self.map.load_dungeon() self.backdrop_ui.load_new_backdrop() self.clean_entities() self.entity_list["animated.hud.map"](self).spawn() self._load_room(self.map.start_node) self.player.x, self.player.y = self.screen.get_center() if self.demo_mode: self.remove_hud() def export_dungeon(self): print "Exporting entire dungeon..." map_size = self.map.nodes.map.map_size for y in range(map_size[0]+1): for x in range(map_size[1]+1): room = self.map.map[y][x] if room: print room self.clean_entities() self._load_room(room) self.init_scrolling = True self.bg_image = self.get_pygame().surface.Surface(self.screen.size) self.draw() self.init_scrolling = False else: self.bg_image = self.get_pygame().surface.Surface(self.screen.size) self.bg_image.fill((0,0,0)) screenshot_path = self.config_manager["path_config", "screenshot_path"] alphabet = "abcdefghijklmnopqrstuvwxyz" path = self.config_manager.get_path(screenshot_path, "dungeon_%s_%s.png" %(alphabet[map_size[1]-x],alphabet[y])) self.get_pygame().image.save(self.bg_image, path) print "montage -mode concatenate -tile %ix%i screenshots/dungeon_*.png dungeon.png"%(map_size[0]+1, map_size[1]+1) def remove_hud(self): for entity in self.get_main().databin.entity_data.hud: entity.despawn() self.player.despawn() def load_room(self, current_room, room_id, no_scroll = False): try: no_sword = len(self.get_main().databin.entity_data.sword.sprites()) == 0 except TypeError: no_sword = True if not no_sword: self.get_main().databin.entity_data.sword.sprites()[0].despawn() if not no_scroll: self.init_scrolling = True self.bg_image = self.get_pygame().surface.Surface(self.screen.size) self.draw() self.init_scrolling = False self.scrolling = (((0,1),(1,0),(0,-1),(-1,0)))[room_id] axis = 1-room_id%2 setattr(self.player, "xy"[axis], self.screen.get_size()[axis]*(1-(room_id>>1))+52*cmp(room_id>>1, 0.5)) self.clean_entities() self.player.invincible = True self._load_room(current_room) def _load_room(self, current_room, no_doors = False, replaced = False): self.current_room = current_room random.seed(self.current_room.seed) self.backdrop_ui.load_current_room() if not no_doors: self.add_doors() self.current_room.visited(replaced) self.load_entities() if not self.demo_mode: self.get_main().databin.entity_data.map.sprites()[0].update_room() self.clock.tick() def add_doors(self): if not self.current_room.been_visited: coords = self.map.get_coords(self.current_room) for pos_id, d_coord in enumerate(((0,1),(-1,0),(0,-1),(1,0))): room = self.map.get_room(map(int.__add__, coords, d_coord)) if room and room in self.current_room.connections: door = self.entity_list["animated.door"](pos_id, room, self.current_room) self.current_room.entity_list.append(door) def clean_entities(self): for entity in self.get_entities(): if not entity.persistant: entity.despawn(killed = False) def load_entities(self): for entity in self.current_room.entity_list: entity.spawn() def room_cleared(self): try: new_room_list = self.current_room.replace_on_room_clear except AttributeError: new_room_list = [] if new_room_list: entities = self.get_entities().sprites()[:] new_room_name = random.choice(new_room_list) self.clean_entities() new_room = self.map.replace_node(self.current_room, new_room_name, entities) self._load_room(new_room, no_doors = True, replaced = True) return auto_cleared = True for entity in self.current_room.entity_list: if entity.must_kill: auto_cleared = False if auto_cleared: for door in self.get_main().databin.entity_data.door: if not door.locked: door.open = True door.current_anim = "Opened" else: self.open_doors() def call_key_event(self, event_name): for event in event_name: assert(event in self.event_funcs) self.event_funcs[event][0](*self.event_funcs[event][1:]) def move(self, delta_offset): self.player.control(delta_offset) def open_doors(self, all_ = False): for door in self.get_main().databin.entity_data.door: if (not door.locked) or all_: door.locked = False door.open = True if not all_: door.current_anim = "Open" def toggle_draw_rects(self): self.draw_rects = not self.draw_rects def calc_scroll(self, in_x_mod, in_y_mod): x_mod = self.scrolling[0] y_mod = self.scrolling[1] sign = map(lambda i: cmp(i, 0), self.scrolling) self.scrolling = [i+sign[j]*(200*self.d_time) for j, i in enumerate(self.scrolling)] self.screen.blit(self.bg_image, (in_x_mod+x_mod,in_y_mod+y_mod)) x_mod -= cmp(x_mod, 0)*self.screen.get_size()[0] y_mod -= cmp(y_mod, 0)*self.screen.get_size()[1] if [cmp(x_mod, 0), cmp(y_mod, 0)] == sign: self.scrolling = [] return in_x_mod+x_mod, in_y_mod+y_mod def draw(self): x_mod = 0 y_mod = 0 if self.shaking > 0: rs = math.ceil(self.shaking) x_mod += random.randrange(-rs,rs) y_mod += random.randrange(-rs,rs) self.shaking -= self.d_time if self.shaking < 0: self.shaking = 0 if self.scrolling: x_mod, y_mod = self.calc_scroll(x_mod, y_mod) for entity in self.get_entities(): if (entity not in self.get_main().databin.entity_data.hud) and entity is not self.player: if self.draw_rects and entity is not self.backdrop_ui: self.draw_rect(entity.rect) else:entity.blit(x_mod,y_mod) if not (self.scrolling or self.init_scrolling): if self.draw_rects and entity is not self.backdrop_ui: self.draw_rect(self.player.rect) else:self.player.blit(x_mod,y_mod) if not self.init_scrolling: for entity in self.get_main().databin.entity_data.hud: entity.blit() if self.draw_debug: self.draw_debug_text() def draw_debug_text(self): cur_room = self.debug_font.render("Current room: %s"%self.current_room, True, (255,255,255)) self.screen.blit(cur_room, (10,50)) cur_room = self.debug_font.render("Difficulty: %s"%self.current_room.difficulty, True, (255,255,255)) self.screen.blit(cur_room, (10,70)) #cur_room = self.debug_font.render("Keys: %d"%self.player.keys, True, (255,255,255)) #self.screen.blit(cur_room, (10,70)) def print_databin(self, databin = None, no_tabs = 0): if databin is None: databin = self.get_main().databin for k,v in databin.__dict__.iteritems(): if isinstance(v, databin.__class__): print "%s%s: {"%(" "*no_tabs,k) self.print_databin(v, no_tabs+2) print "%s}"%(" "*no_tabs) elif isinstance(v, self.get_pygame().sprite.LayeredUpdates): print "%s%s: %s"%(" "*no_tabs, k,v.sprites()) else: print "%s%s: %s"%(" "*no_tabs, k,v) def run(self): self.d_time = self.clock.tick() self.d_time *= self.speedup if self.scrolling: return room_cleared = True for entity in self.get_entities(): if entity.must_kill: room_cleared = False if entity.spawned: try: entity.run(self.d_time) except: print "Exception raised in %r whilst running"%entity raise if room_cleared and not self.current_room.cleared and not self.scrolling: self.current_room.cleared = True self.room_cleared() #print d_time def get_blit(self, dirty): if self.init_scrolling: return self.blit_bg_im if dirty: return self.screen.blit return self.screen.blit_func def draw_rect(self, o_rect): rect = o_rect.copy() rect.x*=2 rect.y*=2 rect.height*=2 rect.width*=2 self.screen.fill((0,0,0), rect) self.screen.blit_rects.append(rect) def blit_bg_im(self, surf, pos): self.bg_image.blit(surf, (pos[0]*2, pos[1]*2)) def get_entities(self): return self.get_main().databin.entity_data.entity