def mouse_resize(self, mouse): brx, bry = 0, 0 root = tc.R.active_root self.raise_window(True) utils.copy_windows_to_console([win for win in self.wmanager.window_stack if win is not self], tc.R.scratch) tc.R.scratch.blit(tc.R.temp_console, self.tlx, self.tly, self.width, self.height, 0, 0, 1.0, 1.0) tc.R.scratch.copy_to_console(root) # copy-console-to-console self.copy_to_console(root) # copy-window-to-console root.flush() key = tcod.Key() while mouse.lbutton: tcod.sys_check_for_event(tcod.EVENT_MOUSE, key, mouse) brx = utils.clamp(self.tlx, tc.R.screen_width() - 1, mouse.cx) bry = utils.clamp(self.tly, tc.R.screen_height() - 1, mouse.cy) if not (brx == self.brx and bry == self.bry): # Erase window tc.R.temp_console.blit(root, 0, 0, self.width, self.height, self.tlx, self.tly, 1.0, 1.0) self.resize(brx - self.tlx, bry - self.tly) self.prepare() # Save part of root console that win is covering tc.R.scratch.blit(tc.R.temp_console, self.tlx, self.tly, self.width, self.height, 0, 0, 1.0, 1.0) # Copy win to root self.copy_to_console(root) root.flush()
def play_game(): global key, mouse player_action = None mouse = libtcod.Mouse() key = libtcod.Key() while not libtcod.console_is_window_closed(): #render the screen libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse) render_all() libtcod.console_flush() #level up if needed check_level_up() #erase all objects at their old locations, before they move for object in objects: object.clear() #handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break #let monsters take their turn if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn()
def mouse_drag(self, mouse): root = tc.R.active_root width, height = self.width, self.height offset_x, offset_y = mouse.cx - self.tlx, mouse.cy - self.tly tlx, tly = 0, 0 swidth = tc.R.screen_width() sheight = tc.R.screen_height() tc.R.scratch.clear() tc.R.temp_console.clear() self.raise_window(self.wmanager.auto_redraw) utils.copy_windows_to_console([win for win in self.wmanager.window_stack if win is not self], tc.R.scratch) tc.R.scratch.blit(tc.R.temp_console, self.tlx, self.tly, self.width, self.height, 0, 0, 1.0, 1.0) tc.R.scratch.copy_to_console(root) # copy-console-to-console self.copy_to_console(root) # copy-window-to-console root.flush() key = tcod.Key() while mouse.lbutton: tcod.sys_check_for_event(tcod.EVENT_MOUSE, key, mouse) tlx = utils.clamp(0, swidth - self.width - 1, mouse.cx - offset_x) tly = utils.clamp(0, sheight - self.height - 1, mouse.cy - offset_y) if not (tlx == self.tlx and tly == self.tly): # Erase window tc.R.temp_console.blit(root, 0, 0, width, height, self.tlx, self.tly, 1.0, 1.0) self.move_window(tlx, tly) # Save part of root console that win is covering tc.R.scratch.blit(tc.R.temp_console, tlx, tly, width, height, 0, 0, 1.0, 1.0) # Copy win to root self.copy_to_console(root) root.flush()
def handle_drag_event(self, mouse_event): """Check for and handle (if necessary) drag events. """ start = tcod.sys_elapsed_milli() dragged = False mouse = mouse_event.state ox, oy = mouse.cx, mouse.cy key = tcod.Key() while mouse.lbutton: tcod.sys_check_for_event(tcod.EVENT_MOUSE, key, mouse) mouse.dx, mouse.dy = ox - mouse.cx, oy - mouse.cy if (tcod.sys_elapsed_milli() > (self.drag_delay * 1000 + start)) and \ (mouse.dx != 0 or mouse.dy != 0): dragged = True # Are we dragging on the window title (move!)? if self.window_manager.topwin.can_drag_p and \ self.window_manager.topwin.on_upper_window_border(mouse.cx - self.window_manager.topwin.tlx, mouse.cy - self.window_manager.topwin.tly): self.window_manager.topwin.mouse_drag(mouse) # Are we dragging on the bottom right corner (resize!)? elif self.window_manager.topwin.can_resize_p and \ ox == (self.window_manager.topwin.tlx + self.window_manager.topwin.width - 1) and \ oy == (self.window_manager.topwin.tly + self.window_manager.topwin.height - 1): self.window_manager.topwin.mouse_resize(mouse) else: self.window_manager.topwin.on_mouse_event(MouseDragEvent(winx=mouse.cx - self.window_manager.topwin.tlx, winy=mouse.cy - self.window_manager.topwin.tly, mouse_state=mouse_event))
def target_tile(max_range=None): #return the position of a tile left-clicked in player's FOV (optionally in a range), or (None,None) if right-clicked. global key, mouse while True: #render the screen. this erases the inventory and shows the names of objects under the mouse. libtcod.console_flush() libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse) render_all() (x, y) = (mouse.cx, mouse.cy) if mouse.rbutton_pressed or key.vk == libtcod.KEY_ESCAPE: return (None, None) #cancel if the player right-clicked or pressed Escape #accept the target if the player clicked in FOV, and in case a range is specified, if it's in that range if (mouse.lbutton_pressed and libtcod.map_is_in_fov(fov_map, x, y) and (max_range is None or player.distance(x, y) <= max_range)): return (x, y)
def sys_get_events(): mouse = tcod.Mouse() key = tcod.Key() events = [] while 1: event = tcod.sys_check_for_event(tcod.EVENT_ANY, key, mouse) if event == tcod.EVENT_NONE: break elif event == tcod.EVENT_KEY_PRESS or event == tcod.EVENT_KEY_RELEASE: events.append((event, key)) elif event in (tcod.EVENT_MOUSE_MOVE, tcod.EVENT_MOUSE_PRESS, tcod.EVENT_MOUSE_RELEASE): events.append((event, mouse)) return events
def main(): constants = get_constants() #sets the font of the console to arial10x10.png tcod.console_set_custom_font('arial10x10.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD) #creates a non-fullscreen window with the width and height defined earlier #and the title of "Tutorial" tcod.console_init_root(constants['screen_width'], constants['screen_height'], constants['window_title'], False) con = tcod.console_new(constants['screen_width'], constants['screen_height']) panel = tcod.console_new(constants['screen_width'], constants['panel_height']) player = None entities = [] world_map = None message_log = None game_state = None show_main_menu = True show_load_error_message = False main_menu_background_image = tcod.image_load('menu_background.png') key = tcod.Key() mouse = tcod.Mouse() while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) if show_load_error_message: message_box(con, 'No save game to load', 50, constants['screen_width'], constants['screen_height']) tcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit_game') #get better method for main menu item selection if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: player, entities, world_map, message_log, game_state = get_game_variables(constants) game_state = GameStates.PLAYER_TURN current_enemy = None show_main_menu = False elif load_saved_game: try: player, entities, world_map, message_log, game_state, current_enemy = load_game() show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: tcod.console_clear(con) play_game(player, entities, world_map, message_log, game_state, current_enemy, con, panel, constants) show_main_menu = True
def menu(header, options, width): global key, mouse if len(options) > 26: raise ValueError("Cannot have a menu with more than 26 options") # Calculate total height for the header (after auto-wrap) and one line per options if header == "": header_height = 0 else: header_height = libtcod.console_get_height_rect( con, 0, 0, width, SCREEN_HEIGHT, header) height = len(options) + header_height # Create an off-screen console that represents the menu's window window = libtcod.console_new(width, height) # Print the header, with auto-wrap libtcod.console_set_default_foreground(window, libtcod.white) libtcod.console_print_rect_ex(window, 0, 0, width, height, libtcod.BKGND_NONE, libtcod.LEFT, header) # Print all the options y = header_height letter_index = ord("a") for option_text in options: text = "({0}) {1}".format(chr(letter_index), option_text) libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 # Calculate coordinates x = SCREEN_WIDTH / 2 - width / 2 y = SCREEN_HEIGHT / 2 - height / 2 # Compute x and y offsets to convert console position to menu position x_offset = x # x is the left edge of the menu y_offset = y + header_height # The top edge of the menu # Now we'll blit the contents of "window" to the root console # The last two parameters of this next function control the foreground transparency # and the background transparency, respectively libtcod.console_blit(window, 0, 0, width, height, 0, int(x), int(y), 1.0, 0.7) while True: # Present the root console to the player and wait for a key press libtcod.console_flush() libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if mouse.lbutton_pressed: (menu_x, menu_y) = (mouse.cx - x_offset, mouse.cy - y_offset) # Check if click is within the menu and on a choice if menu_x >= 0 and menu_x < width and menu_y >= 0 and menu_y < height - header_height: return menu_y if mouse.rbutton_pressed or key.vk == libtcod.KEY_ESCAPE: return None # Cancel if the player right clicked or hit escape if key.vk == libtcod.KEY_ENTER and key.lalt: # Check for alt + enter to fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # Convert the ASCII code to an index; if it corresponds to an option, return it index = key.c - ord('a') if index >= 0 and index < len(options): return index # If they hit a letter that is not an option, return None if index >= 0 and index <= 26: return None
def main(): # This sets the screen size, should be in json file later on. screen_width = 80 screen_height = 50 # Size of the map map_width = 80 map_height = 45 # Some variables for the rooms in the map room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True) entities = [player] # This tells libtcod which font to use. File followed by which type of file we're reading. libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GRAYSCALE | libtcod.FONT_LAYOUT_TCOD) # This actually creates the screen. Dimensions, title and whether it should be fullscreen. libtcod.console_init_root(screen_width, screen_height, '4th Day of Summer Boredom', False) con = libtcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) # Giving player some movement by keeping the key and mouse input. key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYER_TURN # Game loop, won't end until we close the screen. while not libtcod.console_is_window_closed(): # This will capture any new events/inputs and update the key and mouse variables. libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False # Presents everything on the screen. libtcod.console_flush() clear_all(con, entities) # Player movement: action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move and game_state == GameStates.PLAYER_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: print('You kick the ' + target.name + ' in the shins, much to its annoyance!') else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity != player: print('The ' + entity.name + ' ponders the meaning of its existance.') game_state = GameStates.PLAYER_TURN
def main(): constants = get_constants() tcod.console_set_custom_font( 'arial10x10.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD) tcod.console_init_root(constants['screen_width'], constants['screen_height'], constants['window_title'], False, tcod.RENDERER_SDL2, vsync=True) con = tcod.console.Console(constants['screen_width'], constants['screen_height']) panel = tcod.console.Console(constants['screen_width'], constants['panel_height']) player = None entities = [] game_map = None message_log = None game_state = None show_main_menu = True show_load_error_message = False main_menu_background_image = tcod.image_load('menu_background.png') key = tcod.Key() mouse = tcod.Mouse() while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) if show_load_error_message: message_box(con, 'No save game to load', 50, constants['screen_width'], constants['screen_height']) tcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: player, entities, game_map, message_log, game_state = get_game_variables( constants) game_state = GameStates.PLAYERS_TURN show_main_menu = False elif load_saved_game: try: player, entities, game_map, message_log, game_state = load_saved_game = load_game( ) show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: tcod.console_clear(con) play_game(player, entities, game_map, message_log, game_state, con, panel, constants) show_main_menu = True
def main(): '''The loop that keeps the game running''' screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 11, 50), 'light_ground': libtcod.Color(200, 180, 50) } player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white) npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@', libtcod.yellow) entities = [npc, player] libtcod.console_set_custom_font( './dungeoncrash/data/fonts/arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Dungeoncrash', False) con = libtcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player) fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) fov_recompute = True if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if exit: return True
def main(): constants = get_constants() libtcod.console_set_custom_font("arial10x10.png", libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(constants["screen_width"], constants["screen_height"], constants["window_title"], False) con = libtcod.console_new(constants["screen_width"], constants["screen_height"]) panel = libtcod.console_new(constants["screen_width"], constants["panel_height"]) player = None entities = [] game_map = None message_log = None game_state = None show_main_menu = True show_load_error_message = False main_menu_background_image = libtcod.image_load("menu_background.png") key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, constants["screen_width"], constants["screen_height"]) if show_load_error_message: message_box(con, "No save game to load", 50, constants["screen_width"], constants["screen_height"]) libtcod.console_flush() action = handle_main_menu(key) new_game = action.get("new_game") load_saved_game = action.get("load_game") exit_game = action.get("exit") if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: player, entities, game_map, message_log, game_state = get_game_variables(constants) game_state = GameStates.PLAYERS_TURN show_main_menu = False elif load_saved_game: try: player, entities, game_map, message_log, game_state = load_game() show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: libtcod.console_clear(con) play_game(player, entities, game_map, message_log, game_state, con, panel, constants) show_main_menu = True
def main(): log.debug('Started new game.') render_eng = render_functions.RenderEngine() show_main_menu = True show_load_err_msg = False main_menu_bg_img = tcod.image_load(filename=config.menu_img) key = tcod.Key() mouse = tcod.Mouse() while True: # todo: This runs all the time! Make it wait... # Deprecated since version 9.3: Use the tcod.event.get function to check for events. tcod.sys_check_for_event( mask=tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, k=key, m=mouse ) # When I can re-arrange input after rendering - re-enable this... # tcod.sys_wait_for_event( # mask=tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, # k=key, # m=mouse, # flush=True # ) if show_main_menu: render_eng.render_main_menu(main_menu_bg_img) if show_load_err_msg: render_eng.render_msg_box('No save game to load', 50) # Update the display to represent the root consoles current state. tcod.console_flush() key_char = process_tcod_input(key) action = handle_main_menu(state=None, key=key_char) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') options = action.get('options') if show_load_err_msg and (new_game or load_saved_game or exit_game): show_load_err_msg = False elif new_game: log.debug('New game selected.') _game = game.Game() show_main_menu = False elif load_saved_game: log.debug('Load game selected.') _game = load_game(config.savefile) if _game: show_main_menu = False else: show_load_err_msg = True elif options: # todo: Fill out options menu log.debug('Options selected - STUB!') elif exit_game: log.debug('Exit selected') break else: # Reset a console to its default colors and the space character. render_eng.con.clear() engine = Engine(_game, render_eng) engine.play_game() show_main_menu = True
def main(): constants = get_constants() print("Setting up custom font...") libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) print("Initializing Console with SDL2 renderer") libtcod.console_init_root(constants['screen_width'], constants['screen_height'],'roguegame', False, libtcod.RENDERER_SDL2) print("Creating console...") con = libtcod.console_new(constants['screen_width'], constants['screen_height']) print("Setting up view...") panel = libtcod.console_new(constants['screen_width'], constants['panel_height']) print("Creating player and map") player = None entities = [] game_map = None message_log = None game_state = None show_main_menu = True show_load_error_message = False main_menu_background_image = libtcod.image_load('menu_background.png') key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) if show_load_error_message: message_box(con, 'No save game to load', 50, constants['screen_width'], constants['screen_height']) libtcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: player, entities, game_map, message_log, game_state = get_game_variables(constants) game_state = GameStates.PLAYERS_TURN show_main_menu = False elif load_saved_game: try: player, entities, game_map, message_log, game_state = load_game() show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: libtcod.console_clear(con) play_game(player, entities, game_map, message_log, game_state, con, panel, constants) show_main_menu = True
def main(): # screen constants screen_width = 80 screen_height = 50 # UI Stuff bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 # map stuff map_width = 80 map_height = 43 room_max_size = 10 room_min_size = 6 max_rooms = 30 max_monsters_per_room = 4 # FOV constants fov_algorithm = 0 fov_light_walls = True fov_radius = 10 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component) entities = [player] libtcod.console_set_custom_font('assets/consolas12x12_gs_tc.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # libtcod.console_set_custom_font('assets/arial10x10.png' , libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False, renderer=libtcod.RENDERER_SDL2, vsync=False) con = libtcod.console.Console(screen_width, screen_height) # main console panel = libtcod.console.Console(screen_width, panel_height) # ui panel message_log = MessageLog(message_x, message_width, message_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) turn_count = 0 key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN # main game loop while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors) fov_recompute = False libtcod.console_flush() clear_all(con,entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx,dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.ENEMY_TURN: turn_count += 1 for entity in entities: time_based_results = entity.processTimeBasedEffects(turn_count) for tb_result in time_based_results: message = tb_result.get('message') if message: message_log.add_message(message) if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): tcod.console_set_custom_font( 'arial10x10.png', tcod.FONT_TYPE_GRAYSCALE | tcod.FONT_LAYOUT_TCOD) tcod.console_init_root(screen_width, screen_height, 'Platform 50', False) keyboard_activity = tcod.Key() mouse_activity = tcod.Mouse() build = True solo = True while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, keyboard_activity, mouse_activity) if solo: render_map() render_all_entities() build_light_walker(con, npc) render_room() destroy_light_walker(con, player) tcod.console_flush() clear_all() elif build and not solo: render_map() render_all_entities() build_light_walker(con, player) time.sleep(3) destroy_light_walker(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_2(con, player) time.sleep(0.2) destroy_lw_cell_2(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_3(con, player) time.sleep(0.2) destroy_lw_cell_3(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_4(con, player) time.sleep(0.2) destroy_lw_cell_4(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_5(con, player) time.sleep(0.2) destroy_lw_cell_5(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_6(con, player) time.sleep(0.2) destroy_lw_cell_6(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_7(con, player) time.sleep(0.2) destroy_lw_cell_7(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_7(con, player) time.sleep(0.2) destroy_lw_cell_7(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_6(con, player) time.sleep(0.2) destroy_lw_cell_6(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_5(con, player) time.sleep(0.2) destroy_lw_cell_5(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_4(con, player) time.sleep(0.2) destroy_lw_cell_4(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_3(con, player) time.sleep(0.2) destroy_lw_cell_3(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_lw_cell_2(con, player) time.sleep(0.2) destroy_lw_cell_2(con, player) tcod.console_flush() clear_all() render_map() render_all_entities() build_light_walker(con, player) destroy_light_walker(con, player) tcod.console_flush() clear_all() build = False else: render_map() render_all_entities() build_light_walker(con, player) destroy_light_walker(con, player) tcod.console_flush() clear_all() # We hand over the current key result into the handle_keys function # This function returns a library for us that we name action action = handle_keys(keyboard_activity) # We check this library for various results using the get method move = action.get('move') exit = action.get('exit') # exit_walker = action.get('exit_walker') # enter_walker = action.get('enter_walker') fullscreen = action.get('fullscreen') # if not power: # player.power = False if move: dx, dy = move # When we used get on 'move' the result is a list of two numbers (if move even happened) if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) # player.x += dx # player.y += dy Depending on which key we pressed the values are calculated and updated so we move in the correct direction # This dictionary key returns a boolean value that then says to return True which breaks the game loop. if exit: solo = False # Another boolean value which triggers a method setting fullscreen. tcod.console_is_fullscreen() currently returns False # By adding not before it we change the value to True which changes the game to fullscreen. if fullscreen: solo = True
def main(): screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 paney_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 1 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), #'light_wall': libtcod.Color(175, 170, 135), 'light_ground': libtcod.Color(200, 180, 50) #'light_ground': libtcod.Color(235, 220, 170) } fighter_component = Fighter(hp=30, defense=2, power=5) player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component) entities = [player] # sets font for console libtcod.console_set_custom_font( 'arial12x12.png', libtcod.FONT_TYPE_GRAYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial', False) con = libtcod.console.Console(screen_width, screen_height) panel = libtcod.console.Console(screen_width, panel_height) # initialize the game map game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) message_log = Messagelog(message_x, message_width, message_height) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GamesStates.PLAYERS_TURN while not libtcod.console_is_window_closed(): # captures new events libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, paney_y, mouse, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] if move and game_state == GamesStates.PLAYERS_TURN: dx, dy = move destinaiton_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destinaiton_x, destination_y): target = get_blocking_entities_at_location( entities, destinaiton_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GamesStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GamesStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GamesStates.PLAYER_DEAD: break if game_state == GamesStates.PLAYER_DEAD: break else: game_state = GamesStates.PLAYERS_TURN
def main(): constants = get_constants() libtcod.console_set_custom_font( 'rexpaint_cp437_10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_ASCII_INROW) libtcod.console_init_root(constants['screen_width'], constants['screen_height'], title='MVP v0.0') con = libtcod.console_new(constants['screen_width'], constants['screen_height']) panel = libtcod.console_new(constants['screen_width'], constants['screen_height']) status = libtcod.console_new(constants['screen_width'], constants['screen_height']) player = None cursor = None entities = [] game_map = None message_log = None game_state = None turn_state = None event_queue = None player, cursor, entities, game_map, message_log, game_state, turn_state, event_queue = get_game_variables( constants) previous_game_state = game_state key = libtcod.Key() mouse = libtcod.Mouse() fov_recompute = True fov_map = initialize_fov(game_map) while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.location.x, player.location.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) entities_extended = entities.copy() entities_extended.append(cursor) render_all(con, panel, entities_extended, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], status, constants['status_height'], constants['status_width'], constants['status_x'], game_state, turn_state, player, cursor) libtcod.console_flush() clear_all(con, entities_extended) fov_recompute = False """ Handle the Player Actions. """ action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) if action or mouse_action or mouse.dx or mouse.dy: fov_recompute = True move = action.get('move') # Attempt to move. delta_speed = action.get( 'delta_speed' ) # Changes the max speed reached by the unit durnig autopathing movement. next_turn_phase = action.get( 'next_turn_phase') # Move to the next phase. reset_targets = action.get('reset_targets') # Reset targets. select = action.get( 'select') # A target has been selected via keyboard. show_weapons_menu = action.get( 'show_weapons_menu' ) # Show the weapons menu in order to choose a weapon to fire. weapons_menu_index = action.get( 'weapons_menu_index') # Choose an item from the weapons menu. look = action.get('look') # Enter the LOOK game state. exit = action.get('exit') # Exit whatever screen is open. fullscreen = action.get('fullscreen') # Set game to full screen. left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') # TODO: Figure out where this should go. if look and game_state == GameStates.PLAYER_TURN: previous_game_state = game_state game_state = GameStates.LOOK cursor.cursor.turn_on(player) continue """ Handle the turn. """ if game_state == GameStates.ENEMY_TURN or game_state == GameStates.PLAYER_TURN: turn_results = [] active_entity = None # Choose the active entity. if not event_queue.empty(): entity_uuid = event_queue.fetch() for entity in entities: if entity.uuid == entity_uuid: entity.age += 1 active_entity = entity # This phase is not for the active_entity. if turn_state == TurnStates.UPKEEP_PHASE: for entity in entities: if entity.required_game_state == game_state: entity.reset() else: entity.reset(only_action_points=True) event_queue.register_list(entities) turn_state = TurnStates.PRE_MOVEMENT_PHASE # This phase is for the player only. if turn_state == TurnStates.PRE_MOVEMENT_PHASE: if game_state == GameStates.ENEMY_TURN: turn_state = TurnStates.MOVEMENT_PHASE else: # Change player max speed. if delta_speed: turn_results.append( player.propulsion.change_cruising_speed( delta_speed)) # Highlight the legal tiles. if not player.propulsion.legal_tiles: game_map.reset_highlighted() player.propulsion.calculate_movement_range(game_map) game_map.set_highlighted( player.propulsion.legal_tiles['red'], color=libtcod.dark_red) game_map.set_highlighted( player.propulsion.legal_tiles['green'], color=libtcod.light_green) game_map.set_highlighted( player.propulsion.legal_tiles['yellow'], color=libtcod.yellow) fov_recompute = True if player.propulsion.chosen_tile: player.propulsion.choose_tile( player.propulsion.chosen_tile, game_map) game_map.set_pathable(player.propulsion.path, color=libtcod.blue) fov_recompute = True # Left clicking choose path final destination. if left_click: game_map.reset_pathable() player.propulsion.path.clear() turn_results.append( player.propulsion.choose_tile((mouse.cx, mouse.cy), game_map)) game_map.set_pathable(player.propulsion.path, color=libtcod.blue) fov_recompute = True # Right clicking deconstructs path. if right_click: game_map.reset_pathable() player.propulsion.chosen_tile = None player.propulsion.reset() # Attempt to end the turn. if next_turn_phase: if not player.propulsion.chosen_tile: # Phase doesn't end, but goes through one last time with a chosen tile. player.propulsion.chosen_tile = (player.location.x, player.location.y) else: next_turn_phase = False player.propulsion.update_speed() turn_state = TurnStates.MOVEMENT_PHASE # This phase is the big one. All entities act, except for projectiles of this game_state. # This phase ends when all entities have spent their action_points. if turn_state == TurnStates.MOVEMENT_PHASE: if active_entity: if active_entity is player: if active_entity.required_game_state == game_state: turn_results.extend( movement(player, entities, game_map)) if next_turn_phase: next_turn_phase = False player.action_points = 0 elif not active_entity.required_game_state == game_state: turn_results.extend( player.arsenal.fire_active_weapon()) else: turn_results.extend( active_entity.ai.take_turn(game_state, turn_state, entities, game_map)) if active_entity is None and event_queue.empty(): turn_state = TurnStates.POST_MOVEMENT_PHASE # This phase is not for the active_entity. if turn_state == TurnStates.POST_MOVEMENT_PHASE: game_map.reset_flags() fov_recompute = True turn_state = TurnStates.PRE_ATTACK_PHASE # This phase is not for the active_entity. # Entities have their action points refilled in order to use their weapons. if turn_state == TurnStates.PRE_ATTACK_PHASE: if game_state == GameStates.PLAYER_TURN: message_log.add_message( Message( 'Press f to target. Press ESC to stop targeting. Enter to change phase. Press r to choose new targets.', libtcod.orange)) for entity in entities: entity.reset(only_action_points=True) event_queue.register_list(entities) turn_state = TurnStates.ATTACK_PHASE # This phase is for active_entity of the required game_state. # They choose their weapons and targets. if turn_state == TurnStates.ATTACK_PHASE: if active_entity: if active_entity is player: if active_entity.required_game_state == game_state: if show_weapons_menu: previous_game_state = game_state game_state = GameStates.SHOW_WEAPONS_MENU if reset_targets: active_entity.arsenal.reset() message_log.add_message( Message('Targeting reset.', libtcod.light_blue)) game_map.reset_flags() fov_recompute = True if next_turn_phase: next_turn_phase = False active_entity.action_points = 0 else: active_entity.action_points = 0 elif active_entity.ai: turn_results.extend( active_entity.ai.take_turn(game_state, turn_state, entities, game_map)) if active_entity is None and event_queue.empty(): turn_state = TurnStates.POST_ATTACK_PHASE # This phase is not for active_entity. if turn_state == TurnStates.POST_ATTACK_PHASE: fov_recompute = True game_map.reset_flags() w = player.arsenal.get_active_weapon() if w is not None: for x, y in w.targets: erase_cell(con, x, y) turn_state = TurnStates.CLEANUP_PHASE # This phase is useless? if turn_state == TurnStates.CLEANUP_PHASE: if game_state == GameStates.PLAYER_TURN: game_state = GameStates.ENEMY_TURN elif game_state == GameStates.ENEMY_TURN: game_state = GameStates.PLAYER_TURN turn_state = TurnStates.UPKEEP_PHASE # Communicate turn_results. for result in turn_results: message = result.get( 'message') # Push a message to the message log. dead_entity = result.get('dead') # Kill the entity. remove_entity = result.get( 'remove') # Remove the entity (leaves no corpse behind). new_projectile = result.get( 'new_projectile') # Creates a new projectile. end_turn = result.get('end_turn') # End the turn. if result: fov_recompute = True if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_enemy(dead_entity) event_queue.release(dead_entity) if new_projectile: entity_type, location, target, APs, required_game_state = new_projectile projectile = factory.entity_factory( entity_type, location, entities) projectile.action_points = APs xo, yo = location xd, yd = target ### Path extending code. # Determine maximums, based on direction. if xd - xo > 0: max_x = game_map.width else: max_x = 0 if yd - yo > 0: max_y = game_map.height else: max_y = 0 # Determine the endpoints. if xo - xd == 0: # The projectile moves vertically. y_end = max_y else: y_end = yo - (xo - max_x) * (yo - yd) // (xo - xd) if yo - yd == 0: # The projectile moves horizontally. x_end = max_x else: x_end = xo - (yo - max_y) * (xo - xd) // (yo - yd) # Ensure the enpoints are in the map. if not 0 < y_end < game_map.width: y_end = max_y if not 0 < x_end < game_map.height: x_end = max_x projectile.projectile.path = list( libtcod.line_iter(int(x_end), int(y_end), xo, yo)) projectile.projectile.path.pop( ) # Don't start where the shooter is standing. projectile.projectile.path.pop( 0) # Don't end out of bounds. projectile.required_game_state = required_game_state event_queue.register(projectile) if remove_entity: entities.remove(remove_entity) if end_turn: active_entity.action_points = 0 if message: message_log.add_message(Message(message, libtcod.yellow)) # Refill the queue with the active_entity, if appropriate. if active_entity and active_entity.action_points > 0: event_queue.register(active_entity) """ Handle the targeting cursor. """ if game_state == GameStates.TARGETING: targeting_results = [] if move: cursor.cursor.move(move, player.arsenal.get_active_weapon(), player) elif select: cursor.cursor.target(game_map, player.arsenal.get_active_weapon()) fov_recompute = True for result in targeting_results: message = result.get('message') target = result.get('target') if message: message_log.add_message(Message(message, libtcod.red)) if target: pass """ Handle the Show Weapons Menu state. """ if game_state == GameStates.SHOW_WEAPONS_MENU: menu_results = [] if weapons_menu_index is not None and weapons_menu_index < len( player.arsenal.weapons ) and previous_game_state != GameStates.PLAYER_DEAD: menu_results.append( player.arsenal.weapons[weapons_menu_index].activate()) cursor.cursor.turn_on( player, player.arsenal.weapons[weapons_menu_index].targets) game_state = GameStates.TARGETING for result in menu_results: message = result.get('message') if message: message_log.add_message( Message(message, libtcod.dark_green)) """ Handle the Look game state. """ if game_state == GameStates.LOOK: if move: dx, dy = move cursor_movement(cursor, dx, dy) """ Handle the death of the player. """ if game_state == GameStates.PLAYER_DEAD: print('You have died.') return True """ Handle commands that activate regardless of game state. """ if exit: if game_state == GameStates.SHOW_WEAPONS_MENU or game_state == GameStates.LOOK: game_state = previous_game_state cursor.cursor.turn_off() elif game_state == GameStates.TARGETING: cursor.cursor.turn_off() fov_recompute = True game_state = previous_game_state else: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): screen_width = 80 screen_height = 50 # Size of the Map map_width = 80 map_height = 45 # Some variables for the rooms in the map room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 colors = { 'dark_wall': libtcod.Color(0,0,100), 'dark_ground': libtcod.Color(50,50,150), 'light_wall': libtcod.Color(130,110,50), 'light_ground': libtcod.Color(200,180,50) } player = Entity(int(screen_width/2), int(screen_height/2), '@', libtcod.dark_red) npc = Entity(int(screen_width/2 -5), int(screen_height /2), '@', libtcod.green) entities = [npc,player] libtcod.console_set_custom_font('arial10X10.png', libtcod.FONT_TYPE_GREYSCALE|libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width,screen_height, 'Jason\'s rogue-like', False, renderer=libtcod.RENDERER_SDL2, order='F', vsync=False) con = libtcod.console.Console(screen_width, screen_height) game_map = GameMap(map_width, map_height) #game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player) fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() while libtcod.console_is_window_closed: libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') game_exit = action.get('exit') full_screen = action.get('full_screen') if move: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx,dy) fov_recompute = True if game_exit: return True if full_screen: libtcod.console_set_fullscreen(not lib.console_is_fullscreen())
def main(): cursor = Entity(37, 30, 1, "+", C.EN_CURSOR, libtcod.white, "") cursor.visible = False player = Entity(37, 30, 1, "O", C.EN_HUMAN, libtcod.green, "Hrac") player.fighter.set_props(attack=10, defense=1, maxhp=100) npc = Entity(30, 30, 1, "X", C.EN_HUMAN, libtcod.white, "NPC") npc.fighter.set_props(attack=10, defense=1, maxhp=50) box = Entity(15, 15, 1, 254, C.EN_MOVABLE, libtcod.white, "Box") pot = Entity(30, 32, 1, '+', C.EN_ITEM, libtcod.white, "Healing Potion S") pot.item.set_props(hp=20, price=10, type=C.ITEM_CONSUM) #pot.item.add_to_inventory(player.inventory) sword = Entity(25, 30, 1, '?', C.EN_ITEM, libtcod.white, "Weak sword") sword.item.set_props(attack=20, price=10, type=C.ITEM_WEAP) sword2 = Entity(25, 30, 1, '?', C.EN_ITEM, libtcod.white, "Super sword") sword2.item.set_props(attack=30, price=10, type=C.ITEM_WEAP) armor = Entity(20, 30, 1, '?', C.EN_ITEM, libtcod.white, "Super Armor") armor.item.set_props(maxhp=20, defense=5, price=10, type=C.ITEM_ARMOR, requires={ 'lvl': 1, 'eyes': 2 }) # na 1. miste hrac, na -1. miste kurzor gv.entities = [player, box, pot, npc, sword, sword2, armor, cursor] event = EventChangeColor(box, libtcod.red, [1, 1, 1]) event2 = EventChangeChar(player, "V", [1, 1, 0.5, 1, 0.5]) gv.events = [event, event2] libtcod.console_set_custom_font( '../fonts/Cheepicus_15x15.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_ASCII_INROW) libtcod.console_init_root(gv.screen_width, gv.screen_height, 'libtcod tutorial revised', False, libtcod.RENDERER_OPENGL2, "F", True) c_map = libtcod.console.Console(gv.screen_width, gv.screen_height) c_inv = libtcod.console.Console(22, 22) c_info = libtcod.console.Console(22, 32) c_gmst = libtcod.console.Console(22, 3) cons = {'map': c_map, 'inv': c_inv, 'info': c_info, 'gmst': c_gmst} key = libtcod.Key() mouse = libtcod.Mouse() casovac = threading.Thread(target=thread_timer, daemon=True) casovac.start() while not libtcod.console_is_window_closed(): handle_events(gv.events, gv.timer) libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) render_all(cons, gv.entities, gv.game_map, gv.colors) libtcod.console_flush() clear_all(c_map, gv.entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') grab = action.get('grab') swap = action.get('swap') inv = action.get('inv') if grab: if gv.GAME_STATE == C.GS_PLAY: for i in gv.entities: if (i != player) and (i.type == C.EN_ITEM): if i.x == player.x and i.y == player.y: i.item.collect(player.inventory) elif gv.GAME_STATE == C.GS_INVENTORY: player.inventory.items[player.inventory.y].use_item( player, player) if swap: if gv.GAME_STATE == C.GS_PLAY: gv.GAME_STATE = C.GS_PAUSE cursor.visible = True elif gv.GAME_STATE == C.GS_PAUSE: gv.GAME_STATE = C.GS_PLAY cursor.visible = False cursor.x = player.x cursor.y = player.y cursor.h = player.h if inv: if gv.GAME_STATE == C.GS_INVENTORY: gv.GAME_STATE = C.GS_PLAY gv.redraw_map = True elif gv.GAME_STATE == C.GS_PLAY: gv.GAME_STATE = C.GS_INVENTORY if move: if gv.GAME_STATE == C.GS_PLAY: dx, dy, dh = move if player.move(dx, dy, dh): cursor.move(dx, dy, dh) #if dh != 0: #gv.redraw_map = True elif gv.GAME_STATE == C.GS_INVENTORY: dx, dy, dh = move player.inventory.move(dx, dy) elif gv.GAME_STATE == C.GS_PAUSE: dx, dy, dh = move cursor.move(dx, dy, dh) if exit: if gv.GAME_STATE != C.GS_PLAY: gv.GAME_STATE = C.GS_PLAY gv.redraw_map = True else: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): constants = get_constants() libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(constants['screen_width'], constants['screen_height'], constants['window_title'], False) con = libtcod.console_new(constants['screen_width'], constants['screen_height']) panel = libtcod.console_new(constants['screen_width'], constants['panel_height']) player = None entities = [] game_map = None message_log = None game_state = None show_main_menu = True show_load_error_message = False main_menu_background_image = libtcod.image_load('menu_background.png') key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) if show_load_error_message: message_box(con, 'No save game to load', 50, constants['screen_width'], constants['screen_height']) libtcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') debug = action.get('debug') if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: race_selection_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) while show_main_menu: libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) race = handle_race_selection_menu(key).get('race') if race: player, entities, game_map, message_log, game_state = get_game_variables( constants, race=race) game_state = GameStates.PLAYERS_TURN show_main_menu = False elif debug: player, entities, game_map, message_log, game_state = get_game_variables( constants) player.fighter = Fighter(hp=999, defense=999, power=999) player.fighter.owner = player game_state = GameStates.PLAYERS_TURN show_main_menu = False elif load_saved_game: try: player, entities, game_map, message_log, game_state = load_game( ) show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: libtcod.console_clear(con) play_game(player, entities, game_map, message_log, game_state, con, panel, constants) show_main_menu = True
def main(): screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 # Size of the map map_width = 80 map_height = 43 # Some variables for the rooms in the map room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 max_items_per_room = 2 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) inventory_component = Inventory(26) player = Entity(0, 0, 'A', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component) entities = [player] libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Xingqi-Universe Version1.0', False) con = libtcod.console_new(screen_width, screen_height) panel = libtcod.console_new(screen_width, panel_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, max_items_per_room) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width,panel_height, panel_y, mouse, colors, game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show_inventory') inventory_index = action.get('inventory_index') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(player.inventory.items): item = player.inventory.items[inventory_index] player_turn_results.extend(player.inventory.use(item)) if exit: if game_state == GameStates.SHOW_INVENTORY: game_state = previous_game_state else: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel, panel_bg, info, info_bg, player_con, player_con_bg, constants, permanent_cooldown_counter): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None targeting_feat = None game_turn_counter = 0 cooldown_counter = permanent_cooldown_counter while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: fov_map = initialize_fov(game_map) recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, panel_bg, info, info_bg, player_con, player_con_bg, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['map_width'], constants['map_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], constants['info_width'], constants['info_x'], constants['player_con_width'], constants['player_con_x'], constants['player_con_y'], mouse, constants['colors'], game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') wait = action.get('wait') pickup = action.get('pickup') show_inventory = action.get('show_inventory') show_abilities = action.get('show_abilities') use = action.get('use') drop = action.get('drop') inventory_index = action.get('inventory_index') ability_index = action.get('ability_index') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True if game_map.is_door(destination_x, player.y): message_log.add_message( Message('The door creaks open.', libtcod.yellow)) game_state = GameStates.ENEMY_TURN elif wait: game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item_index = inventory_index item = player.inventory.items[inventory_index][0] item.selected = True game_state = GameStates.ITEM_MENU if use: player_turn_results.extend( player.inventory.use(item, item_index, entities=entities, fov_map=fov_map)) game_state = GameStates.SHOW_INVENTORY if game_state != GameStates.TARGETING: item.selected = False else: item.selected = True elif drop: player_turn_results.extend( player.inventory.drop_item(item, item_index)) item.selected = False if show_abilities: previous_game_state = game_state game_state = GameStates.SHOW_ABILITIES if ability_index is not None and previous_game_state != GameStates.PLAYER_DEAD and ability_index < len( player.abilities.feats): feat = player.abilities.feats[ability_index] if feat.turn_performed is None or ( cooldown_counter - feat.turn_performed > feat.cooldown): player_turn_results.extend( player.abilities.perform( feat, turn_performed=cooldown_counter, entities=entities, fov_map=fov_map, ability_power=player.fighter.ability_power)) else: message_log.add_message( Message('That ability is on cooldown.', libtcod.white)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True libtcod.console_clear(con) break else: message_log.add_message( Message('There are no stairs here.', libtcod.yellow)) if level_up: if level_up == 'hp': player.fighter.base_max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.base_strength += 1 elif level_up == 'def': player.fighter.base_defense += 1 elif level_up == 'dog': player.fighter.base_dodge += 3 elif level_up == 'ap': player.fighter.base_ability_power += 2 elif level_up == 'crit': player.fighter.base_crit_chance += 5 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click if hasattr(targeting, 'item'): item_use_results = player.inventory.use(targeting_item, item_index, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) item.selected = False else: if feat.turn_performed is None or game_state == GameStates.TARGETING or ( cooldown_counter - feat.turn_performed > feat.cooldown): feat_use_results = player.abilities.perform( targeting_feat, turn_performed=cooldown_counter, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y, ability_power=player.fighter.ability_power) player_turn_results.extend(feat_use_results) else: message_log.add_message( Message('That ability is on cooldown.', libtcod.white)) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.SHOW_ABILITIES, GameStates.CHARACTER_SCREEN): game_state = previous_game_state for item in player.inventory.items: if hasattr(item[0], 'selected') and item[0].selected: item[0].selected = False elif game_state == GameStates.ITEM_MENU: for item in player.inventory.items: if hasattr(item[0], 'selected') and item[0].selected: item[0].selected = False game_state = GameStates.SHOW_INVENTORY elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) for item in player.inventory.items: if hasattr(item[0], 'selected') and item[0].selected: item[0].selected = False else: save_game(player, entities, game_map, message_log, game_state, cooldown_counter) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') feat_performed = player_turn_result.get('performed') item_dropped = player_turn_result.get('item_dropped') enemy_item_dropped = player_turn_result.get('enemy_item_dropped') equip = player_turn_result.get('equip') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') xp = player_turn_result.get('xp') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message, loot = kill_monster(dead_entity) if loot is not None: player_turn_results.extend( dead_entity.inventory.drop_item( loot[0], dead_entity.inventory.items.index(loot))) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if feat_performed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if enemy_item_dropped: entities.append(enemy_item_dropped) if equip: equip_results = player.equipment.toggle_equip(equip) for equip_result in equip_results: equipped = equip_result.get('equipped') unequipped = equip_result.get('unequipped') if equipped: message_log.add_message( Message('You equipped the {0}'.format( equipped.name))) if unequipped: message_log.add_message( Message('You unequipped the {0}'.format( unequipped.name))) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING if hasattr(targeting, 'item'): targeting_item = targeting message_log.add_message( targeting_item.item.targeting_message) else: targeting_feat = targeting message_log.add_message(targeting_feat.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting Cancelled')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('You gain {0} experience points.'.format(xp))) if leveled_up: message_log.add_message( Message( 'You have faced enough horrors and grow stronger, you reach level {0}' .format(player.level.curr_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN: game_turn_counter += 1 cooldown_counter += 1 for feat in player.abilities.feats: if feat.turn_performed is not None: if ((cooldown_counter - 1) - feat.turn_performed) < feat.cooldown: feat.turn_ready = str(feat.cooldown - (cooldown_counter - feat.turn_performed) + 1) else: feat.turn_ready = "Ready!" for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities, game_turn_counter) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message, loot = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() previous_game_state = game_state targeting_item = None # Game loop goes until esc is pressed while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants["fov_radius"], constants["fov_light_walls"], constants["fov_algorithm"]) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants["screen_width"], constants["screen_height"], constants["bar_width"], constants["panel_height"], constants["panel_y"], mouse, constants["colors"], game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get("move") wait = action.get("wait") pickup = action.get("pickup") show_inventory = action.get("show_inventory") drop_inventory = action.get("drop_inventory") inventory_index = action.get("inventory_index") take_stairs = action.get("take_stairs") level_up = action.get("level_up") show_character_screen = action.get("show_character_screen") exit = action.get("exit") fullscreen = action.get("fullscreen") left_click = mouse_action.get("left_click") right_click = mouse_action.get("right_click") player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif wait: game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message(Message("There is nothing here to pick up.", libtcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True libtcod.console_clear(con) break else: message_log.add_message(Message("There are no stairs here.", libtcod.yellow)) if level_up: if level_up == "hp": player.fighter.max_hp += 20 player.fighter.hp += 20 elif level_up == "str": player.fighter.power += 1 elif level_up == "def": player.fighter.defense += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({"targeting_cancelled": True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({"targeting_cancelled": True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get("message") dead_entity = player_turn_result.get("dead") item_added = player_turn_result.get("item_added") item_consumed = player_turn_result.get("consumed") item_dropped = player_turn_result.get("item_dropped") targeting = player_turn_result.get("targeting") targeting_cancelled = player_turn_result.get("targeting_cancelled") xp = player_turn_result.get("xp") if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.target_message) if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message("Targeting cancelled")) if xp: level_up = player.level.add_xp(xp) message_log.add_message(Message("You gain {0} experience points.".format(xp))) if level_up: message_log.add_message(Message( "Your battle skills grow stronger! You reached level {0}".format( player.level.current_level) + "!", libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get("message") dead_entity = enemy_turn_result.get("dead") if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): constants = get_constants() libtcod.console_set_custom_font('img/Tocky-square-10x10.png', libtcod.FONT_LAYOUT_ASCII_INROW) libtcod.console_init_root(constants['screen_width'], constants['screen_height'], constants['window_title'], False) con = libtcod.console_new(constants['screen_width'], constants['screen_height']) panel = libtcod.console_new(constants['screen_width'], constants['panel_height']) panel_bg = libtcod.console_new(constants['screen_width'], constants['panel_height']) info = libtcod.console_new(constants['info_width'], constants['screen_height']) info_bg = libtcod.console_new(constants['info_width'], constants['screen_height']) player_con = libtcod.console_new(constants['player_con_width'], constants['player_con_x']) player_con_bg = libtcod.console_new(constants['player_con_width'], constants['player_con_x']) player = None entities = [] game_map = None message_log = None game_state = None show_main_menu = True show_character_select = False show_load_error_message = False main_menu_background_image = libtcod.image_load('img/castle.png') character_select_background_image = libtcod.image_load('img/castle.png') key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if show_main_menu and not show_character_select: main_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) if show_load_error_message: message_box(con, 'No Save Game to Load', 50, constants['screen_width'], constants['screen_height']) libtcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: show_character_select = True show_main_menu = False elif load_saved_game: try: player, entities, game_map, message_log, game_state, permanent_cooldown_counter = load_game( ) show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break elif show_character_select and not show_main_menu: character_select_menu(con, character_select_background_image, constants['screen_width'], constants['screen_height']) libtcod.console_flush() action = handle_character_select(key) thief = action.get('thief') brute = action.get('brute') occultist = action.get('occultist') if thief: player, entities, game_map, message_log, game_state, permanent_cooldown_counter = initialize_game( constants, "thief") game_state = GameStates.PLAYERS_TURN show_character_select = False elif brute: player, entities, game_map, message_log, game_state, permanent_cooldown_counter = initialize_game( constants, "brute") player.fighter.heal( player.inventory.items[0][0].equippable.max_hp_bonus) game_state = GameStates.PLAYERS_TURN show_character_select = False elif occultist: player, entities, game_map, message_log, game_state, permanent_cooldown_counter = initialize_game( constants, "occultist") game_state = GameStates.PLAYERS_TURN show_character_select = False elif not (show_main_menu and show_character_select): libtcod.console_clear(con) play_game(player, entities, game_map, message_log, game_state, con, panel, panel_bg, info, info_bg, player_con, player_con_bg, constants, permanent_cooldown_counter) show_main_menu = True
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = tcod.Key() mouse = tcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False tcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') wait = action.get('wait') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif wait: game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', tcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True tcod.console_clear(con) break else: message_log.add_message( Message('There are no stairs here.', tcod.yellow)) if level_up: if level_up == 'hp': player.fighter.base_max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.base_power += 1 elif level_up == 'def': player.fighter.base_defense += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: tcod.console_set_fullscreen(not tcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') equip = player_turn_result.get('equip') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') xp = player_turn_result.get('xp') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('You gain {0} experience points.'.format(xp))) if leveled_up: message_log.add_message( Message( 'Your battle skills grow stronger! You reached level {0}' .format(player.level.current_level) + '!', tcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if equip: equip_results = player.equipment.toggle_equip(equip) for equip_result in equip_results: equipped = equip_result.get('equipped') dequipped = equip_result.get('dequipped') if equipped: message_log.add_message( Message('You equipped the {0}'.format( equipped.name))) if dequipped: message_log.add_message( Message('You dequipped the {0}'.format( equipped.name))) game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): # Size of the SCREEN!!! IT'S THE SCREEN, JERRY! THE SCREEN! screen_width = 80 screen_height = 50 # Size of the map map_width = 80 map_height = 43 # size of the BARS!!!!!!! bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height # MESSAGES!!!!! message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 # Some variables for the rooms in the map room_max_size = 10 room_min_size = 6 max_rooms = 30 # MONSTERS max_monsters_per_room = 3 max_items_per_room = 2 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 # reg colors colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } # debug colors colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } # Components and Entities fighter_component = Fighter(hp=30, defense=2, power=5) inventory_component = Inventory(26) player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component) entities = [player] libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False, vsync=True, renderer=libtcod.RENDERER_SDL2) con = libtcod.console.Console(screen_width, screen_height) panel = libtcod.console_new(screen_width, panel_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, max_items_per_room) print("{}: {}".format("Rooms", len(game_map.rooms))) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN # can't get this code to work the way it's supposed to, so whateves # while not tcod.event.get() == 'QUIT': while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') pickup = action.get('pickup') exit = action.get('exit') # command = action.get('command') fullscreen = action.get('fullscreen') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: # player's result loop message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: # enemy results loop message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 screen_full = False screen_title = 'My Roguelike' room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 #默认为0 fov_light_walls = True #是否照亮墙壁 fov_radius = 10 #视野大小 max_monsters_per_room = 3 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } fighter_component = Fighter(hp = 30, defense = 2, power = 5) player = Entity(0, 0, '@', libtcod.white, 'Player', blocks = True, render_order=RenderOrder.ACTOR, fighter = fighter_component) entities = [player] libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, screen_title, screen_full) con = libtcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) #使用用户输入内容更新key和mouse if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, player, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False libtcod.console_flush() #在屏幕上显示所有内容 ''' libtcod.console_put_char(con, player.x, player.y, ' ', libtcod.BKGND_NONE) libtcod.console_put_char(0, player.x, player.y, ' ', libtcod.BKGND_NONE) #消除原始位置 ''' clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = Entity.get_blocking_entities_at_location(entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') if message: print(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) print(message) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: print(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) print(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
inventory = [] #create the list of game messages and their colors, starts empty game_msgs = [] #a warm welcoming message! message('Welcome stranger! Prepare to perish in the Tombs of the Ancient Kings.', libtcod.red) mouse = libtcod.Mouse() key = libtcod.Key() while not libtcod.console_is_window_closed(): #render the screen libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse) render_all() libtcod.console_flush() #erase all objects at their old locations, before they move for object in objects: object.clear() #handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': break #let monsters take their turn if game_state == 'playing' and player_action != 'didnt-take-turn':
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = tcod.Key() mouse = tcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False tcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') wait = action.get('wait') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') escape = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', tcod.yellow)) if wait and game_state == GameStates.PLAYERS_TURN: game_state = GameStates.ENEMY_TURN if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results({'targeting_cancelled': True}) if escape: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: tcod.console_set_fullscreen(not tcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') if message: message_log.add_message(message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): # Console Parameters screen_width = 80 screen_height = 50 # GUI Parameters bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height # Message Parameters message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 # Map Parameters map_width = 80 map_height = 43 # Room Parameters room_max_size = 10 room_min_size = 6 max_rooms = 30 # Field of View Parameters fov_algorithm = 0 fov_light_walls = True fov_radius = 10 # Spawn parameters max_monsters_per_room = 3 max_items_per_room = 2 # Tile Colors colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } # Entity Variables fighter_component = Fighter( hp=30, defense=2, power=5 ) inventory_component = Inventory(26) player = Entity( 0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component ) entities = [player] # Map Generator game_map = GameMap( # defines the game map dimensions, calling GameMap class map_width, map_height ) game_map.make_map( # generates the map max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, max_items_per_room ) fov_recompute = True fov_map = initialize_fov(game_map) # Console & GUI libtcod.console_set_custom_font('assets/arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False) con = libtcod.console_new(screen_width, screen_height) panel = libtcod.console_new(screen_width, panel_height) message_log = MessageLog(message_x, message_width, message_height) # Input Functions key = libtcod.Key() mouse = libtcod.Mouse() # Game States game_state = GameStates.PLAYERS_TURN previous_game_state = game_state ############################################################# # MAIN GAME LOOP # ############################################################# # So long as the window is open, do... while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) # TRUE on Move, trigger recompute if fov_recompute: recompute_fov( fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm ) # Render the frame render_all( con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state ) # Recompute FOV only on player move fov_recompute = False # Clean up the screen libtcod.console_flush() clear_all( con, entities ) # INPUT HANDLERS action = handle_keys(key, game_state) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') exit = action.get('exit') fullscreen = action.get('fullscreen') # Entity Turn Logics # PLAYER TURN # Combat Results player_turn_results = [] # Move if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y ) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True # PASS TURN game_state = GameStates.ENEMY_TURN # Pickup elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: # If item x,y == player x,y pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow)) # Show Inventory if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY # Drop Inventory if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY # Inventory Index if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend(player.inventory.use(item)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) # ESC Key Logic if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previous_game_state else: return True # Fullscreen if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # Handling end of player turn for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN # ENEMY TURN # Handling the enemy turn if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities ) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break # Pass turn back to Player else: game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): """Main game loop. Args: player(Entity): Player Entity object. entities(list): List of entities on map. game_map(Map): TCOD map object used as game map. message_log(MessageLog): MessageLog object list of messages. game_state(Enum): Enum GameState (e.g. PLAYERS_TURN) con(Console): Console used to display whole game. panel(Console): Console used to display messages and UI info. constants(dict): Dictionary of constant game variables. """ key = libtcod.Key() mouse = libtcod.Mouse() previous_game_state = game_state fov_recompute = True fov_map = initialize_fov(game_map) targeting_item = None while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False # Refresh scene (?) libtcod.console_flush() clear_all(con, entities) # Get any keys that have been pressed and execute their associated action(s). action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') wait = action.get('wait') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') exit = action.get('exit') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif wait: game_state = GameStates.ENEMY_TURN if player.fighter.hp < player.fighter.max_hp: player.fighter.hp += 1 elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( player.inventory.use(item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True con.clear() break else: message_log.add_message( Message('There are no stairs here.', libtcod.yellow)) if level_up: if level_up == 'hp': player.fighter.base_max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.base_power += 1 elif level_up == 'def': player.fighter.base_defense += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: # Toggle fullscreen by making the set_fullscreen variable equal to the opposite of itself. libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # Check what happened on the player's turn and react accordingly. for player_turn_results in player_turn_results: message = player_turn_results.get('message') dead_entity = player_turn_results.get('dead') item_added = player_turn_results.get('item_added') item_consumed = player_turn_results.get('consumed') item_dropped = player_turn_results.get('item_dropped') equip = player_turn_results.get('equip') targeting = player_turn_results.get('targeting') targeting_cancelled = player_turn_results.get( 'targeting_cancelled') xp = player_turn_results.get('xp') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state: GameStates.ENEMY_TURN if item_consumed: game_state: GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled.')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message(Message('You gain {0} XP.'.format(xp))) if leveled_up: message_log.add_message( Message( 'Your fighting skills improve! You reached level {0}' .format(player.level.current_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if item_dropped: entities.append(item_dropped) game_state: GameStates.ENEMY_TURN if equip: equip_results = player.equipment.toggle_equip(equip) for equip_results in equip_results: equipped = equip_results.get('equipped') dequipped = equip_results.get('unequipped') if equipped: message_log.add_message( Message('You equip the {0}'.format(equipped.name))) if dequipped: message_log.add_message( Message('You unequip the {0}'.format( dequipped.name))) game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: # Checking for AI skips the player and any items/other stuff we implement later. if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_results in enemy_turn_results: message = enemy_turn_results.get('message') dead_entity = enemy_turn_results.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): # Game and map constants screen_width = 80 screen_height = 50 # HP Bar paramters bar_width = 20 # Panel for bars panel_height = 7 panel_y = screen_height - panel_height # Message bar message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 # Map size map_width = 80 map_height = 43 # Room parameters room_max_size = 10 room_min_size = 6 max_rooms = 30 # FoV Variables fov_algoritm = 0 fov_light_walls = True fov_radius = 10 # Entity limits max_monsters_per_room = 3 max_items_per_room = 2 colors = { 'dark_wall': tcod.Color(0, 0, 100), 'dark_ground': tcod.Color(50, 50, 150), 'light_wall': tcod.Color(130, 110, 50), 'light_ground': tcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) inventory_component = Inventory(26) player = Entity(0, 0, '@', tcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component) entities = [player] tcod.console_set_custom_font( 'Bisasam_24x24.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_CP437) tcod.console_init_root(screen_width, screen_height, 'tcodtutorial revised', False, renderer=tcod.RENDERER_SDL2) con = tcod.console.Console(screen_width, screen_height) panel = tcod.console.Console(screen_width, panel_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, max_items_per_room) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) key = tcod.Key() mouse = tcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state while not tcod.console_is_window_closed(): tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state) fov_recompute = False tcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) move = action.get('move') pickup = action.get('pickup') exit = action.get('exit') fullscreen = action.get('fullscreen') show_inventory = action.get('show_inventory') inventory_index = action.get('inventory_index') player_turn_results = [] # Move and/or attack action if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN # Picking up an item elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', tcod.yellow)) # Open inventory if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] print(item.name) # Exit game if exit: if game_state == GameStates.SHOW_INVENTORY: # Escape from inventory menu back to game game_state = previous_game_state else: return True # Set to fullscreen if fullscreen: tcod.console_set_fullscreen((not tcod.console_is_fullscreen())) ## PROCESS PLAYER'S TURN for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: # If entity has 'ai', i.e. can move or attack etc, get if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def check_for_event(mask=tcod.EVENT_ANY): key = tcod.Key() mouse = tcod.Mouse() event_type = tcod.sys_check_for_event(mask, key, mouse) return event_type, mouse, key
def main(): """The main function of the engine. It sets up everything needed for the game and contains the main game loop function.""" constants = get_constants() # Sets custom ASCII character PNG image to use. libtcod.console_set_custom_font( 'dejavu10x10_gs_tc.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # Creates the window, window size, window title, and sets fullscreen. libtcod.console_init_root(constants['screen_width'], constants['screen_height'], constants['window_title'], False) con = libtcod.console_new(constants['screen_width'], constants['screen_height']) panel = libtcod.console_new(constants['screen_width'], constants['panel_height']) player = None entities = [] game_map = None message_log = None game_state = None show_main_menu = True show_load_error_message = False main_menu_background_image = libtcod.image_load('menu_background.png') key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) if show_load_error_message: message_box(con, 'No save game to load!', 50, constants['screen_width'], constants['screen_height']) libtcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: player, entities, game_map, message_log, game_state = get_game_variables( constants) game_state = GameStates.PLAYERS_TURN show_main_menu = False elif load_saved_game: try: player, entities, game_map, message_log, game_state = load_game( ) show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: con.clear() play_game(player, entities, game_map, message_log, game_state, con, panel, constants) show_main_menu = True
def poll_for_event(self, mask): event_type = tcod.sys_check_for_event(mask, self.current_key_event, self.current_mouse_event) self.current_event = events.event_from(event_type, self.current_key_event, self.current_mouse_event) return self.current_event
def main(): screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 fov_algorithm = 0 fov_light_walls = True fov_radius = 10 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } blocks = { 'wall': '#', 'ground': '.' } max_monsters_per_room = 3 player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True) entities = [player] key = libtcod.Key() mouse = libtcod.Mouse() # Set font libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # Init console libtcod.console_init_root(screen_width, screen_height, 'From Steel To Plastic', False) con = libtcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) game_state = GameStates.PLAYERS_TURN while not libtcod.console_is_window_closed(): # Game loop # Get mouse and kbd event keypress libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) # con is the console to draw, white is the color of the foreground (the thing we draw, in this case '@') # libtcod.console_set_default_foreground(con, libtcod.white) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors, blocks) fov_recompute = False # Draw on the screen libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: print('You kick the ' + target.name + ' in the shins, much to its annoyance!') else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: """ for entity in entities: if entity != player: print('The ' + entity.name + ' ponders the meaning of its existence.') """ game_state = GameStates.PLAYERS_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): #TODO: Move these setting out to a setting file in the tutorial doesn't already. Bonus points if they can accept user or randomized input screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 #rooms in the dungeon room_max_size = 10 room_min_size = 6 max_rooms = 30 # field of view fov_algorithm = 0 #default algorithm for libcod, consider exploring this. fov_light_walls = True fov_radius = 10 # monsters max_monsters_per_room = 3 #tile colors colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(30, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } #instantiate a player player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True) entities = [player] #input graphics file libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False) #con is the console con = libtcod.console_new(screen_width, screen_height) #game map game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) fov_recompute = True fov_map = initialize_fov(game_map) # Keyboard and mouse input key = libtcod.Key() mouse = libtcod.Mouse() # Main Game Loop game_state = GameStates.PLAYERS_TURN while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: print('You kick the ' + target.name + ' in the shins, much to its annoyance!') else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity != player: print('The ' + entity.name + ' ponders the meaning of its existence.') game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, world_map, message_log, game_state, current_enemy, con, panel, constants): # print("entities: ") # for entity in entities: # print(entity.name) current_map = world_map.maps[world_map.x][world_map.y] # entities = current_map.entities # print("entities: ") # for entity in entities: # print(entity.name) fov_recompute = True fov_map = initialize_fov(current_map) key = tcod.Key() mouse = tcod.Mouse() previous_game_state = game_state targeting_item = None player_target = Target(0,0) #main game loop while not tcod.console_is_window_closed(): #updates the key and mouse variables with any key or mouse events tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: fov_map = initialize_fov(current_map) recompute_fov(fov_map, player, constants['fov_radius'], entities, constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, entities, player, current_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], constants['colors'], game_state, current_enemy, player_target) tcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') pickup = action.get('pickup') show_inventory = action.get('show_inventory') inventory_index = action.get('inventory_index') drop_inventory = action.get('drop_inventory') look = action.get('look') move_target = action.get('move_target') target_selected = action.get('target_selected') player_turn_results = [] #Current errors: # (FIXED) x and y are being set to default make_map values in opposite moves # diagonal moves off the edge of the map cause a crash # !!!FOCUS!!! entity lists are not attached to maps, so buildings remain while entities refresh # Need to readd player to returning maps #!!!!!!!!! #WHEN A USER SAVES AND LOADS ON A GAME_MAP, A PERMANENT "DUMB" COPY OF #THEIR BODY IS LEFT AT THE POSITION THEY SAVED AND LOADED #UPON SUBSEQUENT RETURNS TO THE MAP # #THE GLITCH ONLY OCCURS WHEN THE USER LEAVES THE MAP #SOMEHOW, PLAYER IS KEPT IN ENTITIES OVER TRANSITIONS #Each gamemap needs a copy of player? (maybe) #If you save and load multiple times on one map before leaving it, the #dumb copy spawns at the first position you saved and loaded at. #!!!!!!!!! if move and game_state == GameStates.PLAYER_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if destination_x == current_map.width: if world_map.x < 9: world_map.move_to(world_map.x+1, world_map.y, constants, player) current_map = world_map.maps[world_map.x][world_map.y] entities = current_map.entities destination_x = 0 dx = 0 player.x = 0 player.y = destination_y else: destination_x = player.x destination_y = player.y message_log.add_message(Message('You can\'t go that way', tcod.blue)) print(str(world_map.x)+" ,"+str(world_map.y)) elif destination_y == current_map.height: if world_map.y > 0: world_map.move_to(world_map.x, world_map.y-1, constants, player) current_map = world_map.maps[world_map.x][world_map.y] entities = current_map.entities destination_y = 0 dy = 0 player.y = 0 player.x = destination_x else: destination_x = player.x destination_y = player.y message_log.add_message(Message('You can\'t go that way', tcod.blue)) print(str(world_map.x)+" ,"+str(world_map.y)) elif destination_x == -1: if world_map.x > 0: world_map.move_to(world_map.x-1, world_map.y, constants, player) current_map = world_map.maps[world_map.x][world_map.y] entities = current_map.entities destination_x = current_map.width-1 dx = 0 player.x = current_map.width-1 player.y = destination_y else: destination_x = player.x destination_y = player.y message_log.add_message(Message('You can\'t go that way', tcod.blue)) print(str(world_map.x)+" ,"+str(world_map.y)) elif destination_y == -1: if world_map.y < 9: world_map.move_to(world_map.x, world_map.y+1, constants, player) current_map = world_map.maps[world_map.x][world_map.y] entities = current_map.entities destination_y = current_map.height-1 dy = 0 player.y = current_map.height-1 player.x = destination_x else: destination_x = player.x destination_y = player.y message_log.add_message(Message('You can\'t go that way', tcod.blue)) print(str(world_map.x)+" ,"+str(world_map.y)) if not current_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) if target: if target.fighter and target != player: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) elif target.breakable: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYER_TURN: for entity in entities: if entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message(Message('There is nothing here to pick up', tcod.yellow)) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if look: previous_game_state = game_state player_target.set(player.x, player.y) game_state = GameStates.LOOKING if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(player.inventory.items): item = player.inventory.items[inventory_index] if game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend(player.inventory.use(item, entities = entities, fov_map = fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.LOOKING): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, world_map, message_log, game_state, current_enemy) return True if fullscreen: tcod.console_set_fullscreen(not tcod.console_is_fullscreen()) if game_state == GameStates.TARGETING: if move_target: dx, dy = move_target player_target.move(dx, dy) if target_selected: item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=player_target.x, target_y=player_target.y) player_turn_results.extend(item_use_results) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') destroyed_entity = player_turn_result.get('destroyed') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') if message: message_log.add_message(message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if destroyed_entity: message = destroy_object(destroyed_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYER_TURN game_state = GameStates.TARGETING player_target.set(player.x, player.y) targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn(player, fov_map, current_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYER_TURN if game_state == GameStates.LOOKING and move_target: dx, dy = move_target player_target.move(dx, dy)