def menu(header, options, width): if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options') # get geometry header_height = libtcod.console_get_height_rect(con, 0, 0, width, SCREEN_HEIGHT, header) height = len(options) + header_height # create an off screen window 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) #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 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) index = key.c - ord('a') if index >= 0 and index < len(options): return index return None
def play_game(): player_action = None while not libtcod.console_is_window_closed(): # Render the screen render_all() libtcod.console_flush() check_level_up() # Erease all objects at their old locations, befor they move for object in objects: object.clear() # Handle keys and exit if needed player_action = handle_keys() if player_action == 'exit': save_game() # Save the current game before exit break # Let the monsters take their turn if game_state == 'playing': for object in objects: if object.ai: # Don't take a turn yet if still waiting if object.wait > 0: object.wait -= 1 else: object.ai.take_turn()
def menu(header, options, width): if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options.') #calculate the total height for the header and 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 represent 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 option 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) #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 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 play_game(): global key, mouse, game_state, game_msgs, map_state, inventory game_state = 'playing' map_state = 'map' game_msgs = [] inventory = [] equipment_component = Equipment(slot = 'right hand', add_equipment_skill = ('shot', 'reload')) gun = Object(1, 1, '/', 'gun', libtcod.sky, equipment = equipment_component) inventory.append(gun) # initialize the mouse and key with libtcod libaray mouse = libtcod.Mouse() key = libtcod.Key() while not libtcod.console_is_window_closed(): #check the input from the keyboard or mouse libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE, key, mouse) #display all (include the tile and objects) render_all() libtcod.console_flush() #handle the keyboard or mouse input player_action = handle_keys() if player_action == 'exit': break if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn()
def play_game(): player_action = None while not libtcod.console_is_window_closed(): # Render the screen. render_all() libtcod.console_flush() # Clean the console. libtcod.console_clear(con) # Handle keys and exit game if needed. player_action = handle_keys() if player_action == 'exit': break # Let the monsters take their turn. if game_state == 'playing' or game_state == 'custom playing': for object in objects: if object.ai: if object.wait > 0: object.wait -= 1 else: object.ai.take_turn() object.wait = object.speed
def showDebugScreen(self): # store the current view behind_window = libtcod.console_new(SCREEN_WIDTH, SCREEN_HEIGHT) libtcod.console_blit(0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, behind_window, 0, 0, 1.0, 1.0) # show the background image, at twice the regular console resolution img = libtcod.image_load("./media/menu_debug.png") libtcod.image_blit_2x(img, 0, 0, 0) while not libtcod.console_is_window_closed(): # show options and wait for the player's choice choice = self.showMenu( "Select debug option:", ["Run some test code!", "Show me some game stuff!", "Back"], # Choice 0 # Choice 1 # Choice 2 36, ) # interpret choice if choice is None: continue if choice == 0: print "Running some test code!" self.runTestCode() self.showMessage("Test code complete!", "There might be some output in the console...", 36) continue elif choice == 1: print "Showing some game stuff!" self.newGame() self.showGameScreen() elif choice == 2: # quit print "Back" break # Clean up (restore whatever was behind this window) libtcod.console_blit(behind_window, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0, 1.0, 1.0) libtcod.console_flush()
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 play_game(): global key, mouse player_action = None mouse = libtcod.Mouse() key = libtcod.Key() #main loop while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) #render the screen render_all() libtcod.console_flush() #level up if needed check_level_up() #erase all objects at their old locations, before they move for object in objects: object.clear() #handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break #let monsters take their turn if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn()
def play_game(self): """Where's the game @.""" #Start main loop while not libtcod.console_is_window_closed(): self.player_action = None render_all() #render stuff libtcod.console_flush() #refresh the console #erase before move for ent in self.entities: ent.clear() #import keys handling self.player_action = handle_keys() if self.player_action == None: self.player_action = 'didnt-take-turn' if self.player_action == 'exit': #if pressing a key returns 'exit' - close the window break #'AI' takes turns if self.gamestate == 'playing' and self.player_action != 'didnt-take-turn' or Game.gamemode == 'RT': for ent in self.entities: if ent.ai: ent.ai.take_turn() if ent.killer and ent.x == self.player.x and ent.y == self.player.y: player_death() elif ent.point and ent.x == self.player.x and ent.y == self.player.y: self.score += 1 ent.clear() Game.entities.remove(ent) spawn_points()
def play_game(): global key, mouse, game_state player_action = None mouse = libtcod.Mouse() key = libtcod.Key() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE, key, mouse) render_all() libtcod.console_flush() player.player.check_level_up() for object in objects: object.clear() if game_state == 'playing-waiting-for-input' or game_state == 'dead': player_action = handle_keys() #print "player_action: %s" % player_action if player_action == 'exit': save_game() break elif player_action is None: game_state = 'playing' if game_state == 'playing': scheduler.tick()
def show_menu(self, options, header, hide_options=False): """ Show menu with header and options in the screen. """ #calculate total height for the header (after auto-wrap) header_height = libtcod.console_get_height_rect(self.inv_window, 0, 0, MAP_WIDTH, MAP_HEIGHT, header) #print the header, with auto-wrap libtcod.console_set_default_foreground(self.inv_window, libtcod.white) libtcod.console_print_rect_ex(self.inv_window, 0, 0, MAP_WIDTH, MAP_HEIGHT, libtcod.BKGND_NONE, libtcod.LEFT, header) #print all the options y = header_height for (option_key, option_text) in options: if hide_options is True: text = option_text else: text = '(' + option_key + ') ' + option_text libtcod.console_print_ex(self.inv_window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 #blit the contents of "self.inv_window" to the root console x, y, _ = SCREEN_RECT.top_left.coords libtcod.console_blit(self.inv_window, 0, 0, MAP_WIDTH, MAP_HEIGHT, 0, x, y, 1.0, 0.7) libtcod.console_flush() libtcod.console_clear(self.inv_window)
def play_game(): global key, mouse player_action = None mouse = libtcod.Mouse() key = libtcod.Key() #main loop while not libtcod.console_is_window_closed(): #print to screen zero is the console to be printed to #libtcod.console_set_default_foreground(0, libtcod.crimson) #print character #libtcod.console_put_char(con,playerx,playery, '@', libtcod.BKGND_NONE) libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key, mouse) render_all() #flush console(present changes to console) libtcod.console_flush() #check for player level up check_level_up() for object in objects: object.clear() #handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break #let monsters take their turn if game_state == 'playing' and player_action != 'turnNotTaken': for object in objects: if object.ai: object.ai.take_turn()
def play_game(): global key, mouse player_action = None mouse = libtcod.Mouse() key = libtcod.Key() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse) render_all() libtcod.console_flush() #check for player level up now, while objects are visible behind the menu check_level_up() #erase all objects after render in case they move before next flush for object in objects: object.clear() #handle player input and exit game if appropriate player_action = handle_keys() if player_action == 'exit': save_game() break #give monsters 1 turn for all player turns taken if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn()
def draw(self): libtcod.console_set_alignment(0, libtcod.CENTER) libtcod.console_print(0, self.text_base[0], self.text_base[1], self.title_text) libtcod.console_print(0, self.text_base[0], self.text_base[1] + 2, "a " + self.option_one_text) libtcod.console_print(0, self.text_base[0], self.text_base[1] + 4, "b " + self.option_two_text) libtcod.console_flush() libtcod.console_clear(0)
def play_game(): player_action = None make_world_map() # main loop while game_state == 'playing': libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) # render the screen render_all() libtcod.console_flush() # erase all objects at their old locations, before they move for obj in objects: obj.clear() # handle keys and exit game if needed player_action = handle_keys() if game_state == 'exit': # save_game() quit_game() # let monsters take their turn if game_state == 'combat': for object in objects: if object.in_combat: # combat() pass
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 play_game(): global key, mouse player_action = None while not libtcod.console_is_window_closed(): #render the screen libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE, key, mouse) render_all() libtcod.console_flush() #level up if needed check_level_up() #erase all objects at their old locations before they move for object in objects: object.clear() #handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break #let monsters take their turn if game_state == 'playing': for object in objects: if object.ai: if object.wait > 0: #don't take a turn if still waiting object.wait -= 1 else: object.ai.take_turn()
def menu(header, options, width): if len(options) > 26: raise ValueError("Cannot have a menu with more than 26 options.") #TODO: expand inventory. header_height = libtcod.console_get_height_rect(con, 0, 0, width, SCREEN_HEIGHT, header) 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") #can be replaced with a list i'll iterate over when i want more positions for option_text in options: text = "({0}) {1}".format(chr(letter_index), option_text) libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 #center and show menu 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) index = key.c - ord("a") if index >= 0 and index < len(options): return index else: return None
def draw_main_menu(con, has_file=False): tcod.console_set_default_foreground(con, COL_A) img = tcod.image_load('small.png') tcod.image_set_key_color(img, tcod.red) tcod.image_blit(img, 0, 45, 30, tcod.BKGND_LIGHTEN, .5, .25, 0) xx=-20 yy=15 can_cont = "" can_del = '' if has_file: can_cont = '-- (c)ontinue' can_del = '-- (D)elete' options=( """ GAME TITLE """+chr(tcod.CHAR_BLOCK2)+chr(tcod.CHAR_BLOCK1)+chr(tcod.CHAR_BLOCK1)+""" | | \t-- (n)ew game | \t--\t%s | | | \t%s | \t-- (esc)cape """ % (can_cont, can_del) ) tcod.console_print_ex(con, game.GAME_WIDTH/4+xx, game.GAME_HEIGHT/3+yy, tcod.BKGND_LIGHTEN, tcod.LEFT,options) tcod.console_print(con, 2, game.GAME_HEIGHT-2, 'oyyooyoyoyoyyooyoyoy') tcod.console_flush() tcod.console_clear(con)
def play_game(): settings.player_action = None settings.mouse = libtcod.Mouse() settings.key = libtcod.Key() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, settings.key, settings.mouse) render_all() libtcod.console_flush() check_level_up() for object in settings.objects: object.clear() settings.player_action = handle_keys() if settings.player_action == 'exit': save_game() break if settings.game_state == 'playing' and \ settings.player_action != 'didnt-take-turn': for object in settings.objects: if object.ai: object.ai.take_turn()
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 get_key(self): self.is_visible = True r = None while 1: self.draw() libtcod.console_flush() k = libtcod.console_wait_for_keypress(True) if k and k.pressed and k.c: c = chr(k.c) if c in [i.hotkey for i in self.__items]: r = c break elif c == 'j': self.sel_prev() elif c == 'k': self.sel_next() elif c == ' ': if self.sel_index() != 0: r = self.__items[self.sel_index()].hotkey break self.is_visible = False # TODO: player.redraw_screen() return r
def storyScreen(console): libtcod.console_set_default_background(console, STORY_BACKGROUND_COLOUR1) libtcod.console_clear(console) done = False counter = 0 blinkOn = True blinkSpeed = 10 while not done and not libtcod.console_is_window_closed(): key = libtcod.console_check_for_keypress(True) if not key.vk == libtcod.KEY_NONE: done = True #print the story message libtcod.console_set_default_foreground(console, STORY_FOREGROUND_COLOUR1) libtcod.console_print_rect(console, 1, 3, SCREEN_WIDTH, SCREEN_HEIGHT, STORY_TEXT1) if(blinkOn): libtcod.console_set_default_foreground(console, SPLASH_FOREGROUND_COLOUR3) libtcod.console_print_rect(console, 16, 22, SCREEN_WIDTH, SCREEN_HEIGHT, "press any key") # blit the panel to the screen libtcod.console_blit(console, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-(2*1), 0, 0, 1) libtcod.console_flush() counter += 1 if counter >= blinkSpeed: counter = 0 blinkOn = not blinkOn libtcod.console_clear(console) libtcod.console_clear(console)
def play_game(): player_action = None # Main loop while not libtcod.console_is_window_closed(): # draw render_all() # flush data to screen libtcod.console_flush() # clear all objects for object in objects: object.clear() # handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break # let monsters take their turn if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn()
def 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 autowrap and one line per option header_height = libtcod.console_get_height_rect(con, 0, 0, width, SCREEN_HEIGHT, header) height = len(options) + header_height #create another offscreen console for the menu's window window = libtcod.console_new(width, height) #print the header, with autowrap 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') #start the list of inventory items with ordinal letter a for option_text in options: text = '(' + chr(letter_index) + ') ' + option_text #converts ordinal to a string for selection libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text) y += 1 letter_index += 1 #blit the contents of the inventory window to the root console in the middle of the screen 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) #last two values transparency% #present to the root console to the player and wait for key-press libtcod.console_flush() key = libtcod.console_wait_for_keypress(True)
def splashScreen(console): libtcod.console_set_default_background(console, SPLASH_BACKGROUND_COLOUR) libtcod.console_clear(console) done = False counter = 0 blinkOn = True blinkSpeed = 10 while not done and not libtcod.console_is_window_closed(): key = libtcod.console_check_for_keypress(True) if not key.vk == libtcod.KEY_NONE: done = True #print the splash messages libtcod.console_set_default_foreground(console, SPLASH_FOREGROUND_COLOUR1) libtcod.console_print_rect(console, 4, 5, SCREEN_WIDTH, SCREEN_HEIGHT, "SWORD SHOP") libtcod.console_set_default_foreground(console, SPLASH_FOREGROUND_COLOUR2) libtcod.console_print_rect(console, 4, 8, SCREEN_WIDTH, SCREEN_HEIGHT, "by luke david\n fitzpatrick") if(blinkOn): libtcod.console_set_default_foreground(console, SPLASH_FOREGROUND_COLOUR3) libtcod.console_print_rect(console, 16, 13, SCREEN_WIDTH, SCREEN_HEIGHT, "press any key") # blit the panel to the screen libtcod.console_blit(console, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-(2*6), 0, 0, 6) libtcod.console_flush() counter += 1 if counter >= blinkSpeed: counter = 0 blinkOn = not blinkOn libtcod.console_clear(console)
def new_game(): global player, inventory, game_msgs, game_state, dungeon_level, steps, hunger_msg, ice_counter global msg_index, camera msg_index = 0 name = 'Player' inventory = [] game_msgs = [] libtcod.console_flush() player = Player(0, 0, '@', name, libtcod.white, blocks=True, fighter=None) player.spec = 'Swordsman' player.level = 1 player.inv = inventory hunger_msg = False steps = 0 ice_counter = None dungeon_level = 1 camera = Camera(0, 0) make_map("I would like to fly a plane one day. The wind in my hair gives me hope. When the sun sets over the clouds, I know that everything will be okay.") initialize_fov() game_state = 'playing'
def new_game(): global player, inventory, game_msgs, game_state, dungeon_level, steps, hunger_msg, ice_counter global msg_index, camera msg_index = 0 name = 'Player' inventory = [] game_msgs = [] libtcod.console_flush() player = Player(0, 0, '@', name, libtcod.white, blocks=True, fighter=None) player.spec = 'Swordsman' player.level = 1 player.inv = inventory hunger_msg = False steps = 0 ice_counter = None dungeon_level = 1 camera = Camera(0, 0) while not make_map("Nine-tenths of tactics are certain, and taught in books: but the irrational tenth is like the kingfisher flashing across the pool, and that is the test of generals. Nine-tenths of tactics are certain, and taught in books: but the irrational tenth is like the kingfisher flashing across the pool, and that is the test of generals. flashing across the pool, and that is the test of generals. generals."): pass print len("Nine-tenths of tactics are certain, and taught in books: but the irrational tenth is like the kingfisher flashing across the pool, and that is the test of generals. Nine-tenths of tactics are certain, and taught in books: but the irrational tenth is like the kingfisher flashing across the pool, and that is the test of generals. flashing across the pool, and that is the test of generals. generals.") initialize_fov() game_state = 'playing'
def play_game(): global fov_recompute player_action = None while not libtcod.console_is_window_closed(): # render the screen render_all() libtcod.console_flush() # level up if needed check_level_up() # erase all objects at their old locations, before they move for object in objects: object.clear() # handle keys and exit game if needed player_action = handle_keys() if player_action == 'exit': save_game() break # let monsters take their turn if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn() generate_mana(5) fov_recompute = True
def city_menu(): width, height = R.MAP_VIEW_WIDTH - 4, R.MAP_VIEW_HEIGHT - 4 city_select_pop = libtcod.console_new(width, height) selected_city = None limit = len(cities) - 1 pos_x = R.MAP_VIEW_WIDTH / 2 - width / 2 pos_y = R.MAP_VIEW_HEIGHT / 2 - height / 2 for a in range(R.MAP_VIEW_WIDTH - 4): #clear screen, colour dark grey, every cycle for b in range(R.MAP_VIEW_HEIGHT - 4): #libtcod.console_print_rect(window, a, b, libtcod.console_print_rect_ex(city_select_pop, a, b, R.MAP_VIEW_WIDTH - 4, R.MAP_VIEW_HEIGHT - 4, libtcod.BKGND_NONE, libtcod.LEFT, " ") libtcod.console_blit(city_select_pop, 0, 0, width, height, 0, pos_x, pos_y, 1.0, 0.9) libtcod.console_flush() offset = 0 key = libtcod.console_check_for_keypress() while selected_city == None: #or key.vk != libtcod.KEY_ENTER: libtcod.console_clear(city_select_pop) libtcod.console_set_default_foreground(city_select_pop, libtcod.yellow) libtcod.console_print_ex(city_select_pop, 1, 1, libtcod.BKGND_NONE, libtcod.LEFT, "Select the city") libtcod.console_set_default_foreground(city_select_pop, libtcod.light_yellow) #city_length = len(cities) for lines in range(min(len(cities), 10)): # picks the smaller of the two. libtcod.console_print_ex( city_select_pop, 2, 3 + lines, libtcod.BKGND_NONE, libtcod.LEFT, chr(48 + lines) + ": " + cities[lines + offset].name) # libtcod.console_blit(city_select_pop, 0, 0, width, height, 0, pos_x, pos_y, 1.0, 0.9) libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) max_key = 48 + min( len(cities) - 1, 10) # and again, picks the smaller f the two values. #to prevent it trying to be longer than amount of cities if key.c == 122: #z offset -= 1 if offset < 0: offset = 0 elif key.c == 120: #x offset += 1 if 9 + offset > limit: offset = limit - 10 elif key.c == 48: # 0 selected_city = cities[0 + offset] elif key.c == 49: # 1 if max_key >= 49: selected_city = cities[1 + offset] #I want to interact with the item in the '1' slot in the interface elif key.c == 50: # 2 if max_key >= 50: selected_city = cities[2 + offset] elif key.c == 51: #3 if max_key >= 51: selected_city = cities[3 + offset] elif key.c == 52: #4 if max_key >= 52: selected_city = cities[4 + offset] elif key.c == 53: #5 if max_key >= 53: selected_city = cities[5 + offset] elif key.c == 54: #6 if max_key >= 54: selected_city = cities[6 + offset] elif key.c == 55: #7 if max_key >= 55: selected_city = cities[7 + offset] elif key.c == 56: #8 if max_key >= 56: selected_city = cities[8 + offset] elif key.c == 57: #9 if max_key >= 57: selected_city = cities[9 + offset] elif key.vk == libtcod.KEY_ENTER or key.vk == libtcod.KEY_BACKSPACE: break else: pass #selected_city = None libtcod.console_blit(city_select_pop, 0, 0, width, height, 0, pos_x, pos_y, 1.0, 0.9) libtcod.console_flush() for a in range(R.MAP_WIDTH - 4): #clear screen, colour dark grey, every cycle for b in range(R.MAP_HEIGHT - 4): #libtcod.console_print_rect(window, a, b, libtcod.console_print_rect_ex(city_select_pop, a, b, R.MAP_VIEW_WIDTH - 4, R.MAP_VIEW_HEIGHT - 4, libtcod.BKGND_NONE, libtcod.LEFT, " ") if selected_city != None: key = libtcod.console_check_for_keypress() while not key.vk == libtcod.KEY_ENTER or key.vk == libtcod.KEY_BACKSPACE: current_offset = offset for a in range(R.MAP_WIDTH - 4): #clear screen, colour dark grey, every cycle for b in range(R.MAP_HEIGHT - 4): #libtcod.console_print_rect(window, a, b, libtcod.console_put_char(city_select_pop, a, b, ' ', libtcod.BKGND_NONE) #print the header with auto-wrap libtcod.console_set_default_foreground(city_select_pop, libtcod.white) libtcod.console_print_rect_ex(city_select_pop, 0, 0, width, height, libtcod.BKGND_NONE, libtcod.LEFT, selected_city.name + " stats!") libtcod.console_print_ex(city_select_pop, 2, 5, libtcod.BKGND_NONE, libtcod.LEFT, "-----------------") libtcod.console_print_ex(city_select_pop, 3, 6, libtcod.BKGND_NONE, libtcod.LEFT, "produces:-") y = 8 for resource in selected_city.producing: if selected_city.producing[resource][1] > 0: libtcod.console_print_ex(city_select_pop, 4, y, libtcod.BKGND_NONE, libtcod.LEFT, resource) libtcod.console_print_ex( city_select_pop, 13, y, libtcod.BKGND_NONE, libtcod.LEFT, str(selected_city.producing[resource][1])) y += 1 libtcod.console_print_ex(city_select_pop, 2, y, libtcod.BKGND_NONE, libtcod.LEFT, "\n") y += 1 libtcod.console_print_ex(city_select_pop, 3, y, libtcod.BKGND_NONE, libtcod.LEFT, "desires:-") y += 2 for resource in selected_city.desired: desire = selected_city.desired[resource] libtcod.console_print_ex(city_select_pop, 4, y, libtcod.BKGND_NONE, libtcod.LEFT, resource) libtcod.console_print_ex(city_select_pop, 13, y, libtcod.BKGND_NONE, libtcod.LEFT, str(desire)) y += 1 libtcod.console_print_ex(city_select_pop, 2, y, libtcod.BKGND_NONE, libtcod.LEFT, "-----------------") for resource in selected_city.trade_house.supply_demand: supply_demand = selected_city.trade_house.supply_demand[ resource] libtcod.console_print_ex(city_select_pop, 30, y, libtcod.BKGND_NONE, libtcod.LEFT, resource) libtcod.console_print_ex(city_select_pop, 40, y, libtcod.BKGND_NONE, libtcod.LEFT, str(supply_demand[0])) libtcod.console_print_ex(city_select_pop, 47, y, libtcod.BKGND_NONE, libtcod.LEFT, ", " + str(supply_demand[1])) libtcod.console_print_ex(city_select_pop, 54, y, libtcod.BKGND_NONE, libtcod.LEFT, ", " + str(supply_demand[2])) #libtcod.console_print_ex(window, 30, y, libtcod.BKGND_NONE, libtcod.LEFT, str(resource.quantity)) #libtcod.console_print_ex(window, 30, y, libtcod.BKGND_NONE, libtcod.LEFT, str(resource.quantity)) y += 1 libtcod.console_print_ex(city_select_pop, 2, y, libtcod.BKGND_NONE, libtcod.LEFT, "-----------------") libtcod.console_blit(city_select_pop, 0, 0, width, height, 0, pos_x, pos_y, 1.0, 0.9) libtcod.console_flush() key = libtcod.console_wait_for_keypress(True) libtcod.console_blit(city_select_pop, 0, 0, width, height, 0, pos_x, pos_y, 1.0, 0.9) libtcod.console_flush()
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
xp_loader.transparent_cell_back_g, xp_loader.transparent_cell_back_b)) #################### # libtcod piping to actually put the console layers on screen. This will probably change quite a bit for your actual usage of libtcod #################### draw_layers = False while not libtcod.console_is_window_closed(): key = libtcod.console_check_for_keypress() if key.vk == libtcod.KEY_ESCAPE: break #exit game if key.c == ord('a'): draw_layers = not draw_layers libtcod.console_clear(0) libtcod.console_blit(layer_0_console, 0, 0, xp_data['layer_data'][0]['width'], xp_data['layer_data'][0]['height'], 0, 0, 0) if draw_layers: libtcod.console_blit(layer_1_console, 0, 0, xp_data['layer_data'][1]['width'], xp_data['layer_data'][1]['height'], 0, 0, 0) libtcod.console_flush() libtcod.console_delete(layer_0_console) libtcod.console_delete(layer_1_console)
def main(): constants = get_constants() libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(constants['screen_width'], constants['screen_height'], constants['window_title'], False) con = libtcod.console_new(constants['screen_width'], constants['screen_height']) panel = libtcod.console_new(constants['screen_width'], constants['panel_height']) player = None entities = [] game_map = None message_log = None game_state = None show_main_menu = True show_load_error_message = False main_menu_background_image = libtcod.image_load('menu_background.png') key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, constants['screen_width'], constants['screen_height']) if show_load_error_message: message_box(con, 'No save game to load', 50, constants['screen_width'], constants['screen_height']) libtcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: player, entities, game_map, message_log, game_state = get_game_variables( constants) game_state = GameStates.PLAYERS_TURN show_main_menu = False elif load_saved_game: try: player, entities, game_map, message_log, game_state = load_game( ) show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: libtcod.console_clear(con) play_game(player, entities, game_map, message_log, game_state, con, panel, constants) show_main_menu = True
def main(userID): global changeLevel global PlayerID PlayerID = userID global player PlayerName = sqlcon.sqlQuery("SELECT Name FROM User WHERE ID=%s" % PlayerID)[0][0] # playerstats all the values ID(Primary Key) and User_ID(Fotrign Key) are useless for now ID, MaxHP, CurrentHP, PositionX, PositionY, Attack, Defence, User_ID = sqlcon.getPlayersStats( PlayerID)[0] player = Actors.Player(PlayerName, MaxHP, CurrentHP, Attack, Defence, 0, PositionY, PositionX, '@') global exity, exitx global playerScore playerScore = getScore(PlayerID)[0][0] if playerScore == None: playerScore = 0 global smap smap = [] smap = sqlcon.getMapDataForID(PlayerID) global LevelID LevelID = sqlcon.getLevelIDforUserID(PlayerID)[0][0] changeLevel(LevelID) global moveTimer moveTimer = 0 libtcod.console_set_default_foreground(0, libtcod.lighter_grey) for Object in objects: Object.draw() while not libtcod.console_is_window_closed(): libtcod.console_set_default_foreground(0, libtcod.white) libtcod.console_print(0, 1, 23, " ") libtcod.console_print(0, 1, 23, "HP: %s/%s" % (player.Hp, player.HPMax)) if player.Hp <= 0: gameOver() break libtcod.console_print(0, exitx, exity, ">") player.draw() libtcod.console_flush() # draws(flushes) the buffer player.clear() for Enemy in enemies: Enemy.clear() # handle keys and exit game if needed exit = handleKeys() if levelChange: continue moveEnemies() libtcod.console_set_default_foreground(0, libtcod.green) for Enemy in enemies: Enemy.draw() moveTimer += 1 if exit: break sqlcon.endConnection()
def handleCollisionWithObjects(playerx, playery): global target, playerScore Loot = None libtcod.console_print(0, 12, 22, " ") libtcod.console_flush() if isBlocked(playerx, playery): #if try fails means it is not an enemy so ignore try: enDamage = player.Attack - target.Defence if enDamage < 1: enDamage = 1 Loot = target.LoseHealth(enDamage) # TODO make the damage more based on the difficulty: * difficulty <-- (do this) or make the enemies stats better*** damage = target.Attack - player.Defence # this is to make sure the player takes at least 1 damage and doesn't heal from enemie blows if damage < 1: damage = 1 player.Hp -= damage if target.Hp > 0: libtcod.console_print(0, 12, 22, "TargetHP: %s" % target.Hp) libtcod.console_flush() except: pass else: player.move(playerx, playery) # for all the coins check if player is on top if True then increase score for i in coins: if playerx == i[0] and playery == i[1]: #remove the coin so player won't be able to get the same coin coins.remove(i) playerScore += random.randint(1, 5) #clear the instructions and redraw the score there libtcod.console_print(0, 1, 24, " ") libtcod.console_print(0, 1, 24, "Score: %s" % playerScore) for i in potions: #i[0] = x , i[1] = y , i[2] = type if playerx == i[0] and playery == i[1]: if i[2] == "Health": player.Hp += random.randint(2, 5) #don't make the current health more than the max health points if player.Hp > player.HPMax: player.Hp = player.HPMax elif i[2] == "Attack": player.Attack += random.randint(1, 2) elif i[2] == "Defence": player.Defence += random.randint(1, 2) #remove the potion so player won't be able to get the same coin potions.remove(i) drawStats() if Loot != None: #if try fails means it is not an enemy so ignore try: enemies.remove(target) # Loot[0] = x , Loot[1] = y makeLoot(Loot[0], Loot[1]) except: pass
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 color_table = { "dark_wall": libtcod.Color(0, 0, 100), "dark_ground": libtcod.Color(50, 50, 150) } player_x = screen_width // 2 player_y = screen_height // 2 player = Entity(player_x, player_y, char="@", color=(255, 255, 255)) npc = Entity(player_x - 5, player_y - 5, char="@", color = libtcod.yellow) entity_lst = [player, npc] libtcod.console_set_custom_font("arial10x10.png", libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, "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, entity_lst, game_map, screen_width, screen_height, color_table) libtcod.console_flush() clear_all(con, entity_lst) # key = libtcod.console_check_for_keypress() action = handle_key(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(*move) # if key.vk == libtcod.KEY_ESCAPE: if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): screen_w = 80 screen_h = 50 map_w = 80 map_h = 45 room_max_size = 10 room_min_size = 5 max_rooms = 35 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150) } player = Entity(int(screen_w / 2), int(screen_h / 2), '@', libtcod.white) npc = Entity(int(screen_w / 2 - 5), int(screen_h / 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_w, screen_h, 'The Lantern', False) con = libtcod.console_new(screen_w, screen_h) game_map = GameMap(map_w, map_h, circum, radius) game_map.make_map(max_rooms, room_min_size, room_max_size, map_w, map_h, circum, radius, 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_w, screen_h, 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 target_tile(max_range=None, radius=0): """ | Target a distant tile | For Ranged Attacks, like Archery, Thrown | Also Fireballs or similar projectiles with Radius """ from components import Object from mapcreation import Circle from render import render_all # Spawn a Target Object that can be moved with arrow Keys (x, y) = (gvar.game.player.x, gvar.game.player.y) target = Object(x, y, 'X', color=libtcod.red, name='target', blocks=False) gvar.game.objects.append(target) while True: target.send_to_front() render_all() #Render Splash libtcod.console_clear(gvar.overlay) if radius > 0: target.splash = Circle(target.x, target.y, radius) for point in target.splash.circle: libtcod.console_set_char_background(gvar.overlay, point[0], point[1], libtcod.yellow) libtcod.console_blit(gvar.overlay, 0, 0, gvar.SCREEN_WIDTH, gvar.SCREEN_HEIGHT, 0, 0, 0, 1.0, 0.5) libtcod.console_flush() #Move the Target around key = libtcod.Key() mouse = libtcod.Mouse() key_pressed = libtcod.sys_wait_for_event(libtcod.EVENT_KEY_PRESS, key, mouse, True) if not key_pressed: return 'cancelled' if key.vk == libtcod.KEY_UP or key.vk == libtcod.KEY_KP8: if libtcod.map_is_in_fov(gvar.fov_map, target.x, target.y - 1): target.y -= 1 elif key.vk == libtcod.KEY_DOWN or key.vk == libtcod.KEY_KP2: if libtcod.map_is_in_fov(gvar.fov_map, target.x, target.y + 1): target.y += 1 elif key.vk == libtcod.KEY_LEFT or key.vk == libtcod.KEY_KP4: if libtcod.map_is_in_fov(gvar.fov_map, target.x - 1, target.y): target.x -= 1 elif key.vk == libtcod.KEY_RIGHT or key.vk == libtcod.KEY_KP6: if libtcod.map_is_in_fov(gvar.fov_map, target.x + 1, target.y): target.x += 1 elif key.vk == libtcod.KEY_KP7: if libtcod.map_is_in_fov(gvar.fov_map, target.x - 1, target.y - 1): target.x -= 1 target.y -= 1 elif key.vk == libtcod.KEY_KP9: if libtcod.map_is_in_fov(gvar.fov_map, target.x + 1, target.y - 1): target.x += 1 target.y -= 1 elif key.vk == libtcod.KEY_KP3: if libtcod.map_is_in_fov(gvar.fov_map, target.x + 1, target.y + 1): target.x += 1 target.y += 1 elif key.vk == libtcod.KEY_KP1: if libtcod.map_is_in_fov(gvar.fov_map, target.x - 1, target.y + 1): target.x -= 1 target.y += 1 elif key.vk == libtcod.KEY_ENTER: gvar.game.objects.remove(target) return target break elif key.vk == libtcod.KEY_ESCAPE: gvar.game.objects.remove(target) return 'cancelled' break elif chr(key.c) == 's': # Returns String 'closest' for further evaluation by the calling function, e.g. for targeting the closest mob gvar.game.objects.remove(target) return 'closest' break
def render_all(): global cam_x, cam_y #clear the city locations using OLD cam position. for city in R.cities: loc = R.tiles[city.x][city.y] colour = loc.bg libtcod.console_set_char_background(con, cam_x + city.x, cam_y + city.y, colour, libtcod.BKGND_SET) libtcod.console_set_char(con, cam_x + city.x, cam_y + city.y, ord(' ')) cam_x = scrolling_map(player.x, R.MAP_VIEW_WIDTH / 2, R.MAP_VIEW_WIDTH, R.MAP_WIDTH) cam_y = scrolling_map(player.y, R.MAP_VIEW_HEIGHT / 2, R.MAP_VIEW_HEIGHT, R.MAP_HEIGHT) #now draw the map! for y in range(min(R.MAP_VIEW_HEIGHT, len( R.world.tiles[0]))): #this refers to the SCREEN position. NOT map. for x in range(min(R.MAP_VIEW_WIDTH, len(R.world.tiles))): map_pos_x = x + cam_x map_pos_y = y + cam_y if map_pos_x >= R.MAP_WIDTH: map_pos_x = R.MAP_WIDTH - 1 if map_pos_y >= R.MAP_HEIGHT: map_pos_y = R.MAP_HEIGHT - 1 tile = R.world.tiles[map_pos_x][map_pos_y] #=============================================================== # try: # tile = map[map_pos_x][map_pos_y] # except: # print str(map_pos_x) + " or " + str(map_pos_y) + " is out of bounds." # break #=============================================================== #visible = libtcod.map_is_in_fov(fov_map, tile.x, tile.y) visible = True #wall = tile.block_sight if not visible: pass #TODO: re-do the visible/ not visible code. #if it"s not visible right now, the player can only see it if it"s explored #if tile.explored: #if wall: # libtcod.console_set_char_background(con, x, y, color_dark_wall, libtcod.BKGND_SET) # libtcod.console_set_char(con, x, y, " ") #else: # libtcod.console_set_char_background(con, x, y, color_dark_ground, libtcod.BKGND_SET) # libtcod.console_set_char(con, x, y, " ") else: #it"s visible if tile.POI is None: if traffic: # for b&w image. v = world.get_foot_traffic(map_pos_x, map_pos_y) colour = libtcod.Color(v, v, v) libtcod.console_set_char_background( con, x, y, colour, libtcod.BKGND_SET) libtcod.console_set_char(con, x, y, " ") elif temperature: # for b&w image. v = world.get_temperature(map_pos_x, map_pos_y) v = int(v) colour = libtcod.Color(v, v, v) libtcod.console_set_char_background( con, x, y, colour, libtcod.BKGND_SET) libtcod.console_set_char(con, x, y, " ") else: colour = tile.bg libtcod.console_set_char(con, x, y, " ") libtcod.console_set_char_background( con, x, y, colour, libtcod.BKGND_SET) #libtcod.console_set_char_foreground(con, x, y, libtcod.black) #libtcod.console_set_char(con, x, y, libtcod.CHAR_BULLET) else: libtcod.console_set_char_background( con, x, y, tile.POI.colour, libtcod.BKGND_SET) libtcod.console_set_char_foreground( con, x, y, libtcod.white) libtcod.console_set_char(con, x, y, tile.POI.char) #since it"s visible, explore it tile.explored = True #now draw the mini map for cell_x in range(len(world.mini_map)): for cell_y in range(len(world.mini_map[cell_x])): colour = world.mini_map[cell_x][cell_y].bg libtcod.console_set_char_background(minmap, cell_x, cell_y, colour, libtcod.BKGND_SET) #libtcod.console_set_char_foreground(con, x, y, libtcod.white) # for char in R.world_obj: # if char != player: # char.draw(cam_x, cam_y) #now draw all the merchants for city in cities: for merchant in city.trade_house.caravans_out: merchant.draw(cam_x, cam_y) for objects in R.world_obj: if objects.ai: objects.clear(cam_x, cam_y) objects.draw(cam_x, cam_y) player.draw(cam_x, cam_y) libtcod.console_clear(message_bar) libtcod.console_set_default_foreground(message_bar, libtcod.white) libtcod.console_print_ex( message_bar, 0, 0, libtcod.BKGND_NONE, libtcod.LEFT, str(date[0]) + " " + str(date[1][2]) + " " + str(date[1][0]) + " " + str(date[2][0])) # print the messages, one line at a time. y = 2 for (line, colour) in R.game_msgs: libtcod.console_set_default_foreground(message_bar, colour) libtcod.console_print_ex(message_bar, R.MSG_X, R.MSG_HEIGHT - y, libtcod.BKGND_NONE, libtcod.LEFT, line) y += 1 # y = 0 # for y in range(R.MAP_HEIGHT): # for x in range(R.MAP_WIDTH): # libtcod.console_set_char_background(con, x, y, map_[x][y].bg, libtcod.BKGND_SET) #libtcod.console_print_ex(message_bar, R.SCREEN_WIDTH - R.INFO_BAR_WIDTH, 0, libtcod.BKGND_NONE, libtcod.LEFT, get_names_under_mouse()) libtcod.console_set_default_background(con, libtcod.white) libtcod.console_blit(con, 0, 0, R.MAP_VIEW_WIDTH, R.MAP_VIEW_HEIGHT, 0, 0, 0) #libtcod.console_blit(con, mini_map_x, mini_map_y, mini_map_x+ mini_map_width, mini_map_y +mini_map_height, 0, 0, 0) libtcod.console_blit(con_char, 0, 0, R.MAP_VIEW_WIDTH, R.MAP_VIEW_HEIGHT, 0, 0, 0, 1.0, 0.0) libtcod.console_blit(inf, 0, 0, R.INFO_BAR_WIDTH, R.SCREEN_HEIGHT, 0, R.MAP_VIEW_WIDTH, 0) libtcod.console_blit(minmap, 0, 0, R.INFO_BAR_WIDTH, R.PANEL_HEIGHT, 0, R.MAP_VIEW_WIDTH, R.PANEL_Y) libtcod.console_blit(message_bar, 0, 0, R.PANEL_WIDTH, R.PANEL_HEIGHT, 0, 0, R.PANEL_Y) libtcod.console_flush()
def main(): # Screen settings screen_width = 80 screen_height = 45 # Map creation settings map_width = 80 map_height = 45 # Room creation settings room_max_size = 10 room_min_size = 6 max_rooms = 30 # FOV settings - passed to libtcod library fov_algorithm = 0 fov_light_walls = True fov_radius = 10 # Color Dictionary for entities 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) } # Create player entity and entities list - monsters appended at map creation max_monsters_per_room = 3 player = Entity(0, 0, '@', libtcod.white, 'my dude', blocks=True) entities = [player] # Console settings and initialisation libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GRAYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False) # Set up the console con = libtcod.console_new(screen_width, screen_height) # Create the map object and trigger dungeon creation 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) # Controller mappings key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN # Main Loop 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) # TODO - wouldn't it make more sense to move this under recompute_fov() call? fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: print('You kick the ' + target.name + ' squarely in the nards, much to its dismay') 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 + ' scratches itself in an unpleasant fashion.') game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() if not game_state == GameStates.PLAYER_DEAD: game_state = GameStates.PLAYERS_TURN begin_player_turn = True previous_game_state = game_state targeting_item = None if not game_state == GameStates.PLAYER_DEAD: PLAYERDEADSTATE = False else: PLAYERDEADSTATE = True while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: if game_map.dungeon_level != 0: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) else: recompute_fov(fov_map, player.x, player.y, 100, 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'], constants['kill_count'], game_state, constants['wall_tile'], constants['floor_tile'], constants['grass_tile']) 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') drop_equipment = action.get('drop_equipment') show_equipment_inventory = action.get('show_equipment_inventory') show_bag = action.get('show_bag') inventory_index = action.get('inventory_index') equipment_inventory_index = action.get('equipment_inventory_index') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') show_help_menu = action.get('show_help_menu') exit = action.get('exit') exit_quit_menu = action.get('exit_quit_menu') fullscreen = action.get('fullscreen') cast_magic_wand = action.get('cast_magic_wand') shoot_bow = action.get('shoot_bow') drop_menu = action.get('drop_menu') sell_menu = action.get('sell_menu') sell_equipment_menu = action.get('sell_equipment_menu') buy_menu = action.get('buy_menu') buy_equipment_menu = action.get('buy_equipment_menu') shop_menu = action.get('shop_menu') shop_menu_index = action.get('shop_menu_index') shop_equipment_menu_index = action.get('shop_equipment_menu_index') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] if begin_player_turn and game_state == GameStates.PLAYERS_TURN: begin_player_turn = False if player.fighter.status: player_turn_results.extend(player.fighter.status.update()) if move and game_state == GameStates.PLAYERS_TURN: if player.fighter.status: if player.fighter.status.name == "Frozen": dx = 0 dy = 0 destination_x = player.x + dx destination_y = player.y + dy elif player.fighter.status.name == "Haste": dx, dy = move dx *= 2 dy *= 2 destination_x = player.x + dx destination_y = player.y + dy else: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy else: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): if player.fighter.status: if player.fighter.status.name == "Frozen": target = None else: target = get_blocking_entities_at_location( entities, destination_x, destination_y) else: target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target, constants, entities=entities) #playsound('sounds/attack.mp3', block=False) 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 ( not entity.equippable ) and entity.x == player.x and entity.y == player.y: pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) break elif entity.item and entity.x == player.x and entity.y == player.y: pickup_results = player.equipment_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 show_equipment_inventory: previous_game_state = game_state game_state = GameStates.SHOW_EQUIPMENT_INVENTORY if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if drop_equipment: previous_game_state = game_state game_state = GameStates.DROP_EQUIPMENT if show_bag: previous_game_state = game_state game_state = GameStates.SHOW_BAG if drop_menu: previous_game_state = game_state game_state = GameStates.DROP_MENU 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)) elif game_state == GameStates.SELL_MENU: player_turn_results.extend( player.inventory.sell(item, game_state)) if equipment_inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and equipment_inventory_index < len( player.equipment_inventory.items): equip_item = player.equipment_inventory.items[ equipment_inventory_index] if game_state == GameStates.SHOW_EQUIPMENT_INVENTORY: player_turn_results.extend( player.equipment_inventory.use(equip_item)) elif game_state == GameStates.DROP_EQUIPMENT: player_turn_results.extend( player.equipment_inventory.drop_item(equip_item)) elif game_state == GameStates.SELL_EQUIPMENT_MENU: player_turn_results.extend( player.equipment_inventory.sell(equip_item, game_state)) if shop_menu_index is not None and previous_game_state != GameStates.PLAYER_DEAD: item = game_map.shop_items[shop_menu_index] if game_state == GameStates.BUY_MENU: player_turn_results.extend( player.inventory.buy(item, game_state)) if shop_equipment_menu_index is not None and previous_game_state != GameStates.PLAYER_DEAD: item = game_map.shop_equipment_items[shop_equipment_menu_index] if game_state == GameStates.BUY_EQUIPMENT_MENU: player_turn_results.extend( player.equipment_inventory.buy(item, game_state)) if take_stairs and game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.name == "Up Stairs" and entity.x == player.x and entity.y == player.y: entities = game_map.go_to_village(player, message_log, constants) fov_map = initialize_fov(game_map) fov_recompute = True libtcod.console_clear(con) break elif 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 cast_magic_wand and game_state == GameStates.PLAYERS_TURN: wand = player.inventory.search("Magic Wand") staff = player.inventory.search("Wizard Staff") if wand is None and staff is None: message_log.add_message( Message("You cannot cast magic without a magic item!", libtcod.orange)) else: if player.fighter.status: if player.fighter.status.name == "Frozen": game_state = GameStates.ENEMY_TURN else: player_turn_results.extend( player.inventory.use(wand, entities=entities, fov_map=fov_map)) else: player_turn_results.extend( player.inventory.use(wand, entities=entities, fov_map=fov_map)) game_state = GameStates.ENEMY_TURN if shoot_bow and game_state == GameStates.PLAYERS_TURN: bow = player.inventory.search("Long Bow") arrow = player.inventory.search("Arrow") fire_arrow = player.inventory.search("Fire Arrow") if bow is None and arrow is None and fire_arrow is None: message_log.add_message( Message( "You don't have anything to shoot with at this time!", libtcod.orange)) elif bow is None and (arrow is not None or fire_arrow is not None): message_log.add_message( Message("You cannot shoot an arrow without a bow!", libtcod.orange)) elif bow is not None and (arrow is None and fire_arrow is None): message_log.add_message( Message("You need arrows to use your bow", libtcod.orange)) else: if player.fighter.status: if player.fighter.status.name == "Frozen": game_state = GameStates.ENEMY_TURN else: player_turn_results.extend( player.inventory.use(bow, entities=entities, fov_map=fov_map)) else: player_turn_results.extend( player.inventory.use(bow, entities=entities, fov_map=fov_map)) game_state = GameStates.ENEMY_TURN if level_up: if level_up == 'hp': player.fighter.base_max_hp += 20 player.fighter.hp += 20 message_log.add_message( Message("You leveled up your HP!", libtcod.light_cyan)) elif level_up == 'str': player.fighter.base_power += 1 message_log.add_message( Message("You leveled up your ATTACK!", libtcod.light_cyan)) elif level_up == 'def': player.fighter.base_defense += 1 message_log.add_message( Message("You leveled up your DEFENSE!", libtcod.light_cyan)) elif level_up == 'mgk': player.fighter.base_magic += 1 message_log.add_message( Message("You leveled up your MAGIC!", libtcod.light_cyan)) elif level_up == 'mgk_def': player.fighter.base_magic_defense += 1 message_log.add_message( Message("You leveled up your MAGIC RESISTANCE!", libtcod.light_cyan)) game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if show_help_menu: previous_game_state = game_state game_state = GameStates.HELP_MENU if sell_menu: previous_game_state = game_state game_state = GameStates.SELL_MENU if sell_equipment_menu: previous_game_state = game_state game_state = GameStates.SELL_EQUIPMENT_MENU if buy_menu: previous_game_state = game_state game_state = GameStates.BUY_MENU if buy_equipment_menu: previous_game_state = game_state game_state = GameStates.BUY_EQUIPMENT_MENU if shop_menu: previous_game_state = game_state game_state = GameStates.SHOP_MENU 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.DROP_EQUIPMENT, GameStates.CHARACTER_SCREEN, GameStates.HELP_MENU, GameStates.SHOW_EQUIPMENT_INVENTORY, GameStates.SELL_MENU, GameStates.BUY_MENU, GameStates.SELL_EQUIPMENT_MENU, GameStates.BUY_EQUIPMENT_MENU): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) elif game_state == GameStates.SHOW_BAG: if PLAYERDEADSTATE == True: game_state = GameStates.PLAYER_DEAD else: game_state = GameStates.PLAYERS_TURN elif game_state == GameStates.SHOP_MENU: if PLAYERDEADSTATE == True: game_state = GameStates.PLAYER_DEAD else: game_state = GameStates.PLAYERS_TURN elif game_state == GameStates.PLAYERS_TURN: game_state = GameStates.QUIT_MENU elif game_state == GameStates.DROP_MENU: game_state = GameStates.PLAYERS_TURN else: save_game(player, entities, game_map, message_log, game_state) return True if exit_quit_menu: if game_state == GameStates.QUIT_MENU: game_state = previous_game_state 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') equipment_item_added = player_turn_result.get( 'equipment_item_added') item_consumed = player_turn_result.get('consumed') equipment_consumed = player_turn_result.get('equipment_consumed') item_dropped = player_turn_result.get('item_dropped') loot_dropped = player_turn_result.get('loot_dropped') staff_used = player_turn_result.get('staff_used') 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') item_bought = player_turn_result.get('item_bought') equipment_bought = player_turn_result.get('equipment_bought') end_turn = player_turn_result.get('end_turn') if message: message_log.add_message(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 prowess grows stronger! You reached level {0}!" .format(player.level.current_level), libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if dead_entity: if dead_entity == player: PLAYERDEADSTATE = True message, game_state = kill_player(dead_entity, constants) message_log.add_message(message) else: monster_name = '' monster_name = dead_entity.name message = kill_monster(dead_entity, player, constants) constants['kill_count'] += 1 message_log.add_message(message) while dead_entity.equipment_inventory.items: item = dead_entity.equipment_inventory.items[0] dead_entity.equipment_inventory.loot_item(item) entities.append(item) message_log.add_message( Message( "The {0} dropped the {1}.".format( monster_name, item.name), libtcod.yellow)) while dead_entity.inventory.items: item = dead_entity.inventory.items[0] dead_entity.inventory.loot_item(item) entities.append(item) message_log.add_message( Message( "The {0} dropped the {1}.".format( monster_name, item.name), libtcod.yellow)) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if equipment_item_added: entities.remove(equipment_item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_bought: game_map.shop_items.remove(item_bought) game_state = GameStates.ENEMY_TURN if equipment_bought: game_map.shop_equipment_items.remove(equipment_bought) game_state = GameStates.ENEMY_TURN if equipment_consumed: game_state = GameStates.ENEMY_TURN if staff_used: game_state = GameStates.ENEMY_TURN if end_turn: game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if loot_dropped: entities.append(loot_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 game_state == GameStates.ENEMY_TURN: fov_recompute = True for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities, constants) if entity.fighter.status: enemy_turn_results.extend( entity.fighter.status.update()) 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: PLAYERDEADSTATE = True message, game_state = kill_player( dead_entity, constants) message_log.add_message(message) else: monster_name = '' monster_name = dead_entity.name message = kill_monster(dead_entity, player, constants) constants['kill_count'] += 1 message_log.add_message(message) while dead_entity.equipment_inventory.items: item = dead_entity.equipment_inventory.items[ 0] dead_entity.equipment_inventory.loot_item( item) entities.append(item) message_log.add_message( Message( "The {0} dropped the {1}.".format( monster_name, item.name), libtcod.yellow)) while dead_entity.inventory.items: item = dead_entity.inventory.items[0] dead_entity.inventory.loot_item(item) entities.append(item) message_log.add_message( Message( "The {0} dropped the {1}.".format( monster_name, item.name), libtcod.yellow)) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN begin_player_turn = True
def main(): # Variables that define the screen size. 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 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) # Keeps track of the player's position at all times. player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component) entities = [player] # Tells libtcod which font to use. libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # Creates the screen with a title. libtcod.console_init_root(screen_width, screen_height, 'AngrealRL version T0.01', 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) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) # Variables that hold the keyboard and mouse inputs. key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYER_TURN # Game loop that will only end if the screen is closed. while not libtcod.console_is_window_closed(): # Captures new 'events' (user inputs). 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) # Print the '@' symbol, set it to the position set by two parameters and set the backgroung to 'none'. render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors) fov_recompute = False libtcod.console_flush() clear_all(con, entities) # Allow the game to be 'gracefully' closed by hitting the ESC key. 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.PLAYER_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results = player.fighter.attack(target) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.ENEMY_TURN: 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') # If the entity dies, changes the enemy status to 'dead' 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.PLAYER_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, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } fighter_component = Fighter(hp=30, defense=2, power=5) inventory_component = Inventory(26) player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component) entities = [player] libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False) con = libtcod.console_new(screen_width, screen_height) panel = libtcod.console_new(screen_width, panel_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, max_items_per_room) fov_recompute = True fov_map = initialize_fov(game_map) message_log = MessageLog(message_x, message_width, message_height) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse, colors, game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) # Actions action = handle_keys(key, game_state) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show_inventory') drop_inventory = action.get('drop_inventory') inventory_index = action.get('inventory_index') exit = action.get('exit') fullscreen = action.get('fullscreen') 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)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previous_game_state else: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN 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 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(): # Initial Game Settings screen_width = 80 screen_height = 50 # Map size map_width = 80 map_height = 45 # Field-Of-View settings fov_radius = 10 # Display-field colors colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150), 'light_wall': libtcod.Color(130, 110, 50), 'light_ground': libtcod.Color(200, 180, 50) } # Setup libtcod output console libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Warrens', False) con = libtcod.console_new(screen_width, screen_height) # Initialize and generate game map game_map = GameMap(map_width, map_height, initialize_tiles) game_map = make_map(game_map, 5, 10, 20) seed_ore(game_map, iron_ore) # Field-of-view setup fov_recompute = True fov_map = ShadowcastMap(game_map) # Initialize Player player = Entity(game_map.player_start_x, game_map.player_start_y, '@', libtcod.white, "Player", blocks=True, render_order=RenderOrder.ACTOR) player.add_component(Creature(25, 5, 5, 0)) player.add_component(Storage('Inventory', 100)) # Add starting entities to map game_map.entities.append(player) key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYER_TURN # Main game loop while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: fov_map.recalculate_fov(player.x, player.y, fov_radius) render_all(con, game_map.entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) libtcod.console_flush() clear_all(con, game_map.entities) libtcod.console_put_char(con, player.x, player.y, ' ', libtcod.BKGND_NONE) action = handle_keys(key) move = action.get('move') esc = action.get('esc') fullscreen = action.get('fullscreen') resources = None if move and game_state == GameStates.PLAYER_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if game_map.point_in_map(destination_x, destination_y): if game_map.is_blocked(destination_x, destination_y): resources = game_map.dig(player.x + dx, player.y + dy) else: target = game_map.get_blocking_entities_at_location( destination_x, destination_y) if target: print('You kick the {0} in the shin.'.format( target.name)) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if resources: for resource in resources: status_list = player.components['Inventory'].add_resource( resource) for status in status_list: if status.get('item_status', 'none') == 'rejected': resource_drop = Entity(player.x, player.y, '$', libtcod.white, "Player", resource=resource) game_map.entities.append(resource_drop) if esc: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if game_state == GameStates.ENEMY_TURN: for entity in game_map.entities: if entity != player: print('The {0} waits...'.format(entity.name)) game_state = GameStates.PLAYER_TURN
def play_game(): global key, mouse player_action = None mouse = libtcod.Mouse() key = libtcod.Key() questList=[] #Make me a new quest. Very clearly not how we're going to do this for real newWords=['troll'] benefits=questBenefits(1,'Non',newWords) qData = [player, map, objects, inventory,game_msgs] locQuest=reachLocationQuest(qData) #locQuest.randomizeLocation(qData) #This first quest is a "find the ring and escape" quest, hard-coded. So we need to randomly place the escape and the ring item_component = Item() item = Object(player.x+1, player.y, '*', 'Ring', libtcod.violet, item=item_component) itQuest=obtainItemQuest(item,qData) #itQuest.randomizeItemLocation(qData) quest1=subQuest(benefits,locQuest) quest2=subQuest(benefits,itQuest) mainQuest=quest() mainQuest.addQuest(quest1) mainQuest.addQuest(quest2) questList.append(mainQuest) #make the player's dictionary for testing player.fighter.dictionary = ['strong','banish','orc'] #make up some weapons - there are only so many weapons, so they are all global constants. This will be moved away once we get Item moved daggerStats=equipStats(8,0,0) daggerItem_component = Item() daggerItem = Object(player.x+2, player.y, ')', 'Dagger', libtcod.violet, item=daggerItem_component) dagger=weapon(daggerItem,1,daggerStats) inventory.append(dagger.weaponObject) while not libtcod.console_is_window_closed(): #render the screen libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse) render_all(mouse,map,player,objects,fov_recompute,fov_map) libtcod.console_flush() #erase all objects at their old locations, before they move for object in objects: object.clear() #handle keys and exit game if needed player_action = handle_keys(key,objects,player,inventory,game_state) if player_action == 'exit': # save_game() break qData = [player, map, objects, inventory,game_msgs] #upate the quest data #Once the player takes an action, check quests for qu in questList: qu.isComplete(qData) if qu.completed == True: qu.benefits.giveBenefits(player) inx = questList.index(qu) del(questList[inx]) #let monsters take their turn if game_state == 'playing' and player_action != 'didnt-take-turn': for object in objects: if object.ai: object.ai.take_turn(fov_map,player)
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, 'First RL', 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) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: print('You kick the ' + target.name + ' in the shins, much to its annoyance!') else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity != player: print('The ' + entity.name + ' ponders the meaning of its existence.') game_state = GameStates.PLAYERS_TURN
fov_recompute = True fov_map = tcod.map_new(MAP_WIDTH, MAP_HEIGHT) for y in range(MAP_HEIGHT): for x in range(MAP_WIDTH): tcod.map_set_properties(fov_map, x, y, not map[x][y].block_sight, not map[x][y].blocked) message('Welcome, stranger! Prepare to perish in the Dungeons of Peril!', tcod.red) while not tcod.console_is_window_closed(): render_all() #renders thescreen tcod.console_flush() for object in objects: object.clear() #erases all the old chars player_action = handle_keys() if player_action == 'exit': break if game_state == 'playing': for object in objects: if object.ai: if object.wait > 0: object.wait -= 1 else:
def flush(self): """Flush everything to screen""" libtcod.console_flush()
def render_all(fov_recompute): # main fucntion which draws all objects on the screen every cycle #local renders player = gameconfig.player objects = gameconfig.objects level_map = gameconfig.level_map fov_map = gameconfig.fov_map theme = gameconfig.color_theme if fov_recompute: libtcod.map_compute_fov(fov_map, player.x, player.y, gameconfig.TORCH_RADIUS, gameconfig.FOV_LIGHT_WALLS, gameconfig.FOV_ALGO) # go through all tiles, and set their background color for y in range(gameconfig.MAP_HEIGHT): for x in range(gameconfig.MAP_WIDTH): visible = libtcod.map_is_in_fov(fov_map, x, y) wall = level_map[x][y].block_sight if not visible: if level_map[x][y].explored: if wall: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_dark_wall'], libtcod.BKGND_SET) else: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_dark_ground'], libtcod.BKGND_SET) else: if wall: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_light_wall'], libtcod.BKGND_SET) else: libtcod.console_set_char_background( gameconfig.con, x, y, theme['color_light_ground'], libtcod.BKGND_SET) level_map[x][y].explored = True # draw all objects in the list for obj in objects: if obj != player: if libtcod.map_is_in_fov(fov_map, obj.x, obj.y): draw_object(obj, gameconfig.con) draw_object(player, gameconfig.con) # draw player last #blit the contents of "con" to the root console libtcod.console_blit(gameconfig.con, 0, 0, gameconfig.SCREEN_WIDTH, gameconfig.SCREEN_HEIGHT, 0, 0, 0) # panel libtcod.console_set_default_background(gameconfig.panel, libtcod.black) libtcod.console_clear(gameconfig.panel) # HUD render_hud() render_messages() libtcod.console_blit(gameconfig.panel, 0, 0, gameconfig.SCREEN_WIDTH, gameconfig.PANEL_HEIGHT, 0, 0, gameconfig.PANEL_Y) # clean up libtcod.console_flush() for obj in objects: clear_object(obj, gameconfig.con)
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, 'The Tombs of Twilight', 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) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') player_turn_results = [] if move and game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy if not game_map.is_blocked(destination_x, destination_y): target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') if message: 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(argv=None): """ Entry-point into program.""" settings, args = process_command_line(argv) # Initialise libtcod libtcod.console_set_custom_font( 'arial12x12.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, PROGRAM_NAME, False) libtcod.sys_set_fps(10) libtcod.console_set_background_flag(0, libtcod.BKGND_SET) # Create a map and add starting entities. map = Map(maps.ground_control.level_1_raw) player = Human("Bob Smith", "male", 15, 30) player.report = ReportType.PLAYER map.add_entity(map.entry_point[0], map.entry_point[1], player) # Ghost is used to move around map for viewing ghost = Human("Ghost", "male", 15, 0) # Set up UI ui.Screens.map = ui.MapScreen(MAP_WINDOW[0], MAP_WINDOW[1], MAP_WINDOW[2], MAP_WINDOW[3]) ui.Screens.msg = ui.MessageScreen(MSG_WINDOW[0], MSG_WINDOW[1], MSG_WINDOW[2], MSG_WINDOW[3]) ui.Screens.inv = ui.InventoryScreen(INVENTORY_WINDOW[0], INVENTORY_WINDOW[1], INVENTORY_WINDOW[2], INVENTORY_WINDOW[3]) ui.Screens.map.show_and_activate() ui.Screens.msg.show_and_activate() ui.Screens.inv.hide_and_deactivate() # Set up main game loop. # turn_taken - did the action actually take a turn - ie do we want to update the simulation now? Initially true, to force a initial render. # input_type - what input state did the action leave us in? Are we expecting the next input to be part of the current action? # delayed_action - if we are in the middle of a multi-stage action, this is the action (closure) to be performed at the end of it. turn_taken = True input_type = InputType.IMMEDIATE delayed_action = None current_turn = 1 # main loop while not libtcod.console_is_window_closed(): libtcod.console_clear(0) libtcod.console_set_default_foreground(0, libtcod.white) # set up render bounds centre_bounds = int(MAP_WINDOW[2] / 2), int( MAP_WINDOW[3] / 2), map.x_max - int( MAP_WINDOW[2] / 2) - 1, map.y_max - int(MAP_WINDOW[3] / 2) - 1 # are we viewing the player or the ghost entity which acts as the automap viewer? view_centre = max(centre_bounds[0], min( player.x, centre_bounds[2])), max(centre_bounds[1], min(player.y, centre_bounds[3])) # Render screens if ui.Screens.map.show: ui.Screens.map.render(map, view_centre, player) if ui.Screens.msg.show: ui.Screens.msg.render() if ui.Screens.inv.show: ui.Screens.inv.render(player) ui.render_entity_info(player, map) libtcod.console_set_default_foreground(0, libtcod.white) libtcod.console_print(0, 0, 0, "Turn: %d" % current_turn) # Blit to console libtcod.console_flush() # Process input player_action = input.handle_input(player, input_type, delayed_action) turn_taken, input_type, delayed_action = player_action[0]( player, map, player_action[1:]) if turn_taken: current_turn += 1 # Quit the loop? if turn_taken is None: break # If we've done something, update world and render if turn_taken: sim.update_world() # Return peacefully return 0
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): # Calculate the Fog of War on the map fov_recompute = True fov_map = initialize_fov(game_map) # Set variables to receive both keypresses and mouse movements key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None # The Main game loop while not libtcod.console_is_window_closed(): # Wait until a key is pressed libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) # Recalculate the field of vision from player coordinates. Only happens when player moves if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm']) # Draw everything on screen 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) # Define actions 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') take_stairs = action.get('take_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') exit = action.get('exit') wait = action.get('wait') fullscreen = action.get('fullscreen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') player_turn_results = [] # Move the player character 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 the square contained an enemy, attack it if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) # Otherwise, move into the square and recalculate Field of Vision else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN # Player tries to pick up an item elif pickup and game_state == GameStates.PLAYERS_TURN: for entity in entities: # If there is an item at the coordinates, try to add it to inventory. If full, fail at that 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 # Player tried to pick up empty space else: if random.randint(0, 100) >= 99: message_log.add_message( Message( 'You daintly pick up a handful of musty air and stuff it in your pocket.', libtcod.yellow)) else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) # If the player hits wait, move straight to the enemy turn elif wait and game_state == GameStates.PLAYERS_TURN: game_state = GameStates.ENEMY_TURN # Show the inventory if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY # Show the inventory for dropping items if drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY # Select an item from 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] 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)) """ Player takes the stairs to the next level generate a new level, reset the map and seen squares, and clear the console """ 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)) # When player goes up a level, they get to choose a stat to upgrade and then we return to previous game state 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 # Showing character screen if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN """ Targeting mode Left-click on mouse sets target coordinates and uses the item Right-click cancels targeting """ 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}) # Exits from inventory screens, targeting, or the game in general 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 # Process the results from player turn if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) # Loop that handles all the different 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') 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 there's a message, add to log if message: message_log.add_message(message) # If something died, put a message to the log and if it was the player, react accordingly 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 the player picked up an item, remove it from the world if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN # If player used an item, switch to enemy turn. The item reacts by itself, # this loop only needs to concern itself with the game states if item_consumed: game_state = GameStates.ENEMY_TURN # If an item was dropped, add it to the game world if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN # If player selects equipment from the inventory, equip or dequip it 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 # Item requires targeting, go to targeting mode if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) # Player cancels targeting if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) # Getting experience when killing monsters if xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('You gain {0} experience points.'.format(xp))) # If the xp goes over the xp_to_next_level threshold, leveled_up will be true and player goes up a level 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 # The enemy turn if game_state == GameStates.ENEMY_TURN: # Go through all entities in the list for entity in entities: # If it has an AI, make a move if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) # Handle all the messages from entities for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') # If there's a message, log it if message: message_log.add_message(message) # If something died, make that happen 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
# Create the player player = Object(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2, '@', tcod.white) # Create an NPC npc = Object(SCREEN_WIDTH // 2 - 5, SCREEN_HEIGHT // 2, '@', tcod.yellow) # List of objects objects = [npc, player] while not tcod.console_is_window_closed(): # Draw all objects in the list for object in objects: object.draw() # Blit the contents of 'con' to the root console and present it tcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0) # Push to the root console tcod.console_flush() # Present changes to the screen # Erase all objects at their old locations, before they move for object in objects: object.clear() # Handle keys and exit game if required: tcod.console_put_char(con, player_x, player_y, ' ', tcod.BKGND_NONE) exit = handle_keys() if exit: break
def menu(header, options, width): # general selection menu 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(gameconfig.con, 0, 0, width, gameconfig.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) libtcod.console_set_default_background(window, gameconfig.MENU_BKGND) libtcod.console_rect(window, 0, 0, width, height, False, libtcod.BKGND_SCREEN) #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) 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 window contents x = gameconfig.SCREEN_WIDTH / 2 - width / 2 y = gameconfig.SCREEN_HEIGHT / 2 - height / 2 libtcod.console_set_default_background(window, libtcod.red) libtcod.console_blit(window, 0, 0, width, height, 0, x, y, 1.0, 1.0) #present the root console to the player and wait for a key-press libtcod.console_flush() selected = 0 while True: key = libtcod.console_wait_for_keypress(True) if options: # selection loop if key.vk == libtcod.KEY_DOWN or key.vk == libtcod.KEY_UP: if key.vk == libtcod.KEY_DOWN: if selected < len(options): selected += 1 else: selected = 1 if key.vk == libtcod.KEY_UP: if selected > 1: selected -= 1 else: selected = len(options) # hightlight selected option libtcod.console_set_default_background(window, gameconfig.MENU_BKGND) libtcod.console_rect(window, 0, 0, width, height, False, libtcod.BKGND_SET) libtcod.console_set_default_background( window, gameconfig.MENU_SELECT_BKGND) libtcod.console_rect(window, 0, selected - 1 + header_height, width, 1, False, libtcod.BKGND_SCREEN) libtcod.console_blit(window, 0, 0, width, height, 0, x, y, 1.0, 1.0) libtcod.console_flush() if key.vk == libtcod.KEY_ENTER: return (selected - 1) # convert ascii to index index = key.c - ord('a') if index >= 0 and index < len(options): return index if key.vk == libtcod.KEY_ESCAPE: return None
def play_game(self, players, entities, game_map, message_log, game_state, con, panel, constants): # Flags if we need to update FOV fov_recompute = True for player in players: player.vision.fov_map = initialize_fov(game_map) # Holds keyboard and mouse input key = libtcod.Key() mouse = libtcod.Mouse() self.game_state = GameStates.PLAYERS_TURN previous_game_state = self.game_state targeting_item = None self.previous_player = 0 players[self.active_player].color = libtcod.white # Game loop while not libtcod.console_is_window_closed(): # Execute any player command if players[self.active_player].command: command_results = players[self.active_player].command.execute() finish_turn = False for command_result in command_results: finish_command = command_result.get('finish_command') redo_fov = command_result.get('redo_fov') end_turn = command_result.get('end_turn') if finish_command: players[self.active_player].command = None if redo_fov: fov_recompute = True if end_turn: finish_turn = True if finish_turn: self.next_player(players) continue # Enemy Movement if self.game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( players, 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 in players: message, self.game_state = kill_player( dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if self.game_state == GameStates.PLAYER_DEAD: break if self.game_state == GameStates.PLAYER_DEAD: break else: self.game_state = GameStates.PLAYERS_TURN continue # Input listener I guess libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) # Update fov if needed if fov_recompute: for player in players: recompute_fov(player.vision.fov_map, player.x, player.y, self.constants['fov_radius'], self.constants['fov_light_walls'], self.constants['fov_algorithm']) # Render all entities render_all( con, panel, entities, players, self.active_player, game_map, fov_recompute, message_log, self.constants['screen_width'], self.constants['screen_height'], self.constants['bar_width'], self.constants['panel_height'], self.constants['panel_y'], mouse, self.constants['colors'], self.game_state) fov_recompute = False # Push frame update libtcod.console_flush() # Clear old entity positions clear_all(con, entities, game_map) # Determine action action = handle_keys(key, self.game_state) mouse_action = handle_mouse(mouse) # Process the action object repeat = action.get('repeat') 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') cancel_follow = action.get('cancel_follow') level_up = action.get('level_up') exit = action.get('exit') show_character_screen = action.get('show_character_screen') fullscreen = action.get('fullscreen') # Handle mouseclicks left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') # For the message log player_turn_results = [] # Movement if move and self.game_state == GameStates.PLAYERS_TURN: dx, dy = move destination_x = players[self.active_player].x + dx destination_y = players[self.active_player].y + dy if not (destination_x < 0 or destination_x >= game_map.width or destination_y < 0 or destination_y >= game_map.height or game_map.is_blocked(destination_x, destination_y)): target = get_blocking_entities_at_location( entities, destination_x, destination_y) # If the way is blocked by a baddie if target: # Don't attack other players if target in players: # follow the player you're bumping into # Only follow if it would not make it so every player is following something # (That would be bad) command_count = 0 for player in players: if player.command: command_count += 1 if command_count < len(players) - 1: players[self.active_player].set_command( FollowCommand(-1, target, entities, game_map)) self.next_player(players) else: # If it would do that, just ignore the input continue # Do attack enemies else: attack_results = players[ self.active_player].fighter.attack(target) player_turn_results.extend(attack_results) # Change active player self.next_player(players) else: # Repeat if needed if repeat: # Dont let all players be repeating command_count = 0 for player in players: if player.command: command_count += 1 if command_count < len(players) - 1: players[self.active_player].set_command( MoveCommand(repeat, dx, dy, entities, game_map)) else: # If it would do that, just ignore the input continue else: players[self.active_player].set_command( MoveCommand(1, dx, dy, entities, game_map)) if wait: if repeat: # Dont let all players be repeating command_count = 0 for player in players: if player.command: command_count += 1 if command_count < len(players) - 1: # We wait by moving nowhere. This may need to become a WaitCommand eventually players[self.active_player].set_command( MoveCommand(repeat, 0, 0, entities, game_map)) else: # If it would make all players repeat, just ignore the input continue else: # Change active player players[self.active_player].set_command( MoveCommand(1, 0, 0, entities, game_map)) # Picking up an item elif pickup and self.game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.item and entity.x == players[ self.active_player].x and entity.y == players[ self.active_player].y: pickup_results = players[ self.active_player].inventory.add_item(entity) player_turn_results.extend(pickup_results) break else: message_log.add_message( Message('There is nothing here to pick up.', libtcod.yellow)) # Show inventory menu if show_inventory: previous_game_state = self.game_state self.game_state = GameStates.SHOW_INVENTORY # Drop inventory if drop_inventory: previous_game_state = self.game_state self.game_state = GameStates.DROP_INVENTORY # Choose inventory item if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( players[self.active_player].inventory.items): item = players[ self.active_player].inventory.items[inventory_index] if self.game_state == GameStates.SHOW_INVENTORY: player_turn_results.extend( players[self.active_player].inventory.use( item, entities=entities, fov_map=players[ self.active_player].vision.fov_map)) elif self.game_state == GameStates.DROP_INVENTORY: player_turn_results.extend( players[self.active_player].inventory.drop_item(item)) # Take stairs if take_stairs and self.game_state == GameStates.PLAYERS_TURN: for entity in entities: if entity.stairs and entity.x == players[ self.active_player].x and entity.y == players[ self.active_player].y: entities = game_map.next_floor(players, message_log, self.constants) for player in players: player.vision.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)) # Cancel follow if cancel_follow: for player in players: player.command = None # Level up if level_up: if level_up == 'hp': players[self.active_player].fighter.base_max_hp += 20 players[self.active_player].fighter.hp += 20 elif level_up == 'str': players[self.active_player].fighter.base_power += 1 elif level_up == 'def': players[self.active_player].fighter.base_defense += 1 self.game_state = previous_game_state # Character screen if show_character_screen: previous_game_state = self.game_state self.game_state = GameStates.CHARACTER_SCREEN # Targeting if self.game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = players[ self.active_player].inventory.use( targeting_item, entities=entities, fov_map=players[self.active_player].vision.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}) # Exit on escape if exit: if self.game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): self.game_state = previous_game_state elif self.game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(players, entities, game_map, message_log, self.game_state, self.active_player) return True # Toggle fullscreen if fullscreen: libtcod.console_set_fullscreen( not libtcod.console_is_fullscreen()) # Print message results 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 in players: message, self.game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) # Change active player self.next_player(players) if item_consumed: # Change active player self.next_player(players) if item_dropped: entities.append(item_dropped) # Change active player self.next_player(players) if equip: equip_results = players[ self.active_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))) # Change active player self.next_player(players) if targeting: previous_game_state = GameStates.PLAYERS_TURN self.game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message( targeting_item.item.targeting_message) if targeting_cancelled: self.game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if xp: leveled_up = players[self.active_player].level.add_xp(xp) message_log.add_message( Message('You gain {0} experience point.'.format(xp))) if leveled_up: message_log.add_message( Message( 'Your battle skills grow stronger! You reached level {0}' .format(players[ self.active_player].level.current_level) + '!', libtcod.yellow)) previous_game_state = self.game_state self.game_state = GameStates.LEVEL_UP
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): """Logic for controlling the game itself""" fov_recompute = True # Only need to recompute when we move (and start!) fov_map = initialize_fov(game_map) # Variable that is the fov result message_log = MessageLog(constants['message_x'], constants['message_width'], constants['message_height']) # Input variables and game state key = libtcod.Key() mouse = libtcod.Mouse() game_state = GameStates.PLAYERS_TURN previous_game_state = game_state targeting_item = None # ENGINE 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, entities, player, game_map, fov_map, fov_recompute, constants['screen_width'], constants['screen_height'], message_log, constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state) fov_recompute = False libtcod.console_flush() # Presents everything on the screen clear_all(con, entities) # Erases the old positions # ACTION HANDLERS 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 = [] # GAME STATE SITUATIONS 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 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: # no break 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: # No break 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 fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): # Return to gameplay state from above states game_state = previous_game_state elif game_state == GameStates.TARGETING: # Return to game from targeting state game_state = previous_game_state player_turn_results.append({'targeting_cancelled': True}) elif game_state == GameStates.PLAYER_DEAD: # Delete a save file if player exits after dying if os.path.isfile('savegame.dat'): os.remove('savegame.dat') return True else: # Create a save file if player exits while alive save_game(player, entities, game_map, message_log, game_state) return True # PLAYER TURN RESULTS 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') unequipped = equip_result.get('unequiped') if equipped: message_log.add_message( Message("You equipped the {}.".format( equipped.name))) if unequipped: message_log.add_message( Message("You unequipped the {}.".format( unequipped.name))) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN # Canceling doesn't go to inventory 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) # Adds the xp and returns boolean re: a level-up message_log.add_message(Message( "You gained {} EXP".format(xp))) if leveled_up: message_log.add_message( Message( "You've grown to level {}!".format( player.level.current_level), libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN
def main(): # Screen size screen_width = 80 screen_height = 50 # Map parameters map_width = 80 map_height = 45 max_rooms = 30 room_min_size = 6 room_max_size = 10 max_monsters_per_room = 3 # Field of view parameters fov_algorithm = 0 fov_light_walls = True fov_radius = 10 # Colors for blocked and non-blocked tiles 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 data, a white @ in the middle of the screen # Position needs to be forcefully cast to int player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white, 'Player', blocks=True) # Entity array entities = [player] # Loads greyscale TCOD-mapping Arial 10x10 font libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # Creates the screen. Boolean indicates full screen libtcod.console_init_root(screen_width, screen_height, 'NeverDie', False) # Creates a new console con = libtcod.console_new(screen_width, screen_height) # Initialize the map game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room) # Variable to recompute FOV fov_recompute = True # Initialize field of view fov_map = initialize_fov(game_map) # Store keyboard and mouse input key = libtcod.Key() mouse = libtcod.Mouse() # Initiatlize the game state game_state = GameStates.PLAYER_TURN # Main game loop while not libtcod.console_is_window_closed(): # Captures keyboard and mouse input libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) # Recompute FOV if player has moved if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) # Draws entities and map render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False # Redraws the screen libtcod.console_flush() # Erases old positions of entities clear_all(con, entities) # Leaves a red dot to be drawn next time the @ moves libtcod.console_set_default_foreground(con, libtcod.red) libtcod.console_put_char(con, player.x, player.y, '.', libtcod.BKGND_NONE) # Handles key presses action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') # If "move" and is the player's turn, moves the player if move and game_state == GameStates.PLAYER_TURN: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy # Check if the space is blocked by a wall before moving if not game_map.is_blocked(destination_x, destination_y): # And if it's blocked by an entity 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) # Recompute FOV after moving fov_recompute = True # Change to enemy's turn game_state = GameStates.ENEMY_TURN # If it's the enemy's turn, move the enemies if game_state == GameStates.ENEMY_TURN: # Every monster does nothing for entity in entities: if entity != player: print('The ' + entity.name + ' ponders the meaning of ' + 'its existence.') # Change to player's turn game_state = GameStates.PLAYER_TURN if exit: return True # If "fullscreen"", toggles fullscreen if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(self): # Set font libtcod.console_set_custom_font( 'dejavu_wide16x16_gs_tc.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # Create game window libtcod.console_init_root(self.constants['screen_width'], self.constants['screen_height'], self.constants['window_title'], False) # Create a console (Drawing Layer?) con = libtcod.console_new(self.constants['screen_width'], self.constants['screen_height']) panel = libtcod.console_new(self.constants['screen_width'], self.constants['panel_height']) players = [] entity = [] game_map = None message_log = None self.game_state = None self.active_player = 0 show_main_menu = True show_load_error_message = False main_menu_background_image = libtcod.image_load('menu_background.png') # Holds keyboard and mouse input key = libtcod.Key() mouse = libtcod.Mouse() # Menu loop while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) if show_main_menu: main_menu(con, main_menu_background_image, self.constants['screen_width'], self.constants['screen_height']) if show_load_error_message: message_box(con, 'No save game to load', 50, self.constants['screen_width'], self.constants['screen_height']) libtcod.console_flush() action = handle_main_menu(key) new_game = action.get('new_game') load_saved_game = action.get('load_game') exit_game = action.get('exit') if show_load_error_message and (new_game or load_saved_game or exit_game): show_load_error_message = False elif new_game: players, entities, game_map, message_log, self.game_state = get_game_variables( self.constants) self.game_state = GameStates.PLAYERS_TURN show_main_menu = False elif load_saved_game: try: players, entities, game_map, message_log, self.game_state, self.active_player = load_game( self.constants['player_count']) self.game_state = GameStates.PLAYERS_TURN show_main_menu = False except FileNotFoundError: show_load_error_message = True elif exit_game: break else: libtcod.console_clear(con) self.play_game(players, entities, game_map, message_log, self.game_state, con, panel, self.constants) show_main_menu = True