def handle_keys(): global playerx, playery, fov_recompute #key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return "exit" if game_state == 'playing': #movement keys if key.vk == libtcod.KEY_UP: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT: player_move_or_attack(1, 0) else: return 'didnt-take-turn'
def handle_keys(state): """Handles key inputs from the PLAYER. UP/DOWN/LEFT/RIGHT keys will move the PLAYER in their respective directions. Fullscreen mode is toggled with LAlt+ENTER; Game exit is triggered with ESCAPE. Accesses and modifies PLAYER, ZONE, and the FOV_RECOMPUTE flag. """ # Fullscreen and Exit keys; # Use "True" arg for turn-based; omit for real-time if settings.TURN_BASED is True: key = libtcod.console_wait_for_keypress(True) else: key = libtcod.console_check_for_keypress() if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' # Exit game if state["status"] == 'playing': # Movement Keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): player_move_or_attack(state, 0, -1) elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): player_move_or_attack(state, 0, 1) elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): player_move_or_attack(state, -1, 0) elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): player_move_or_attack(state, 1, 0) else: print 'Hero takes no action' return 'no_action'
def input(): global recompute_field_of_view # key = libtcod.console_check_for_keypress() #real-time key = tcod.console_wait_for_keypress(True) # turn-based if key.vk == tcod.KEY_ENTER and key.lalt: # Alt+Enter: toggle fullscreen tcod.console_set_fullscreen(not tcod.console_is_fullscreen()) elif key.vk == tcod.KEY_ESCAPE: return True # exit game # movement keys if tcod.console_is_key_pressed(tcod.KEY_UP): engine.frogue.move(0, -1) render.recompute_field_of_view = True elif tcod.console_is_key_pressed(tcod.KEY_DOWN): engine.frogue.move(0, 1) render.recompute_field_of_view = True elif tcod.console_is_key_pressed(tcod.KEY_LEFT): engine.frogue.move(-1, 0) render.recompute_field_of_view = True elif tcod.console_is_key_pressed(tcod.KEY_RIGHT): engine.frogue.move(1, 0) render.recompute_field_of_view = True
def handle_keys(): global player_x, player_y, m, turns #movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): if libtcod.map_is_walkable(m, player_x, player_y - 1): player_y -= 1 turns += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): if libtcod.map_is_walkable(m, player_x, player_y + 1): player_y += 1 turns += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): if libtcod.map_is_walkable(m, player_x - 1, player_y): player_x -= 1 turns += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): if libtcod.map_is_walkable(m, player_x + 1, player_y): player_x += 1 turns += 1 key = libtcod.Key() mouse = libtcod.Mouse() libtcod.sys_check_for_event(libtcod.EVENT_ANY, key, mouse) if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_SPACE: end(player_x, player_y, mouse.cx, mouse.cy) elif key.vk == libtcod.KEY_ESCAPE: return True #exit game
def menu(header, options, width): if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options.') # calculate total height for the header (after auto-wrap) WITH one line per option. header_height = libtcod.console_get_height_rect(con, 0, 0, width, SCREEN_HEIGHT, header) if header == '': header_height = 0 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 = '(' + chr(letter_index) + ') ' + option_text libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 # Blit the contents of "window" to the root console. x = SCREEN_WIDTH//2 - width//2 y = SCREEN_HEIGHT//2 - height//2 libtcod.console_blit(window, 0, 0, width, height, 0, x, y, 1.0, 0.7) # Present the root console to the player and wait for a key-press. libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: #(special case) Alt+Enter: toggle 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 return None
def handle_input(): global key, game_state if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle full screen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' # exit game if game_state == 'playing': # respond to movement keys if key.vk == libtcod.KEY_UP: return 'up' elif key.vk == libtcod.KEY_DOWN: return 'down' elif key.vk == libtcod.KEY_LEFT: window.activate_pane("-") elif key.vk == libtcod.KEY_RIGHT: window.activate_pane("+") elif key.vk == libtcod.KEY_SPACE: game_state = 'paused' message('Game Paused', libtcod.purple) else: return 'no action' elif game_state == 'paused': if key.vk == libtcod.KEY_SPACE: game_state = 'playing' message('Game Unpaused', libtcod.purple)
def handle_keys(): global playerx, playery key = libtcod.console_wait_for_keypress(True) #fullscreen toggle if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) #exit game elif key.vk == libtcod.KEY_ESCAPE: return True #movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): playery -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): playery += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): playerx -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): playerx += 1
def player_card(): #create an off-screen console that represents the card's window window = libtcod.console_new(20, 20) #print player stats libtcod.console_set_default_foreground(window, libtcod.white) libtcod.console_print_ex(window, 1, 1, libtcod.BKGND_NONE, libtcod.LEFT, 'STR:' + str(player.fighter.str)) libtcod.console_print_ex(window, 1, 2, libtcod.BKGND_NONE, libtcod.LEFT, 'DEX:' + str(player.fighter.dex)) libtcod.console_print_ex(window, 1, 3, libtcod.BKGND_NONE, libtcod.LEFT, 'CON:' + str(player.fighter.con)) libtcod.console_print_ex(window, 1, 4, libtcod.BKGND_NONE, libtcod.LEFT, 'INT:' + str(player.fighter.int)) libtcod.console_print_ex(window, 1, 5, libtcod.BKGND_NONE, libtcod.LEFT, 'FTH:' + str(player.fighter.fth)) libtcod.console_print_ex(window, 1, 6, libtcod.BKGND_NONE, libtcod.LEFT, 'PER:' + str(player.fighter.per)) libtcod.console_print_ex(window, 1, 9, libtcod.BKGND_NONE, libtcod.LEFT, 'Encumbrance: ') #blit the contents of "window" to the root console libtcod.console_blit(window, 0, 0, 20, 20, 0, 1, 7, 1.0, 0.7) #present the root console to the player and wait for a key-press libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: #(special case) Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) return None
def handleKeys(player): """ Handles key presses from the user; including movement, exiting, and toggle fullscreen. It takes the player so that it can update the player's state. """ # Our game is turnbased so we wait for a keypress every turn # before executing more code. key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: # M-Return (Alt+Enter) toggles fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) return False elif key.vk == libtcod.KEY_ESCAPE: return True # which we handle by exiting the game loop # Useful alias for a long fn name keyPressed = libtcod.console_is_key_pressed if keyPressed(libtcod.KEY_UP): player.move(0, -1) return False elif keyPressed(libtcod.KEY_DOWN): player.move(0, 1) return False elif keyPressed(libtcod.KEY_LEFT): player.move(-1, 0) return False elif keyPressed(libtcod.KEY_RIGHT): player.move(1, 0) return False
def key_input(self): ##============================================================================ ##Menu Keyboard Input key = libtcod.console_check_for_keypress() index = key.c - ord('a') if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if key.vk == libtcod.KEY_ESCAPE: libtcod.console_check_for_keypress() return 'close' if key: if index >= 0 and index < len(self.options): libtcod.console_check_for_keypress() return index #if key.vk == libtcod.KEY_DOWN: # current_pick = (current_pick +1) % len(self.options) #if key.vk == libtcod.KEY_UP: # current_pick = (current_pick -1) % len(self.options) #if key.vk == libtcod.KEY_ENTER: # return current_pick return -1
def handle_keys(): global playerx, playery global fov_recompute key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt + Enter: Toggle Fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: #Exit the game return True #movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): player.move(0, -1) fov_recompute = True #playery -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): player.move(0, 1) fov_recompute = True #playery += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): player.move(-1, 0) fov_recompute = True #playerx -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): player.move(1, 0) fov_recompute = True
def menu(header, options, width): if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options') # Calc the header height after auto-wrap, one line per option header_height = libtcod.console_get_height_rect(con, 0, 0, width, opt.SCREEN_HEIGHT, header) if header == '': header_height = 0 height = len(options) + header_height # Create new offscreen window window = libtcod.console_new(width, height) # Print header with auto-wrap libtcod.console_set_default_foreground(window, libtcod.Color(230,230,230)) libtcod.console_print_rect_ex(window, 0, 0, width, height, libtcod.BKGND_NONE, libtcod.LEFT, header) # Print options y = header_height letter_index = ord('a') for option_text in options: # Print options in format a) Option text = chr(letter_index) + ') ' + option_text libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 x = opt.SCREEN_WIDTH/2 - width/2 y = opt.SCREEN_HEIGHT/2 - height/2 libtcod.console_blit(window, 0, 0, width, height, 0, x, y, 1.0, 0.7) libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # If an item was chosen, return it index = key.c - ord('a') if index >= 0 and index < len(options): return index return None
def menu(header, options, width): if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options.') header_height = libtcod.console_get_height_rect(con, 0, 0, width, SCREEN_HEIGHT, header) if header == '': header_height = 0 height = len(options) + header_height window = libtcod.console_new(width, height) libtcod.console_set_default_foreground(window, libtcod.white) libtcod.console_print_rect_ex(window, 0, 0, width, height, libtcod.BKGND_NONE, libtcod.LEFT, header) y = header_height letter_index = ord('a') for option_text in options: text = '(' + chr(letter_index) + ') ' + option_text libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 x = SCREEN_WIDTH / 2 - width/2 y = SCREEN_HEIGHT / 2 - height/2 libtcod.console_blit(window, 0, 0, width, height, 0, x, y, 1.0, 0.7) libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: #(special case) Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) index = key.c - ord('a') if index >= 0 and index < len(options): return index return None
def handle_keys(): # global playerx,playery,fov_recompute,key # special keys if key.vk == libtcod.KEY_ENTER and key.lalt: # Alt+enter: FS toggler libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return "exit" # GET OUT!!!! # Movement keys if game_state == "playing": if key.vk == libtcod.KEY_UP: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT: player_move_or_attack(1, 0) else: # Check for action keys key_char = chr(key.c) if key_char == "g": # Grab for object in objects: if object.x == player.x and object.y == player.y and object.item: object.item.pick_up() break return "didnt-take-turn"
def handle_keys(self): key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return "exit" #exit game elif key.vk == libtcod.KEY_F1: if self.game_state == "not-playing": self.game_state = "playing" return "exit-debug-screen" self.game_state = "not-playing" return "debug-screen" if self.game_state != "playing": return if libtcod.console_is_key_pressed(libtcod.KEY_UP): self.move_player(0,-1) elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): self.move_player(0,1) elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): self.move_player(-1,0) elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): self.move_player(1,0) else: return "didn't-move"
def handle_keys(): global playerx, playery #key = libtcod.console_check_for_keypress() #real-time key = libtcod.console_wait_for_keypress(True) #turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return True #exit game #movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): playery -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): playery += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): playerx -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): playerx += 1
def handle_keys(self): key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ESCAPE: return 'exit' elif key.vk == libtcod.KEY_ENTER and libtcod.KEY_ALT: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_CONTROL and ord('s'): libtcod.sys_save_screenshot() move = False if self.mode == 'playing': if libtcod.console_is_key_pressed(libtcod.KEY_UP): self.move_player((0, -1)) move = True return 'move' elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): self.move_player((0, 1)) move = True return 'move' elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): self.move_player((-1, 0)) move = True return 'move' elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): self.move_player((1, 0)) move = True return 'move' if move: return 'move' else: return "didnt-take-turn"
def Menu(header, options, width): if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options') header_height = libtcodpy.console_get_height_rect(0, 0, 0, config.window_width, config.window_height, header) if header == '': header_height = 0 height = len(options) + header_height menupanel = Panel(0, 0, width, height) menupanel.write_wrap_ex(0, 0, width, height, header, libtcodpy.LEFT) y = header_height letter_index = ord('a') for option_text in options: text = '(' + chr(letter_index) + ') ' + option_text menupanel.write(0, y, text) y += 1 letter_index += 1 x = config.window_width / 2 - width / 2 y = config.window_height / 2 - height / 2 menupanel.blit(xdst=x, ydst=y, bfade=0.7) config.gamewindow.flush key = libtcodpy.console_wait_for_keypress(True) if key.vk == libtcodpy.KEY_ENTER and key.lalt: libtcodpy.console_set_fullscreen(not libtcodpy.console_is_fullscreen()) index = key.c - ord('a') if index >= 0 and index < len(options): return index return None
def handle_keys(): global key global fov_recompute # here we set the globals for the players position plus handle movement #use check for keypress for realtime if key.vk == libtcod.KEY_ENTER and key.lalt: #alt enter for fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' #exit game if game_state == 'playing': if libtcod.console_is_key_pressed(libtcod.KEY_UP): player_move_or_attack(0, -1) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): player_move_or_attack(0, 1) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): player_move_or_attack(-1, 0) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): player_move_or_attack(1, 0) fov_recompute = True else: return 'didnt-take-turn'
def handle_keys(): global playerx, playery #key = libtcod.console_check_for_keypress() #real-time key = libtcod.console_wait_for_keypress(True) #turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return True #exit game # Movement keys by arrows. if libtcod.console_is_key_pressed(libtcod.KEY_UP): #north player.move(0, -1) elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): #south player.move (0, 1) elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): #west player.move (-1, 0) elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): #east player.move (1, 0)
def handle_keys(): global fov_recompute # key = libtcod.console_check_for_keypress() #real-time key = libtcod.console_wait_for_keypress(True) # turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: # Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return True # exit game # movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): player.move(0, -1) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): player.move(0, 1) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): player.move(-1, 0) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): player.move(1, 0) fov_recompute = True
def handle_keys(): global keys if key.vk == libtcod.KEY_ENTER and key.lalt: # Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return "exit" # exit game if game_state == "playing": # movement keys if key.vk == libtcod.KEY_UP: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT: player_move_or_attack(1, 0) else: return "didnt-take-turn"
def handle_keys(): global fov_recompute, keys, mouse, msg_index, game_msgs if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' if game_state == 'playing': if key.vk == libtcod.KEY_UP or key.vk == libtcod.KEY_KP8: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN or key.vk == libtcod.KEY_KP2: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT or key.vk == libtcod.KEY_KP4: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT or key.vk == libtcod.KEY_KP6: player_move_or_attack(1, 0) elif key.vk == libtcod.KEY_KP1: player_move_or_attack(-1,1) elif key.vk == libtcod.KEY_KP3: player_move_or_attack(1,1) elif key.vk == libtcod.KEY_KP7: player_move_or_attack(-1,-1) elif key.vk == libtcod.KEY_KP9: player_move_or_attack(1,-1) elif key.vk == libtcod.KEY_KP5: # wait pass
def handle_keys(): #key = libtcod.console_check_for_keypress() #real-time key = libtcod.console_wait_for_keypress(True) #turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' #exit game if game_state == 'playing': #movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): player_move_or_attack(0, -1) elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): player_move_or_attack(0, 1) elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): player_move_or_attack(-1, 0) elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): player_move_or_attack(1, 0) else: return 'didnt-take-turn'
def handle_keys(key,currentArea): shouldQuit = False currentArea = copy.deepcopy(currentArea) p = currentArea.entities[0] if key.vk == libtcod.KEY_ESCAPE: shouldQuit = True #exit game if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) newX = p.x newY = p.y #movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): newY -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): newY += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): newX -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): newX += 1 else: k = chr(key.c) if not bump(newX,newY,p.id,currentArea): currentArea.map[p.y][p.x] = currentArea.map[p.y][p.x]._replace(changed = True) currentArea.entities[0] = p._replace(x = newX,y = newY) return [shouldQuit,currentArea]
def menu(header, options, width): #First, make sure the menu has 26 or fewer items (This is due to an alphabetical selection limitation) if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options!') #implicitly calculate the height of the window, based on the header height (after word wrap) and the number # of options header_height = libtcod.console_get_height_rect(con, 0, 0, width, SCREEN_HEIGHT, header) if header == '': header_height = 0 height = len(options) + header_height #Create an offscreen console that represents the menus window, and a slightly larger one to nest the menu inside of #This will create a border effect for the inner menu, strictly asthetic outer_window = libtcod.console_new(width + 2, height + 2) window = libtcod.console_new(width, height) #Print the header to our offscreen console libtcod.console_set_default_foreground(window, libtcod.white) libtcod.console_set_default_background(window, libtcod.darker_sepia) libtcod.console_clear(window) libtcod.console_print_rect_ex(window, 0, 0, width, height, libtcod.BKGND_NONE, libtcod.LEFT, header) #Print all the options, with a corresponding ASCII character y = header_height #Get the ASCII value of the letter 'a' letter_index = ord('a') for option_text in options: text = '(' + chr(letter_index) + ') ' + option_text libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 #Blit the contents of the window to the main game screen, centered x = SCREEN_WIDTH / 2 - width / 2 y = SCREEN_HEIGHT /2 - height / 2 #Set up the outer window (which only acts as a border for the inner window, strictly graphical) libtcod.console_set_default_background(outer_window, libtcod.brass) libtcod.console_clear(outer_window) #Blit the actual message window onto the outer window, centered and one off from the borders libtcod.console_blit(window, 0, 0, width, height, outer_window, 1, 1) #Blit the outer window onto the screen, centered libtcod.console_blit(outer_window, 0, 0, width + 2, height + 2, 0, x, y) #Now that the console is presented to the player, wait for them to make a choice before doing anything else libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) #Clear the main console, so no artifacts from the menu appear libtcod.console_clear(0) #Check for fullscreen keys if key.vk == libtcod.KEY_ENTER and key.lalt: #ALT + Enter, toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) #Convert the ASCII code to an index; if it corresponds to a valid menu item, return it index = key.c - ord('a') if index >= 0 and index < len(options): return index return None
def handle_keys(): global fov_recompute #key = libtcod.console_check_for_keypress() #real-time key = libtcod.console_wait_for_keypress(True) #turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return True #exit game # Movement keys by arrows. # New for module 4: fov_recompute will force a recalculation every movement. if libtcod.console_is_key_pressed(libtcod.KEY_UP): #north player.move(0, -1) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): #south player.move (0, 1) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): #west player.move (-1, 0) fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): #east player.move (1, 0) fov_recompute = True
def handle_keys(): global playerx, playery #this is blocking, console_check_for_keypress() is nonblocking key = libtcod.console_wait_for_keypress(True) #exit if key.vk == libtcod.KEY_ESCAPE: return True #Alt+Enter: toggle fullscreen elif key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) #movement keys # checked this way so you can just hold it down elif libtcod.console_is_key_pressed(libtcod.KEY_UP): playery -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): playery += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): playerx -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): playerx += 1
def handle_keys(): game.fov_recompute = False key = libtcod.console_wait_for_keypress(True) # Alt+Enter: toggle fullscreen if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # Escape to exit game elif key.vk == libtcod.KEY_ESCAPE: return 'exit' # movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP): try_move(game.player_one, (0, -1)) game.fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): try_move(game.player_one, (0, 1)) game.fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): try_move(game.player_one, (-1, 0)) game.fov_recompute = True elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): try_move(game.player_one, (1, 0)) game.fov_recompute = True else: return 'no-action'
def player_card(): #create an off-screen console that represents the card's window window = libtcod.console_new(30, 20) #print player stats libtcod.console_set_foreground_color(window, libtcod.white) libtcod.console_print_left(window, 1, 1, libtcod.BKGND_NONE, 'Player') libtcod.console_print_left(window, 1, 2, libtcod.BKGND_NONE, 'Class: ' + player.stats.plclass) libtcod.console_print_left(window, 1, 3, libtcod.BKGND_NONE, 'STR:' + str(player.stats.str)) libtcod.console_print_left(window, 1, 4, libtcod.BKGND_NONE, 'DEX:' + str(player.stats.dex)) libtcod.console_print_left(window, 1, 5, libtcod.BKGND_NONE, 'CON:' + str(player.stats.con)) libtcod.console_print_left(window, 1, 6, libtcod.BKGND_NONE, 'INT:' + str(player.stats.int)) libtcod.console_print_left(window, 1, 7, libtcod.BKGND_NONE, 'FTH:' + str(player.stats.fth)) libtcod.console_print_left(window, 1, 8, libtcod.BKGND_NONE, 'PER:' + str(player.stats.per)) libtcod.console_print_left(window, 1, 10, libtcod.BKGND_NONE, 'AC: ' + str(player.stats.ac)) libtcod.console_print_left(window, 1, 11, libtcod.BKGND_NONE, 'Encumbrance: ') libtcod.console_print_left(window, 1, 13, libtcod.BKGND_NONE, 'Hit %: ' + str((20-player.stats.hitdie)*5)) libtcod.console_print_left(window, 1, 14, libtcod.BKGND_NONE, 'Damage: ' + str(player.stats.mindmg) + ' - ' + str(player.stats.maxdmg)) #blit the contents of "window" to the root console libtcod.console_blit(window, 0, 0, 30, 20, 0, 1, 1, 1.0, 0.7) #present the root console to the player and wait for a key-press libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: #(special case) Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) return None
def handle_keys(): global key #key = libtcod.console_check_for_keypress() #real-time key = libtcod.console_wait_for_keypress(True) #turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' #exit game if game_state == 'playing': #movement keys if key.vk == libtcod.KEY_UP or key.vk == libtcod.KEY_KP8: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN or key.vk == libtcod.KEY_KP2: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT or key.vk == libtcod.KEY_KP4: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT or key.vk == libtcod.KEY_KP6: player_move_or_attack(1, 0) elif key.vk == libtcod.KEY_HOME or key.vk == libtcod.KEY_KP7: player_move_or_attack(-1, -1) elif key.vk == libtcod.KEY_PAGEUP or key.vk == libtcod.KEY_KP9: player_move_or_attack(1, -1) elif key.vk == libtcod.KEY_END or key.vk == libtcod.KEY_KP1: player_move_or_attack(-1, 1) elif key.vk == libtcod.KEY_PAGEDOWN or key.vk == libtcod.KEY_KP3: player_move_or_attack(1, 1) elif key.vk == libtcod.KEY_KP5: pass #do nothing ie wait for the monster to come to you else: #test for other keys key_char = chr(key.c) if key_char == 'g': #pick up an item for object in objects: #look for an item in the player's tile if object.x == player.x and object.y == player.y and object.item: object.item.pick_up() break if key_char == 'i': #show the inventory; if an item is selected, use it chosen_item = inventory_menu('Press the key next to an item to use it, or any other to cancel.\n') if chosen_item is not None: chosen_item.use() if key_char == 'd': #show the inventory; if an item is selected, drop it chosen_item = inventory_menu('Press the key next to an item to drop it, or any other to cancel.\n') if chosen_item is not None: chosen_item.drop() if key_char == 'c': #show character information level_up_xp = LEVEL_UP_BASE + player.level * LEVEL_UP_FACTOR msgbox('Character Information\n\nLevel: ' + str(player.level) + '\nExperience: ' + str(player.fighter.xp) + '\nExperience to level up: ' + str(level_up_xp) + '\n\nMaximum HP: ' + str(player.fighter.max_hp) + '\nAttack: ' + str(player.fighter.power) + '\nDefense: ' + str(player.fighter.defense), CHARACTER_SCREEN_WIDTH) if key_char == 't': #go down stairs, if the player is on them if stairs.x == player.x and stairs.y == player.y: next_level() return 'didnt-take-turn'
playery -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN): playery += 1 elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT): playerx -= 1 elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT): playerx += 1 # # # Lógica # # while not libtcod.console_is_window_closed(): libtcod.console_set_default_foreground(0, libtcod.white) libtcod.console_put_char(0, int(playerx), int(playery), '@', libtcod.BKGND_NONE) libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) key = libtcod.console_check_for_keypress() if key.vk == libtcod.KEY_ENTER and key.lalt: # Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: break # exit game
def set_fullscreen(want_fullscreen=True): return libtcod.console_set_fullscreen(want_fullscreen)
def main(): # Initiate important variables 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 map_width = 80 map_height = 43 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), } # Initiate the objects that will be important in rendering and the map 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, 'Cardinal Code', False) #boolean is fullscreen or not 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 # Main game loop while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) # fov_recompute tells if the render function should recompute the FOV # recompute_fov will recompute the FOV from render_functions.py based on the initialized variables if(fov_recompute): recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) # Renders the map and the screens 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) libtcod.console_flush() # Clears entities whose position changed clear_all(con, entities) # Get what key was pressed, from sets of dictionaries action = handle_keys(key) # Then get the action from the sets of dictionaries established in input_handlers.py move = action.get('move') pickup = action.get('pickup') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] # If move has a value and the game_state is the player's state if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy # If the player's destination is not blocked, do something if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location(entities, destination_x, destination_y) # If there is an entity at the destination, do this if target: player.fighter.attack(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 pickup.', 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: 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: entity.ai.take_turn(player, fov_map, game_map, entities) 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 test_console_fullscreen(console): libtcodpy.console_set_fullscreen(False)
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) } 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( 'dejavu16x16_gs_tc.png', libtcod.FONT_TYPE_GRAYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', 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())
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() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state 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 libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) move = action.get('move') aim_weapon = action.get('aim_weapon') 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') show_character_screen = action.get('show_character_screen') exit = action.get('exit') level_up = action.get('level_up') fullscreen = action.get('fullscreen') exit_menu = action.get('exit_menu') 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 dx == 0 and dy == 0: player.move(dx, dy) fov_recompute = True elif target: # ATTACK! if player.equipment.power_bonus == 4: attack_results = player.fighter.basic_bow_attack( target) player_turn_results.extend(attack_results) else: 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 aim_weapon and game_state == GameStates.PLAYERS_TURN: # ALSO ATTACK! Working on this at the moment if player.equipment.power_bonus == 4 and game_state == GameStates.PLAYERS_TURN: message_log.add_message( Message( 'Left click a tile to fire at it or right click to cancel!', libtcod.yellow)) game_state = GameStates.AIMING else: message_log.add_message( Message('You do not have a ranged weapon equipped!', libtcod.yellow)) 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.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 game_state == GameStates.AIMING: if left_click: target_x, target_y = left_click coordinates = target_x, target_y # OKAY NOW WHAT THE F**K I DONT UNDESTAND WHY THIS WORKS OR HOW THE # VARIABLES GET FROM HERE TO THE FUNCTION I NEED THEM I MEAN JESUS CHRIST I JUST WOUND UP WITH THIS # ARRANGEMENT BY F*****G AROUND I MEAN IT WORKS BUT SERIOUSLY I DONT UNDERSTAND WHY THIS WORKS player_turn_results.append({'fire_weapon': True}) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit_menu: 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}) if exit: 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') fire_weapon = player_turn_result.get('fire_weapon') 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 fire_weapon: destination_x, destination_y = coordinates target = get_blocking_entities_at_location( entities, destination_x, destination_y) try: if target == player: message_log.add_message( Message( 'No hitting yourself. Targeting cancelled.', libtcod.yellow)) game_state = previous_game_state elif target.ai and libtcod.map_is_in_fov( fov_map, target.x, target.y): attack_results = player.fighter.basic_bow_attack( target) player_turn_results.extend(attack_results) game_state = GameStates.ENEMY_TURN elif target.ai and not libtcod.map_is_in_fov( fov_map, target.x, target.y): message_log.add_message( Message( 'That cannot be targeted. Targeting cancelled.', libtcod.yellow)) game_state = previous_game_state except: message_log.add_message( Message( 'That cannot be targeted. Targeting cancelled.', libtcod.yellow)) game_state = previous_game_state 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 config.win == True: game_state = GameStates.PLAYER_DEAD if game_state == GameStates.PLAYER_DEAD: break 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 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( dequipped.name))) 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} 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) + '!', 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 handle_keys(): global fov_recompute, mouse, key check_level_up() if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' if game_state == 'playing': if player.wait > 0: player.wait -= 1 return #movement keys if libtcod.console_is_key_pressed( libtcod.KEY_UP) or key.vk == libtcod.KEY_KP8: player_move_or_attack(0, -1) elif libtcod.console_is_key_pressed( libtcod.KEY_DOWN) or key.vk == libtcod.KEY_KP2: player_move_or_attack(0, 1) elif libtcod.console_is_key_pressed( libtcod.KEY_LEFT) or key.vk == libtcod.KEY_KP4: player_move_or_attack(-1, 0) elif libtcod.console_is_key_pressed( libtcod.KEY_RIGHT) or key.vk == libtcod.KEY_KP6: player_move_or_attack(1, 0) elif libtcod.console_is_key_pressed( libtcod.KEY_HOME) or key.vk == libtcod.KEY_KP7: player_move_or_attack(-1, -1) elif libtcod.console_is_key_pressed( libtcod.KEY_PAGEUP) or key.vk == libtcod.KEY_KP9: player_move_or_attack(1, -1) elif libtcod.console_is_key_pressed( libtcod.KEY_END) or key.vk == libtcod.KEY_KP1: player_move_or_attack(-1, 1) elif libtcod.console_is_key_pressed( libtcod.KEY_PAGEDOWN) or key.vk == libtcod.KEY_KP3: player_move_or_attack(1, 1) elif libtcod.console_is_key_pressed(libtcod.KEY_KP5): pass if not fov_recompute: key_char = chr(key.c) if key_char == 'g': #try to pick up an item for object in objects: if object.x == player.x and object.y == player.y and object.item: object.item.pick_up() break if key_char == 'i': #show the inventory chosen_item = inventory_menu( 'Press the key next to an item to use it, or any other to cancel.\n' ) if chosen_item is not None: chosen_item.use() if key_char == 'd': chosen_item = inventory_menu( 'Press the key next to an item to drop it, or any other to cancel.\n' ) if chosen_item is not None: chosen_item.drop() if key_char == '<': if stairs.x == player.x and stairs.y == player.y: next_level() if key_char == 'c': #show character information level_up_xp = LEVEL_UP_BASE + player.level + LEVEL_UP_FACTOR msgbox( 'Character Information\n' + '\nLevel: ' + str(player.level) + '\nExperience: ' + str(player.fighter.xp) + '\nExperience to level up: ' + str(level_up_xp) + '\n\nMaximum HP: ' + str(player.fighter.max_hp) + '\nAttack: ' + str(player.fighter.power) + '\nDefense: ' + str(player.fighter.defense), CHARACTER_SCREEN_WIDTH) return 'didnt-take-turn'
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'], 'rogue', False) con = libtcod.console_new(constants['screen_width'], constants['screen_height']) panel = libtcod.console_new(constants['screen_width'], constants['panel_height']) player, entities, game_map, message_log, game_state = get_game_variables( constants) fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() 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, 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'], constants['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') 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') 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(player.x + dx, player.y + dy): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: player.fighter.attack(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 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.append(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (game_state.SHOW_INVENTORY, game_state.DROP_INVENTORY): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) 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') 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 = game_state.ENEMY_TURN if item_consumed: game_state.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 handle_keys(self): for creature in self.active_objects: if hasattr(creature, "ai") == True: creature.ai() if self.player_wait > 0: self.player_wait -= 1 if self.cursor != None: self.cursor.blink() if self.time == "free": key = libtcod.console_check_for_keypress() #real-time elif self.time == "step": key = libtcod.console_wait_for_keypress(True) #turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return True #exit game #movement keys if libtcod.console_is_key_pressed(libtcod.KEY_UP) and self.player_wait == 0: self.player.move(0, -1) if self.cursor != None: self.cursor.move(0, -1) self.player_wait = game.MAX_MOVESPEED elif libtcod.console_is_key_pressed(libtcod.KEY_DOWN) and self.player_wait == 0: self.player.move(0, 1) if self.cursor != None: self.cursor.move(0, 1) self.player_wait = game.MAX_MOVESPEED elif libtcod.console_is_key_pressed(libtcod.KEY_LEFT) and self.player_wait == 0: self.player.move(-1, 0) if self.cursor != None: self.cursor.move(-1, 0) self.player_wait = game.MAX_MOVESPEED elif libtcod.console_is_key_pressed(libtcod.KEY_RIGHT) and self.player_wait == 0: self.player.move(1, 0) if self.cursor != None: self.cursor.move(1, 0) self.player_wait = game.MAX_MOVESPEED if key.vk == libtcod.KEY_CHAR: #Show or hide right-side menu if key.c == ord('l') and self.show_menu == False: self.show_menu = True self.CAMERA_WIDTH = self.CAMERA_WIDTH - self.MENU_WIDTH #Make sure when we do it, the cursor remains in view if self.mode == "look" and self.cursor.x > self.player.x + self.CAMERA_WIDTH/2: self.cursor.x = self.player.x + self.CAMERA_WIDTH/2 - 1 elif key.c == ord('l') and self.show_menu == True: self.show_menu = False self.CAMERA_WIDTH = self.CAMERA_WIDTH + self.MENU_WIDTH #Look mode elif key.c == ord('k') and self.mode == "move": self.mode = "look" self.cursor = Cursor() elif key.c == ord('k') and self.mode == "look": self.mode = "move" self.cursor = None elif key.c == ord('=') and self.GAMESPEED < 9: self.GAMESPEED += 1 self.MAX_MOVESPEED = self.GAMESPEED/2 elif key.c == ord('-') and self.GAMESPEED > 0: self.GAMESPEED -= 1 self.MAX_MOVESPEED = self.GAMESPEED/2 #Switch between turn-based and free input elif key.c == ord('t') and self.time == "free": self.time = "step"
def handle_keys(): global keys, player_turn, pause, game_speed, fov_recompute global debug_mode, traffic, temperature, continent, local, pathfinding, path_to_draw #key = libtcod.console_check_for_keypress() #real-time # key = libtcod.console_wait_for_keypress(True) #turn-based if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return "exit" #exit game elif key.vk == libtcod.KEY_SPACE: if pause: pause = False elif not pause: pause = True #return "pause" #exit game elif key.vk == libtcod.KEY_0: #increase Speed. if game_speed == SLOW_SPEED: game_speed = NORM_SPEED elif game_speed == NORM_SPEED: game_speed = FAST_SPEED elif game_speed == FAST_SPEED: game_speed = FASTEST_SPEED elif game_speed == FASTEST_SPEED: R.ui.message("can't go no fasterer! :)", libtcod.light_grey) elif key.vk == libtcod.KEY_9: #decrease speed if game_speed == SLOW_SPEED: R.ui.message("can't go no slower-er! :)", libtcod.light_grey) elif game_speed == NORM_SPEED: game_speed = SLOW_SPEED elif game_speed == FAST_SPEED: game_speed = NORM_SPEED elif game_speed == FASTEST_SPEED: game_speed = FAST_SPEED if game_state == "playing": #movement keys if key.vk == libtcod.KEY_UP or key.vk == libtcod.KEY_KP8: you.direction = "N" player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN or key.vk == libtcod.KEY_KP2: you.direction = "S" player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT or key.vk == libtcod.KEY_KP4: you.direction = "E" player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT or key.vk == libtcod.KEY_KP6: you.direction = "W" player_move_or_attack(1, 0) elif key.vk == libtcod.KEY_HOME or key.vk == libtcod.KEY_KP7: you.direction = "NW" player_move_or_attack(-1, -1) elif key.vk == libtcod.KEY_PAGEUP or key.vk == libtcod.KEY_KP9: you.direction = "NE" player_move_or_attack(1, -1) elif key.vk == libtcod.KEY_END or key.vk == libtcod.KEY_KP1: you.direction = "SW" player_move_or_attack(-1, 1) elif key.vk == libtcod.KEY_PAGEDOWN or key.vk == libtcod.KEY_KP3: you.direction = "SE" player_move_or_attack(1, 1) elif key.vk == libtcod.KEY_KP5: player_move_or_attack(0, 0) pass #do nothing ie wait for the monster to come to you else: #test for other keys key_char = chr(key.c) if key_char == "d": if debug_mode: debug_mode = False else: debug_mode = True elif key_char == "i": inventory_menu() elif key_char == "p": player_menu() elif key_char == "q": pathfinding = not pathfinding elif key_char == "c": city_menu() elif key_char == "v": city_production_menu() elif key_char == "t": #debug mode to look at temperature if temperature is False: temperature = True elif temperature is True: temperature = False elif key_char == "f": #debug key to look at traffic maps. if traffic is False: traffic = True elif traffic is True: traffic = False elif key_char == "k": if continent is False: continent = True elif continent is True: continent = False elif key_char == ",": pick_up() elif key_char == "<": go_up() elif key_char == ">": """Go Down""" go_down() if debug_mode: if key_char == "#": you.depth = 0 you.x = R.player_pos[0] you.y = R.player_pos[1] clear_consoles() local = False R.ui.message("DEBUG: Jumped to surface", colour=libtcod.light_flame) if pathfinding: if key_char == "1": path_to_draw = 1 elif key_char == "2": path_to_draw = 2 elif key_char == "3": path_to_draw = 3
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 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] 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 = 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) 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) 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 menu(header, options, width, numbers=False): if numbers: if len(options) > 9: raise ValueError('Cannot have a menu with more than 9 options.') else: 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 option header_height = libtcod.console_get_height_rect(cfg.con, 0, 0, width, cfg.SCREEN_HEIGHT, header) if header == '': header_height = 0 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 if numbers: letter_index = ord('1') else: letter_index = ord('a') for option_text in options: text = '(' + chr(letter_index) + ') ' + option_text libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 #blit the contents of "window" to the root console x = cfg.SCREEN_WIDTH / 2 - width / 2 y = cfg.SCREEN_HEIGHT / 2 - height / 2 libtcod.console_blit(window, 0, 0, width, height, 0, x, y, 1.0, 0.85) #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 #subtract the height of the header from the top edge of the menu while True: #present the root console to the player and check for input libtcod.console_flush() libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, cfg.key, cfg.mouse) if (cfg.mouse.lbutton_pressed): (menu_x, menu_y) = (cfg.mouse.cx - x_offset, cfg.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 cfg.mouse.rbutton_pressed or cfg.key.vk == libtcod.KEY_ESCAPE: return None #cancel if the player right-clicked or pressed Escape if cfg.key.vk == libtcod.KEY_ENTER and cfg.key.lalt: #Alt+Enter: toggle 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 if numbers: index = cfg.key.c - ord('1') else: index = cfg.key.c - ord('a') if index >= 0 and index < len(options): return index #if they pressed a letter that is not an option, return None #also return none if the window gets closed if cfg.key.c >= 7 or libtcod.console_is_window_closed(): return None
def main(): screen_width = 64 screen_height = 32 bar_width = 18 panel_height = 4 panel_y = screen_height - panel_height map_width = 30 map_height = 30 room_max_size = 10 room_min_size = 6 max_rooms = 30 colors = { 'dark_wall': libtcod.Color(50, 50, 50), 'dark_ground': libtcod.Color(150, 150, 150) } #Player starting add-ons player_stats = Opponent(hp=3000, mp=1000, defense=2, power=5) player_inventory = Inventory(4) #Player instantiation player = Object(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white, 'Player', blocks=True, opponent=player_stats, inventory=player_inventory) #Player stat change tests player.opponent.hp = 1500 player.opponent.mp = 500 npc = Object(int(screen_width / 2 - 5), int(screen_height / 2), '@', libtcod.yellow, 'NPC') objects = [npc, player] libtcod.console_set_custom_font( 'testfont8x16_aa_tc.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Clean Slate', 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) #key = libtcod.console_wait_for_keypress(True) key = libtcod.console_check_for_keypress() mouse = libtcod.Mouse() game_state = GameStates.PLAYER_TURN previous_game_state = game_state while not libtcod.console_is_window_closed(): render_all(con, panel, objects, player, game_map, screen_width, screen_height, bar_width, panel_height, panel_y, colors, game_state) libtcod.console_flush() clear_all(con, objects) ############################# #Player Control Section ############################# libtcod.sys_check_for_event(libtcod.EVENT_KEY_RELEASE, key, mouse) action = handle_keys(key, game_state) move = action.get('move') direction = action.get('direction') exit = action.get('exit') fullscreen = action.get('fullscreen') inventory = action.get('inventory') if inventory: previous_game_state = game_state game_state = GameStates.PLAYER_MENU libtcod.console_print(panel, 0, 0, "INVENTORY") if move: dx, dy = move if direction == 'up': player.setGlyph('^') elif direction == 'down': player.setGlyph('v') elif direction == 'left': player.setGlyph('<') else: player.setGlyph('>') if not game_map.is_blocked(player.x + dx, player.y + dy) and player.direction == direction: player.move(dx, dy) if player.direction != direction: player.setDirection(direction) if exit: if game_state == GameStates.PLAYER_MENU: 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 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 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, 'libtcod tutorial revised', 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) 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) 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) 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: 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
def main(): # Presets libtcod.sys_set_fps(120) screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 max_monsters = 20 fov_algorithm = 0 fov_light_walls = True fov_radius = 6 # Dictionary to hold colors we'll be using colors = { 'dark_wall': libtcod.Color(48, 98, 48), 'dark_ground': libtcod.Color(100, 140, 15), 'light_wall': libtcod.Color(110, 110, 48), 'light_ground': libtcod.Color(155, 188, 15), 'unexplored': libtcod.Color(15, 56, 15) } # We declare an npc npc = Entity(int(screen_width / 2 + 2), int(screen_height / 2 - 5), '@', libtcod.grey) # We declare the player player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white) # We get all entities in a list so we can iterate them entities = [player, npc] # Define the font and the screen... libtcod.console_set_custom_font( 'arial12x12.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Roguelike', False) # False because we dont want fullscreen # Main console con = libtcod.console_new(screen_width, screen_height) # We create a map randomly from the available options map_type = randint(0, 1) if map_type == 0: game_map = GameMap(map_width, map_height) game_map.make_map(80, map_width, map_height, player, max_monsters, entities) else: room_num = randint(10, max_rooms) game_map = roomGameMap(map_width, map_height) game_map.make_map(room_num, room_min_size, room_max_size, map_width, map_height, player, entities, 3) # Fov doesn't need to be computed every turn, only if we move. We use # the boolean fov_recompute to handle this fov_recompute = True fov_map = initialize_fov(game_map) # Key for holding key presses and mouse variable key = libtcod.Key() mouse = libtcod.Mouse() # Game Loop while not libtcod.console_is_window_closed(): # Check for keypress libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) # Calculate fov 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, player) fov_recompute = False libtcod.console_flush() # We overwrite the character before getting the new coordinates, so next time we draw # it will not leave a trace ''' Key handling We look for dictionary entries in action. If any of these is present it will be True. ''' action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: dx, dy = move # We check if we can actually move to the tile 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()) # On and off
def handle_keys(): if cfg.key.vk == libtcod.KEY_ENTER and cfg.key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif cfg.key.vk == libtcod.KEY_ESCAPE or libtcod.console_is_window_closed( ): return 'exit' #exit game if cfg.game_state == 'playing': #movement keys if cfg.key.vk == libtcod.KEY_UP or cfg.key.vk == libtcod.KEY_KP8: object.player_move_or_attack(0, -1) elif cfg.key.vk == libtcod.KEY_DOWN or cfg.key.vk == libtcod.KEY_KP2: object.player_move_or_attack(0, 1) elif cfg.key.vk == libtcod.KEY_LEFT or cfg.key.vk == libtcod.KEY_KP4: object.player_move_or_attack(-1, 0) elif cfg.key.vk == libtcod.KEY_RIGHT or cfg.key.vk == libtcod.KEY_KP6: object.player_move_or_attack(1, 0) elif cfg.key.vk == libtcod.KEY_HOME or cfg.key.vk == libtcod.KEY_KP7: object.player_move_or_attack(-1, -1) elif cfg.key.vk == libtcod.KEY_PAGEUP or cfg.key.vk == libtcod.KEY_KP9: object.player_move_or_attack(1, -1) elif cfg.key.vk == libtcod.KEY_END or cfg.key.vk == libtcod.KEY_KP1: object.player_move_or_attack(-1, 1) elif cfg.key.vk == libtcod.KEY_PAGEDOWN or cfg.key.vk == libtcod.KEY_KP3: object.player_move_or_attack(1, 1) elif cfg.key.vk == libtcod.KEY_KP5 or cfg.key.vk == libtcod.KEY_SPACE: pass #do nothing ie wait for the monster to come to you elif cfg.key.vk == libtcod.KEY_INSERT or cfg.key.vk == libtcod.KEY_KP0: #toggle real time mode cfg.run_realtime = not cfg.run_realtime else: #test for other keys key_char = chr(cfg.key.c) # use for alphabetical keys # use key.text for symbolic keys ''' if key_char == 'g': #pick up an item for obj in objects: #look for an item in the player's tile if obj.x == cfg.player.x and obj.y == cfg.player.y and obj.item: obj.item.pick_up() break if key_char == 'i': #show the inventory; if an item is selected, use it chosen_item = inventory_menu('Press the key next to an item to use it, or any other to cancel.\n') if chosen_item is not None: chosen_item.use() if key_char == 'd': #show the inventory; if an item is selected, drop it chosen_item = inventory_menu('Press the key next to an item to drop it, or any other to cancel.\n') if chosen_item is not None: chosen_item.drop() if key_char == 'c': #show character information level_up_xp = cfg.LEVEL_UP_BASE + cfg.player.level * cfg.LEVEL_UP_FACTOR gui.msgbox('Character Information\n\nLevel: ' + str(cfg.player.level) + '\nExperience: ' + str(cfg.player.fighter.xp) + '\nExperience to level up: ' + str(level_up_xp) + '\n\nMaximum HP: ' + str(cfg.player.fighter.max_hp) + '\nAttack: ' + str(cfg.player.fighter.power) + '\nDefense: ' + str(cfg.player.fighter.defense), cfg.CHARACTER_SCREEN_WIDTH) ''' if key_char == 's': #show monster stats gui.display_monster_stats() if key_char == 'd': #show monster descriptions gui.display_description() if key_char == '/' or key_char == '?': #show monster descriptions gui.display_controls() if key_char == 'r': #toggle real time mode cfg.run_realtime = not cfg.run_realtime if key_char == 'q': #quit game while running return 'exit' ''' if cfg.key.text == '>' or cfg.key.text == '+': #go down stairs, if the player is on them if cfg.stairs.x == cfg.player.x and cfg.stairs.y == cfg.player.y: next_level() ''' if cfg.run_realtime: return 'wait' else: return 'didnt-take-turn'
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 map_width = 80 map_height = 43 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, 64, 128), 'dark_ground': libtcod.Color(0, 96, 128), 'light_wall': libtcod.Color(63, 63, 63), 'light_ground': libtcod.Color(159, 159, 159) } 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, 'Derelict Expedition', 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 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, 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) mouse_action = handle_mouse(mouse) 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') 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.', 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 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): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) 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') 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_dropped: entities.append(item_dropped) 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 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(): #initilize main variables 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 map_width = 80 map_height = 43 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 #define color palette colors = { 'dark_wall': libtcod.Color(55, 50, 45), 'dark_ground': libtcod.Color(15, 15, 15), 'light_wall': libtcod.Color(70, 55, 40), 'light_ground': libtcod.Color(30, 20, 15) } #Create Player 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] player_won = False #set up screen libtcod.console_set_custom_font( 'arial12x12.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'SimpleRogue', False) con = libtcod.console_new(screen_width, screen_height) panel = libtcod.console_new(screen_width, panel_height) key = libtcod.Key() mouse = libtcod.Mouse() #Generate map with entities 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 = initializ_fov(game_map) game_state = GameStates.PLAYERS_TURN previous_game_state = game_state message_log = MessageLog(message_x, message_width, message_height) # main game loop while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) #Update Display 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) #Define possible actions 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') #Clear the last set of results from actions player_turn_results = [] #Handle actions #move the player 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: player.fighter.attack(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 #try to pick up something 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)) #display the inventory screen if show_inventory: if game_state != GameStates.SHOW_INVENTORY: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY #use an item in the 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)) #exit screen or close game if exit: if game_state == GameStates.SHOW_INVENTORY: game_state = previous_game_state else: return True #toggle full screen view if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) #Display results of player actions 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_states = 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 #check for win (player killed everything) fighter_count = 0 for entity in entities: if entity.fighter is not None and entity.name != 'Player': fighter_count += 1 if fighter_count == 0 and player_won != True: player_won = True message_log.add_message( Message("I hope you're proud of yourself...", libtcod.yellow)) message_log.add_message(Message("You monster!", libtcod.red)) #Handle enemy actions and display results 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 else: game_state = GameStates.PLAYERS_TURN
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 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150) } 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( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Roguelike Title', 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) key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) render_all(con, entities, game_map, screen_width, screen_height, colors) 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) if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def initialise(self): libtcod.console_set_custom_font('framework/consolas10x10_gs_tc.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(self.screen_width, self.screen_height, 'Goldmine', False) libtcod.sys_set_fps(self.fps) libtcod.console_set_fullscreen(True)
def handle_keys(): global fov_recompute, game_state global key if key.vk == libtcod.KEY_ENTER and key.lalt: # Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' # exit game if game_state == 'playing': # movement keys if key.vk == libtcod.KEY_UP: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_KP8: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_KP2: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_KP4: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT: player_move_or_attack(1, 0) elif key.vk == libtcod.KEY_KP6: player_move_or_attack(1, 0) elif key.vk == libtcod.KEY_KP1: player_move_or_attack(-1, 1) elif key.vk == libtcod.KEY_KP3: player_move_or_attack(1, 1) elif key.vk == libtcod.KEY_KP7: player_move_or_attack(-1, -1) elif key.vk == libtcod.KEY_KP9: player_move_or_attack(1, -1) elif key.vk == libtcod.KEY_KP5: player.move(0, 0) fov_recompute = True else: key_char = chr(key.c) item_picked_up = None if key_char == ',' or key_char == 'g': for object in objects: if object.x == player.x and object.y == player.y and object.item: object.item.pick_up() item_picked_up = True break if not item_picked_up: message('Nothing to pick up', libtcod.light_crimson) if key_char == 'i': chosen_item = inventory_menu( 'Press the key next to an item to use it, or any other key to cancel.\n' ) if chosen_item is not None: chosen_item.use() if key_char == 'd': chosen_item = inventory_menu('Choose an item to drop\n') if chosen_item is not None: chosen_item.drop() return 'didnt-take-turn'
def handle_keys(): # 控制键位与角色行走 global key, race if key.vk == libtcod.KEY_ENTER and key.lalt: # Alt + Enter: 全屏 libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' # 按下 ESC 则 exit game if game_state == 'playing': if key.vk == libtcod.KEY_UP or key.vk == libtcod.KEY_KP8: player_move_or_attack(0, -1) elif key.vk == libtcod.KEY_DOWN or key.vk == libtcod.KEY_KP2: player_move_or_attack(0, 1) elif key.vk == libtcod.KEY_LEFT or key.vk == libtcod.KEY_KP4: player_move_or_attack(-1, 0) elif key.vk == libtcod.KEY_RIGHT or key.vk == libtcod.KEY_KP6: player_move_or_attack(1, 0) elif key.vk == libtcod.KEY_HOME or key.vk == libtcod.KEY_KP7: player_move_or_attack(-1, -1) elif key.vk == libtcod.KEY_PAGEUP or key.vk == libtcod.KEY_KP9: player_move_or_attack(1, -1) elif key.vk == libtcod.KEY_END or key.vk == libtcod.KEY_KP1: player_move_or_attack(-1, 1) elif key.vk == libtcod.KEY_PAGEDOWN or key.vk == libtcod.KEY_KP3: player_move_or_attack(1, 1) elif key.vk == libtcod.KEY_KP5: pass # 等待 else: #test for other keys key_char = chr(key.c) if key_char == 'g': # 拿起一件物品 for object in objects: if object.x == player.x and object.y == player.y and object.item: object.item.pick_up() break if key_char == 'i': # 显示库存 chosen_item = inventory_menu( 'Press the key next to an item to use it, or any other to cancel.\n' ) if chosen_item is not None: chosen_item.use() if key_char == 'd': # 丢弃 chosen_item = inventory_menu( 'Press the key next to an item to drop it, or any other to cancel.\n' ) if chosen_item is not None: chosen_item.drop() if key_char == 'c': # 显示角色信息 level_up_xp = LEVEL_UP_BASE + player.level * LEVEL_UP_FACTOR msgbox( 'Character Information\n\nLevel: ' + str(player.level) + '\nExperience: ' + str(player.fighter.xp) + '\nExperience to level up: ' + str(level_up_xp) + '\n\nMaximum HP: ' + str(player.fighter.max_hp) + '\nAttack: ' + str(player.fighter.power) + '\nDefense: ' + str(player.fighter.defense), CHARACTER_SCREEN_WIDTH) if key_char == 's': # 下楼梯 if stairs.x == player.x and stairs.y == player.y: next_level() if key_char == 'q': story() # 各个种族的描述 return 'didnt-take-turn'
def main(): # Adding the main function for Python 3 compatibility # Setting constants and global variables screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height # Adding variables Message log display to show events. 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 = 0 fov_light_walls = True fov_radius = 10 max_monsters_per_room = 3 brown_color = libtcod.flame * libtcod.light_blue colors = { 'dark_wall': brown_color, # Color(0, 0, 100), 'dark_ground': libtcod.desaturated_orange, # Color(50, 50, 150) 'light_wall': libtcod.dark_flame, 'light_ground': libtcod.light_orange } # Coloring our tiles # LIMIT_FPS = 20 # Unused for now # Setting player coordinate starting point at center of console fighter_component = Fighter(hp=30, defense=2, power=5) # Setting player attributes player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component) entities = [player] # Initializing the library font libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # Now creating the window with size constants, title, and whether fullscreen libtcod.console_init_root(screen_width, screen_height, 'python/libtcod tutorial', False) con = libtcod.console_new( screen_width, screen_height) # Allows the ability to create new consoles panel = libtcod.console_new( screen_width, panel_height) # New console to hold HP and Messages game_map = GameMap(map_width, map_height) # Initialize the game map 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 # Whether to reset the Field of View, True for start of game fov_map = initialize_fov(game_map) #Initialize the Field of View message_log = MessageLog(message_x, message_width, message_height) key = libtcod.Key() # Setting keyboard variable for input mouse = libtcod.Mouse() # Setting mouse variable for input game_state = GameStates.PLAYERS_TURN # Sets initial game_state to players turn # Next is the main game loop. We basically print the @ character to the screen in white while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) #libtcod.console_set_default_foreground(0, libtcod.white) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) # Changing the way the console is initialized so we can reference different consoles later 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( ) # Flush the console which writes any changes to the screen clear_all(con, entities) # New setup to call handle_keys() function from input_handlers.py action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] # new dictionary 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: # Are you running into a monster? attack_results = player.fighter.attack( target) # Attack monster player_turn_results.extend( attack_results) # Get results of attack else: player.move(dx, dy) fov_recompute = True # Recompute the FOV upon movement game_state = GameStates.ENEMY_TURN # Sets state to players turn. if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # Iterate through the results # Player Results Loop for player_turn_result in player_turn_results: message = player_turn_result.get('message') # Get the message part dead_entity = player_turn_result.get( 'dead') # Get the part as to whether dead or not if message: message_log.add_message( message) # Prints any messages for the player turn if dead_entity: # Check is something dead this turn if dead_entity == player: # Is the dead thing the player? message, game_state = kill_player( dead_entity) # Run kill_player function else: message = kill_monster( dead_entity) # Run kill_monster function message_log.add_message(message) # Enemy Results Loop if game_state == GameStates.ENEMY_TURN: # Checks to see if enemy turn for entity in entities: # Cycles through entities looking for monsters if entity.ai: # If entity is not the player and has ai. # Set a list that calls the take_turn function for the ai enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: # Iterate through the list message = enemy_turn_result.get( 'message') # Gather any messages for that ai dead_entity = enemy_turn_result.get( 'dead') # get and dead comments if message: message_log.add_message( message ) # Print any messages for the turn of the ai if dead_entity: # Check if dead entity this turn if dead_entity == player: # Is it the player? message, game_state = kill_player( dead_entity ) # If yes then run kill_player and show message from results else: message = kill_monster( dead_entity ) # If it's the monster, then kill it. message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: # Did the player die? break # If dead player then end game. if game_state == GameStates.PLAYER_DEAD: break # Ends game if player dies and monster has died at same time. else: # Set the game_state back to players turn game_state = GameStates.PLAYERS_TURN
def main(): """The main program. Initializes data, then runs through the main loop until user quits.""" previous_game_state = 'NONE' game_state = 'INIT' entities = [] tiles = [] for y in range(init.map_height): for x in range(init.map_width): tiles.append({ 'Name': 'wall', 'Position': { 'x': x, 'y': y, 'z': 0 }, 'Char': '#', 'Color': colors.dark_wall, 'Size': 1, 'Opacity': 1, 'Solid': 1, 'Seen': False, 'Health': 100, 'Map': True, 'Defense': 0, 'ZOrder': 0, 'A*Highlight': False }) player = { 'Name': 'player', 'Player': True, 'Color': colors.white, 'Char': '@', 'Movement': { 'x': 0, 'y': 0, 'z': 0 }, 'Position': { 'x': 0, 'y': 0, 'z': 1 }, 'Opacity': 1, 'Compressability': 0, 'Size': 0.85, 'Solid': 1, 'Health': 20, 'MaxHealth': 20, 'Attack': 3, 'Defense': 0, 'Alive': True, 'ZOrder': 2, # above items / bodies 'Inventory': { 'capacity': 20, 'items': [] }, 'Action': '' } monsters = [] number_of_monsters = randint(init.min_monsters, init.max_monsters) for i in range(number_of_monsters): if randint(0, 100) < 50: # add an orc monsters.append({ 'Name': 'orc', 'Color': colors.desaturated_green, 'Char': 'o', 'Movement': { 'x': 0, 'y': 0, 'z': 0 }, 'Position': { 'x': 0, 'y': 0, 'z': 1 }, 'Opacity': 1, 'Size': 0.85, 'Solid': 0.85, 'Health': 6, 'Attack': 1, 'Defense': 0, 'Goal': None, 'Alive': True, 'ZOrder': 2, 'Inventory': { 'capacity': 3, 'items': [] }, 'Action': '' }) else: # Add a troll monsters.append({ 'Name': 'troll', 'Color': colors.darker_green, 'Char': 'T', 'Movement': { 'x': 0, 'y': 0, 'z': 0 }, 'Position': { 'x': 0, 'y': 0, 'z': 1 }, 'Opacity': 1, 'Size': 0.85, 'Solid': 0.85, 'Health': 9, 'Attack': 2, 'Defense': 0, 'Goal': None, 'Alive': True, 'ZOrder': 2, 'Inventory': { 'capacity': 3, 'items': [] }, 'Action': '' }) items = [] number_of_items = randint(init.min_items, init.max_items) for i in range(number_of_items): items.append({ 'Name': 'healing potion', 'Color': colors.violet, 'Char': '!', 'Position': { 'x': 0, 'y': 0, 'z': 0 }, 'Opacity': 1, 'Size': 0.2, 'Solid': 1, 'Healing': 5, 'ZOrder': 1 }) # mutating the tiles into a map, returning the corners of the rooms rooms = game_map.make_map(tiles) # add stuff to rooms, randomly for thing in [player] + monsters + items: place_in_random_room(thing, rooms) # note we are giving initialize_fov tiles, not rooms fov_map = make_fov_map(tiles) # add everything into the entities list for processing entities = [player] + monsters + items + tiles # notifications are the game messages displayed for the player to read notifications = [] keyb = libtcod.Key() mouse = libtcod.Mouse() while True: ###################### Here is the main loop... do the processing ################### # TODO: drop cool-downs until someone is at 0 # take that turn for that entity # if not player's turn, continue looping # if player's turn, get input actions = [] if game_state == 'INIT': actions += processAllEntities(process_tick, player, entities, fov_map, mouse) game_state = 'DEFAULT' if game_state == 'DEFAULT': if not keyb.vk == libtcod.KEY_NONE: # process all entities [tick] actions += processAllEntities(process_tick, player, entities, fov_map, mouse) if mouse.x: # process all entities [mousing] actions += processAllEntities(process_mouse_move, player, entities, fov_map, mouse) if mouse.lbutton_pressed or mouse.rbutton_pressed: # process all entities [clicking] actions += processAllEntities(process_click, player, entities, fov_map, mouse) ############################# The Rendering ################################ # render all entitites in z order entities_in_render_order = sorted(entities, key=lambda x: x['ZOrder']) for entity in entities_in_render_order: process_all_rendering(entity, fov_map) # render everything libtcod.console_blit(init.con, 0, 0, init.screen_width, init.screen_height, 0, 0, 0) # render the UI libtcod.console_set_default_background(init.panel, libtcod.black) libtcod.console_clear(init.panel) # render any notifications or identify imperitives for action in actions: notification = action.get('notification') identify = action.get('identify') pickupables = action.get('pickupables') if notification: # get notifications ready to render (wrapping, scrolling, etc...) add_notification(notifications, notification) if identify: # render the coords render_to_panel(init.panel, 10, 6 - identify['z'], identify['text']) if pickupables: print('pickupables: ', pickupables) # render the game messages, one line at a time y = 1 for notification in notifications: libtcod.console_set_default_foreground(init.panel, notification['color']) libtcod.console_print_ex(init.panel, init.message_x, y, libtcod.BKGND_NONE, libtcod.LEFT, notification['text']) y += 1 # render the health bar render_bar(init.panel, 1, 1, init.bar_width, 'HP', player['Health'], player['MaxHealth'], libtcod.light_red, libtcod.darker_red) # render the coords # render_to_panel(init.panel, 6, 5, 'X: {0} Y: {1}'.format(player['Position']['x'], player['Position']['y'])) libtcod.console_blit(init.panel, 0, 0, init.screen_width, init.panel_height, 0, 0, init.panel_y) # maybe render the inventory? if game_state == 'SHOW_INVENTORY': if player['Action'] == 'USE': render_inventory_menu( 'Press the key next to an item to use it, or Esc to cancel.\n', player['Inventory']['items'], 50) if player['Action'] == 'DROP': render_inventory_menu( 'Press the key next to an item to drop it, or Esc to cancel.\n', player['Inventory']['items'], 50) # flush it all to the screen libtcod.console_flush() ###################### That's it. Now wait for the player's next action ################### # now, get the keyboard input # key = libtcod.console_wait_for_keypress(True) # 0000001 event mask 1 == key down # 0000010 event mask 2 == key up # 0000100 event mask 4 == mouse move # 0001000 event mask 16 == mouse click # 0001101 mouse move & click, key down == 21 evt = libtcod.sys_wait_for_event(21, keyb, mouse, True) # # NOTE: replace above with this to go real-time # libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, keyb, mouse # map keypress to action action = handle_keys(keyb, game_state) move = action.get('move') pickup = action.get('pickup') drop = action.get('drop') exit = action.get('exit') attack = action.get('action') fullscreen = action.get('fullscreen') use = action.get('use') inventory_index = action.get('inventory_index') close_inventory = action.get('close_inventory') player_dead = action.get('player_dead') ################################# handle keyboard input ################################### if 'Movement' in player: if move: # if user wants to move, set the Movement component, then let the processors handle the rest (follow this pattern with any action?) dx, dy = move player['Movement']['x'] = dx player['Movement']['y'] = dy else: player['Movement']['x'] = 0 player['Movement']['y'] = 0 if pickup: player['Action'] = 'PICKUP' if drop: print('player wants to drop something') player['Action'] = 'DROP' previous_game_state = game_state game_state = 'SHOW_INVENTORY' if use: print('player wants to use something') player['Action'] = 'USE' previous_game_state = game_state game_state = 'SHOW_INVENTORY' if player_dead: print('player dead game state') game_state = 'PLAYER_DEAD' if inventory_index is not None and game_state != 'PLAYER_DEAD' and inventory_index < len( player['Inventory']['items']): item = player['Inventory']['items'][inventory_index] if player['Action'] == 'USE': print('going to try to use ', item['Name']) game_state = previous_game_state item['Using'] = True # trigger the use of the item if player['Action'] == 'DROP': print('going to try to drop ', item['Name'], ' contained by ', item['ContainedBy']['Name']) game_state = previous_game_state item['Dropping'] = True # trigger dropping the item if close_inventory: game_state = previous_game_state if exit: print('we hit escape') if game_state == 'SHOW_INVENTORY': # TODO: if we exit the inventory menu without selecting anything # monsters will have an extra turn! game_state = previous_game_state else: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def handle_keys(): global need_fov_refresh # Movement keys key = libtcod.console_check_for_keypress(True) if key.vk == libtcod.KEY_ENTER and key.lalt: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' # Only allow movement if we're in the 'playing' state if game_state == 'playing': if key.c == ord('k'): player_move_or_attack(0, -1) need_fov_refresh = True elif key.c == ord('j'): player_move_or_attack(0, 1) need_fov_refresh = True elif key.c == ord('h'): player_move_or_attack(-1, 0) need_fov_refresh = True elif key.c == ord('l'): player_move_or_attack(1, 0) need_fov_refresh = True elif key.c == ord('y'): player_move_or_attack(-1, -1) need_fov_refresh = True elif key.c == ord('u'): player_move_or_attack(1, -1) need_fov_refresh = True elif key.c == ord('n'): player_move_or_attack(1, 1) need_fov_refresh = True elif key.c == ord('b'): player_move_or_attack(-1, 1) need_fov_refresh = True # Pick up an item on the ground elif key.c == ord('g'): for object in objects: if object.x == player.x and object.y == player.y and object.item: object.item.pick_up(player) # View inventory elif key.c == ord('i'): item = show_inventory('Here\'s what you\'ve got...') if item != None: item.use() # Close door elif key.c == ord('c'): door_object = get_first_adjacent(player, 'door') if door_object is not None: door_object.door.close() need_fov_refresh = True else: message('There isn\'t a door close enough to shut.') elif key.c == ord('s'): smashable_object = get_first_adjacent(player, 'smashable') if smashable_object is not None: smashable_object.smashable.smash(player) need_fov_refresh = True else: message('There isn\'t anything nearby to smash') # Wait a turn elif key.c == ord('.'): pass else: return 'didnt-take-turn'
def play_game(player, entities, game_map, message_log, game_state, con, panel, cursor, constants): colors = constants['colors'] fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYER_TURN previous_game_state = game_state # Keep track of targeting item targeting_item = None # === 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, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) render_all(con, panel, cursor, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_width'], constants['panel_x'], mouse, constants['colors'], game_state, targeting_item, key) fov_recompute = False libtcod.console_flush() clear_all(con, entities) # === PLAYER TURN === # Handle player action 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_equipment = action.get('show_equipment') 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 = [] # Check what player did this turn if move and game_state == GameStates.PLAYER_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy # Check if tile is passable 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.take_step(dx, dy, game_map) # Recompute FOV everytime the player moves fov_recompute = True game_state = GameStates.ENEMY_TURN elif wait: 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.', colors['text_warning'])) if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if show_equipment: previous_game_state = game_state game_state = GameStates.SHOW_EQUIPMENT 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.SHOW_EQUIPMENT: item = player.equipment.equipped[inventory_index] 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.PLAYER_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) libtcod.console_clear(con) break else: message_log.add_message( Message('There are no stairs here.', colors['text_warning'])) 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 select_target: # current_x, current_y = player.x, player.y # dx, dy = select_target # new_x, new_y = current_x + dx, current_y + dy 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.SHOW_EQUIPMENT, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN }: game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) elif game_state == GameStates.PLAYER_DEAD: # Delete save file if player exits after dying if os.path.isfile('savegame.dat'): os.remove('savegame.dat') return 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()) # toggle on/off # At the end of the player's turn, evaluate results and print messages to log 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 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: # Remove item from map (now in inventory) entities.remove(item_added) # Takes a turn game_state = GameStates.ENEMY_TURN if item_consumed: 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), colors['text_equip'])) if dequipped: message_log.add_message( Message( 'You dequipped the {0}'.format(dequipped.name), colors['text_unequip'])) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYER_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 xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('You gain {0} experience'.format(xp))) if leveled_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 # === MONSTER 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.PLAYER_TURN
def handle_keys(): global fov_recompute global playerx, playery global key # movement and combat keys can only be used in the play state if game_state == 'playing': if key.vk == libtcod.KEY_UP or key.vk == libtcod.KEY_KP8: player.body.move_or_attack(0, -1) fov_recompute = True elif key.vk == libtcod.KEY_KP7: player.body.move_or_attack(-1, -1) fov_recompute = True elif key.vk == libtcod.KEY_DOWN or key.vk == libtcod.KEY_KP2: player.body.move_or_attack(0, 1) fov_recompute = True elif key.vk == libtcod.KEY_KP1: player.body.move_or_attack(-1, 1) fov_recompute = True elif key.vk == libtcod.KEY_LEFT or key.vk == libtcod.KEY_KP4: player.body.move_or_attack(-1, 0) fov_recompute = True elif key.vk == libtcod.KEY_KP3: player.body.move_or_attack(1, 1) fov_recompute = True elif key.vk == libtcod.KEY_RIGHT or key.vk == libtcod.KEY_KP6: player.body.move_or_attack(1, 0) fov_recompute = True elif key.vk == libtcod.KEY_KP9: player.body.move_or_attack(1, -1) fov_recompute = True if key.vk == libtcod.KEY_ENTER and key.lalt: #Alt+Enter: toggle fullscreen libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) elif key.vk == libtcod.KEY_ESCAPE: return 'exit' #exit game else: #test for other keys key_char = chr(key.c) if key_char == 'g': #pick up an item for object in objects: #look for an item in the player's tile if object.x == player.x and object.y == player.y and object.item: object.item.pick_up(player) break if key_char == 'i': #show the inventory chosen_item = inventory_menu( 'Press the key next to an item to use it, or any other to cancel.\n' ) if chosen_item is not None: chosen_item.use() return '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 = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state 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 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.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: 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') 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: game_state = GameStates.ENEMY_TURN 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( dequipped.name))) 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} experience points.'.format(xp))) if leveled_up: 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 handle_keys(game): libtcod.console_flush() event = libtcod.sys_check_for_event(1 | 4 | 8 | 16, key, mouse) mousestatus = libtcod.mouse_get_status() (a, b) = game.upper_left_of_map() (x, y) = (mousestatus.cx + a, mousestatus.cy + b) #If the player clicks an acceptable tile, build a path to that location and start pathing toward it. if mousestatus.lbutton_pressed and game.map[x][y].explored: game.state = 'pathing' fov_pathing_map = map.new_fov_pathing_map(game.map) game.player.mover.path = libtcod.path_new_using_map( fov_pathing_map, 1.41) libtcod.path_compute(game.player.mover.path, game.player.x, game.player.y, x, y) # Full screen / window switching if key.vk == libtcod.KEY_ENTER and (key.lalt | key.ralt): libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # This is a catch-all for situations where one needs to 'back out' of wherever one is. # An obvious one is to quit the game. if key.vk == libtcod.KEY_ESCAPE: return 'exit' # Movement keys - used if actually playing. if game.state == 'playing': dx = dy = 0 key_char = chr(key.c) if key_char in ('q', 'w', 'e'): dy = -1 if key_char in ('q', 'a', 'z'): dx = -1 if key_char in ('z', 'x', 'c'): dy = 1 if key_char in ('c', 'd', 'e'): dx = 1 if key.vk == libtcod.KEY_UP: dy = -1 elif key.vk == libtcod.KEY_DOWN: dy = 1 elif key.vk == libtcod.KEY_LEFT: dx = -1 elif key.vk == libtcod.KEY_RIGHT: dx = 1 elif key_char in ('1'): game.debug_showexplored = not (game.debug_showexplored) elif key_char in ('2'): game.debug_troubletiles = not (game.debug_troubletiles) # Eventually, need keys for working with inventory and items. if (dx | dy): action = actors.player_move(game, dx, dy) if action is not 'blocked': game.map_movement = True return 'tookturn' elif game.state == 'in menu': pass else: return 'no action'