def start_screen(self): show_main_menu = True while show_main_menu: libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, self.key, self.mouse) main_menu(self.con, game_constants.main_menu_background_image) libtcod.console_flush() action = handle_keys(self.key, GameStates.MAIN_MENU) game_type = action.get('game_start') exit_game = action.get('action') == 'exit' if exit_game: return False elif game_type == 'from_scratch': return True elif game_type == 'from_save': self.player, self.entities, self.game_map, self.message_log, self.game_state = load_game( ) self.fov_map = initialize_fov(self.game_map) self.entities.set_log_all(self.message_log) return True
def check_for_input(self): """Checks for window events and passes key events to input handler.""" for event in tcod.event.get(): if event.type == "QUIT": raise SystemExit if event.type == "KEYDOWN": return input_handler.handle_keys(event.sym)
def main(): #Initialise some game variables/objects and the libtcod console screen_width = 16 screen_height = 16 fps_limit = 60 libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Snake', False) libtcod.sys_set_fps(fps_limit) con = libtcod.console_new(screen_width, screen_height) key = libtcod.Key() mouse = libtcod.Mouse() apple = Apple('A', libtcod.Color(200, 20, 20), screen_width, screen_height) snake = Snake(int(screen_width / 2), int(screen_height / 2), 'S', libtcod.Color(20, 200, 20), 1, fps_limit, apple, screen_width, screen_height) #Main game loop while not libtcod.console_is_window_closed(): #Updates game entities if snake is not dead if snake.alive == True: snake.update() entities = snake.entities.copy() entities.append(apple.apple) #Handles rendering render_all(con, entities, screen_width, screen_height) libtcod.console_flush() clear_all(con, entities) #Handles keyboard input libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) input = handle_keys(key) move = input.get('move') restart = input.get('restart') exit = input.get('exit') fullscreen = input.get('fullscreen') if move: snake.set_next_dir(move) if restart: snake = Snake(int(screen_width / 2), int(screen_height / 2), 'S', libtcod.Color(20, 200, 20), 1, fps_limit, apple, screen_width, screen_height) if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): 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) dialog_prompt = DialogPrompt(dialog_pos_x, dialog_pos_y, "npc_dialog", dialog_width, dialog_height, con) game_map = GameMap(map_width, map_height) game_map.switch_map(0) fov_recomputer = True game_entities = [] dialog_entities = [] player = GameObject(3, 3, '@', libtcod.white, "Hero", True) npc = GameObject(int(screen_width / 2 - 5), int(screen_height / 2), '@', libtcod.yellow, "Bad Guy", True) game_entities.append(player) game_entities.append(npc) key= libtcod.Key() mouse = libtcod.Mouse() libtcod.console_set_window_title(game_title+ " - " + game_map.map_name) while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) draw_all(con, game_entities, game_map, screen_width, screen_height) libtcod.console_flush() clear_all(con, game_entities) if key.c == ord('a'): dialog_prompt.npc_dialog('main') action = handle_keys(key) move = action.get('move') exit = action.get('exit') if move: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy) and not game_map.is_transport(player.x + dx, player.y + dy): game_map.unblock(player.x, player.y) player.move(dx,dy) elif game_map.is_transport(player.x + dx, player.y + dy): transport = game_map.spaces[player.x + dx][player.y + dy].transport game_map.switch_map(transport.new_map_index) libtcod.console_set_window_title( game_title + " - " + game_map.map_name) game_map.unblock(player.x, player.y) player.move(dx , dy ) player.move(transport.dx, transport.dy) if key.vk == libtcod.KEY_ESCAPE: return True game_map.update_blocked(game_entities)
def main(): screen_width = 20 screen_height = 20 libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'TEST RL', False) con = libtcod.console_new(screen_width, screen_height) key = libtcod.Key() mouse = libtcod.Mouse() player = Entity(5, 5, '@', libtcod.red) oracle = Entity(2, 2, '0', libtcod.blue) entities = [player, oracle] while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) render_all(con, entities, screen_width, screen_height) libtcod.console_flush() clear_all(con, entities) input = handle_keys(key) move = input.get('move') exit = input.get('exit') fullscreen = input.get('fullscreen') if move: x, y = move player.move(x, y) if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): screen_width = 80 screen_height = 50 player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white) npc = Entity(int(screen_width / 2) -5, int(screen_height / 2), '@', libtcod.yellow) entities = [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, 'libtcod tutorial revised', False) key = libtcod.Key() mouse = libtcod.Mouse() con = libtcod.console_new(screen_width, screen_height) while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) render_all(con,entities,screen_width,screen_height) libtcod.console_flush() clear_all(con, entities) key = libtcod.console_check_for_keypress() action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: dx, dy = move player.move(dx,dy) if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def main(): ## SETUP ## screen_width = 80 screen_height = 65 fps_limit = 10 libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'The Game of Life', False) libtcod.sys_set_fps(fps_limit) con = libtcod.console_new(screen_width, screen_height) key = libtcod.Key() mouse = libtcod.Mouse() map = GameMap(screen_width, screen_height) ## GAME LOOP ## while not libtcod.console_is_window_closed(): ## ENTITY UPDATES AND RENDERING ## entities = map.get_entities() libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) render_all(con, entities, screen_width, screen_height) libtcod.console_flush() clear_all(con, entities) map.update_tiles() ## CALLS TO INPUT HANDLING ## input = handle_keys(key) exit = input.get('exit') fullscreen = input.get('fullscreen') if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants, turns, poison_turns, burned_turns, frozen_turns): fov_recompute = True pet = 0 boss = None for entity in entities: if entity.name == 'Pet': pet = entity break for entity in entities: if entity.name == 'Dragonlord': boss = entity break 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 arrow_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']) if game_map.biome == 'The Dungeon': colors = { 'dark_wall': libtcod.darkest_grey, 'dark_ground': libtcod.darker_grey, 'light_wall': libtcod.grey, 'light_ground': libtcod.white, 'dark_water': libtcod.blue, 'light_water': libtcod.light_blue } elif game_map.biome == 'The Icebleak Cavern': colors = { 'dark_wall': libtcod.darkest_cyan, 'dark_ground': libtcod.darker_cyan, 'light_wall': libtcod.dark_cyan, 'light_ground': libtcod.white, 'dark_water': libtcod.blue, 'light_water': libtcod.light_blue } elif game_map.biome == 'The Underglade': colors = { 'dark_wall': libtcod.darker_green, 'dark_ground': libtcod.darkest_green, 'light_wall': libtcod.desaturated_green, 'light_ground': libtcod.brass, 'dark_water': libtcod.blue, 'light_water': libtcod.light_blue } elif game_map.biome == 'The Hadalrealm': colors = { 'dark_wall': libtcod.darkest_red, 'dark_ground': libtcod.darker_red, 'light_wall': libtcod.dark_red, 'light_ground': libtcod.white, 'dark_water': libtcod.blue, 'light_water': libtcod.light_blue } elif game_map.biome == 'Dragonroost': colors = { 'dark_wall': libtcod.darkest_grey, 'dark_ground': libtcod.darker_grey, 'light_wall': libtcod.dark_grey, 'light_ground': libtcod.grey, 'dark_water': libtcod.blue, 'light_water': libtcod.light_blue } elif game_map.biome == 'Oblivion\'s Gate': colors = { 'dark_wall': libtcod.darkest_grey, 'dark_ground': libtcod.darker_grey, 'light_wall': libtcod.dark_grey, 'light_ground': libtcod.white, 'dark_water': libtcod.blue, 'light_water': libtcod.light_blue } elif game_map.biome == 'The Vault': colors = { 'dark_wall': libtcod.darker_yellow, 'dark_ground': libtcod.dark_yellow, 'light_wall': libtcod.yellow, 'light_ground': libtcod.white, 'dark_water': libtcod.blue, 'light_water': libtcod.light_blue } render_all(turns, 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, colors, game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) mouse_action = handle_mouse(mouse) player.sound = 0 Scent.set_scent(game_map, player.x, player.y, turns) 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') wait = action.get('wait') take_up_stairs = action.get('take_up_stairs') take_down_stairs = action.get('take_down_stairs') level_up = action.get('level_up') show_character_screen = action.get('show_character_screen') show_help_screen = action.get('show_help_screen') left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') up = action.get('up') down = action.get('down') left = action.get('left') right = action.get('right') player_turn_results = [] if player.frozen and frozen_turns > 0: game_state = GameStates.ENEMY_TURN if player.frozen == False: frozen_turns = -42 if player.burned == False: burned_turns = -42 if player.poisoned == False: poison_turns = -42 if poison_turns == 0: player_turn_results.append({ 'message': Message('You feel a lot better', libtcod.light_cyan) }) poison_turns = -42 player.poisoned = False if burned_turns == 0: player_turn_results.append({ 'message': Message('Your burn feels a lot better', libtcod.light_cyan) }) burned_turns = -42 player.burned = False if frozen_turns == 0: player_turn_results.append( {'message': Message('You defrost', libtcod.light_cyan)}) frozen_turns = -42 player.frozen = False if wait: game_state = GameStates.ENEMY_TURN d = randint(0, 100) if d < 25: message_log.add_message( Message('You stand around doing nothing', libtcod.brass)) elif d < 50: message_log.add_message( Message('You lean on your sword', libtcod.brass)) elif d < 75: message_log.add_message( Message('You stand around looking like a lemon', libtcod.brass)) else: message_log.add_message( Message('You examine your surroundings intensely', libtcod.light_amber)) 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: if target.name == 'Pet': target = None if target: attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: if game_map.tiles[player.x][player.y].water == True: if randint(0, 10) == 1: game_map.tiles[destination_x][ destination_y].water = True player_turn_results.append({ 'message': Message( 'You splash water all over the dry bit of floor', libtcod.cyan) }) player.move(dx, dy) player.sound = 10 if turns % randint(9, 11) == 0: player.fighter.heal(1) levelup = player.level.add_con_xp(1) if levelup: player.fighter.hp += 20 player.fighter.base_max_hp += 20 player_turn_results.append({ 'message': Message( 'You feel healthy, you must have been very active', libtcod.fuchsia) }) fov_recompute = True game_state = GameStates.ENEMY_TURN elif pickup and game_state == GameStates.PLAYERS_TURN: here = 0 for entity in entities: if entity.name != 'Player' and not entity.stairs and not entity.monster_class == '(Pet)': if (entity.item or entity.equippable ) and entity.x == player.x and entity.y == player.y: here = 1 player.sound = 5 pickup_results = player.inventory.add_item(entity) player_turn_results.extend(pickup_results) else: if here == 0: 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 player.sound = 5 game_state = GameStates.DROP_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.items): item = player.items[inventory_index] if type(item) != str: if game_state == GameStates.SHOW_INVENTORY: success = True if item.item_class == '(Scroll)': difficulty = randint(0, 10) if difficulty > player.fighter.intelligence: success = False else: levelup = player.level.add_int_xp(1) if levelup: message_log.add_message( Message( 'Your reading grows more accurate!', libtcod.fuchsia)) player.fighter.base_intelligence += 1 player_turn_results.extend( player.inventory.use(success, item, entities=entities, fov_map=fov_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend( player.inventory.drop_item(item)) else: message_log.add_message( Message('You can\'t use Headers', libtcod.yellow)) if take_up_stairs and game_state == GameStates.PLAYERS_TURN and not boss: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: pet, entities = game_map.next_floor( player, message_log, constants, entities, 'up') fov_map = initialize_fov(game_map) fov_recompute = True player.sound = 10 libtcod.console_clear(con) break else: message_log.add_message( Message('You can\'t go up here.', libtcod.yellow)) if take_down_stairs and game_state == GameStates.PLAYERS_TURN and not boss: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: pet, entities = game_map.next_floor( player, message_log, constants, entities, 'down') fov_map = initialize_fov(game_map) fov_recompute = True player.sound = 10 libtcod.console_clear(con) break else: message_log.add_message( Message('You can\'t go down 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_defence += 1 elif level_up == 'int': player.fighter.base_intelligence += 1 elif level_up == 'dex': player.fighter.base_dexterity += 1 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if show_help_screen: previous_game_state = game_state game_state = GameStates.HELP_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(success, targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if game_state == GameStates.ARROW_TARGETING: direction = None if up: direction = 'up' elif down: direction = 'down' elif left: direction = 'left' elif right: direction = 'right' if direction: item_use_results = player.inventory.use(success, arrow_targeting_item, entities=entities, fov_map=fov_map, direction=direction) player_turn_results.extend(item_use_results) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN, GameStates.HELP_SCREEN): game_state = previous_game_state elif game_state == GameStates.TARGETING or game_state == GameStates.ARROW_TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state, poison_turns, turns, burned_turns, frozen_turns) 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') arrow_consumed = player_turn_result.get('arrow_consumed') item_dropped = player_turn_result.get('item_dropped') equip = player_turn_result.get('equip') targeting = player_turn_result.get('targeting') arrow_targeting = player_turn_result.get('arrow_targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') player_burned = player_turn_result.get('burned') enemy_turn = player_turn_result.get('pass') if enemy_turn: game_state = GameStates.ENEMY_TURN if player_burned: player_turn_results.append( {'message': Message('You get Burned', libtcod.flame)}) burned_turns = randint(5, 10) message = player_turn_result.get('message') 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, game_map, entities) arrows = 0 for i in range(0, dead_entity.arrows): arrow_break = randint(0, 1) if not arrow_break: item_component = Item(use_function=None) arrow = Entity(dead_entity.x, dead_entity.y, '|', libtcod.sepia, 'Arrow', item=item_component, item_class='(Arrow)') entities.append(arrow) else: arrows += 1 if arrows == 1: MessageLog.add_message( self=message_log, message=Message( 'The arrow stuck in the {0} breaks as it falls over' .format(dead_entity.name), libtcod.red)) elif arrows: MessageLog.add_message( self=message_log, message=Message( 'The {0} arrows stuck in the {1} breaks as it falls over' .format(arrows, dead_entity.name), libtcod.red)) 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 arrow_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if equip: player.sound = 10 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 arrow_targeting: player.sound = 5 previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.ARROW_TARGETING arrow_targeting_item = arrow_targeting message_log.add_message( arrow_targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if game_state == GameStates.ENEMY_TURN: if turns % int( (300 - (game_map.dungeon_level * 2)) / 2) == 0 and turns != 0: game_map.add_entity(message_log, entities, fov_map) if burned_turns >= 0 and player.burned: dead_entity = False burned_results = player.fighter.take_damage(4) for burned_result in burned_results: dead_entity = burned_result.get('dead') if dead_entity: if dead_entity.name == 'Player': message, game_state = kill_player(dead_entity) message_log.add_message(message) burned_turns -= 1 if poison_turns >= 0 and player.poisoned: dead_entity = False poison_results = player.fighter.take_damage(1) for poison_result in poison_results: dead_entity = poison_result.get('dead') if dead_entity: if dead_entity.name == 'Player': message, game_state = kill_player(dead_entity) message_log.add_message(message) poison_turns -= 1 if frozen_turns >= 0 and player.frozen: frozen_turns -= 1 if frozen_turns == 0: player.frozen = False for entity in entities: if entity.ai: pet_there = 0 if pet: if entity.distance_to(player) >= entity.distance_to( pet) and entity.name != 'Pet': pet_there = 1 enemy_turn_results = entity.ai.take_turn( pet, fov_map, game_map, entities, turns) else: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities, turns) else: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities, turns) for enemy_turn_result in enemy_turn_results: if burned_turns >= 0: burned_results = entity.fighter.take_damage(4) for burned_result in burned_results: dead_entity = burned_result.get('dead') if dead_entity.name == 'Player': message, game_state = kill_player( dead_entity) message_log.add_message(message) burned_turns -= 1 poisoned, player_burned, frozen = False, False, False if not player.fighter.poison_resistance and not pet_there: poisoned = enemy_turn_result.get('poisoned') if not player.fighter.fire_resistance and not pet_there: player_burned = enemy_turn_result.get('burned') if not player.fighter.poison_resistance and not pet_there: frozen = enemy_turn_result.get('frozen') if player_burned: enemy_turn_results.append({ 'message': Message('You get Burned', libtcod.flame) }) burned_turns = randint(5, 10) player.burned = True if poisoned: enemy_turn_results.append({ 'message': Message('you start to feel ill', libtcod.green) }) poison_turns = randint(20, 50) player.poisoned = True if frozen: enemy_turn_results.append({ 'message': Message('you stop being able to move!', libtcod.light_blue) }) frozen_turns = randint(2, 5) player.frozen = True 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) elif dead_entity == pet: pet = 0 message = kill_pet(dead_entity) elif dead_entity == boss: game_state = GameStates.WINNING message = kill_boss(dead_entity) else: message = kill_monster(dead_entity, pet, game_map) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: turns += 1 game_state = GameStates.PLAYERS_TURN
def main(): # Presets libtcod.sys_set_fps(120) screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 max_monsters = 20 fov_algorithm = 0 fov_light_walls = True fov_radius = 6 # Dictionary to hold colors we'll be using colors = { 'dark_wall': libtcod.Color(48, 98, 48), 'dark_ground': libtcod.Color(100, 140, 15), 'light_wall': libtcod.Color(110, 110, 48), 'light_ground': libtcod.Color(155, 188, 15), 'unexplored': libtcod.Color(15, 56, 15) } # We declare an npc npc = Entity(int(screen_width / 2 + 2), int(screen_height / 2 - 5), '@', libtcod.grey) # We declare the player player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white) # We get all entities in a list so we can iterate them entities = [player, npc] # Define the font and the screen... libtcod.console_set_custom_font( 'arial12x12.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Roguelike', False) # False because we dont want fullscreen # Main console con = libtcod.console_new(screen_width, screen_height) # We create a map randomly from the available options map_type = randint(0, 1) if map_type == 0: game_map = GameMap(map_width, map_height) game_map.make_map(80, map_width, map_height, player, max_monsters, entities) else: room_num = randint(10, max_rooms) game_map = roomGameMap(map_width, map_height) game_map.make_map(room_num, room_min_size, room_max_size, map_width, map_height, player, entities, 3) # Fov doesn't need to be computed every turn, only if we move. We use # the boolean fov_recompute to handle this fov_recompute = True fov_map = initialize_fov(game_map) # Key for holding key presses and mouse variable key = libtcod.Key() mouse = libtcod.Mouse() # Game Loop while not libtcod.console_is_window_closed(): # Check for keypress libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) # Calculate fov if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors, player) fov_recompute = False libtcod.console_flush() # We overwrite the character before getting the new coordinates, so next time we draw # it will not leave a trace ''' Key handling We look for dictionary entries in action. If any of these is present it will be True. ''' action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: dx, dy = move # We check if we can actually move to the tile if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) fov_recompute = True if exit: return True if fullscreen: libtcod.console_set_fullscreen( not libtcod.console_is_fullscreen()) # On and off
def main(): screen_height = 50 screen_width = 80 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) } # initial position for player player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True) # creates list to hold the map's entities entities = [player] # set font for game libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) # makes root console libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False) # console for drawing the game con = libtcod.console.Console(screen_width, screen_height) # instance the game's 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) # init field-of-view for player character fov_recompute = True fov_map = initialize_fov(game_map) key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): # gets new events, and updates key and mouse libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) if fov_recompute: compute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm) # recomputed, until player moves, don't recomputer fov map libtcod.console_set_default_foreground(con, libtcod.white) # render all entities to desired console render_all(con, entities, game_map, fov_map, fov_recompute, screen_width, screen_height, colors) fov_recompute = False # output to console libtcod.console_flush() # clear last position clear_all(con, entities) # obtain event action = handle_keys(key) # check and handle event move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: # from the move dictionary obtain the x and y and update player pos dx, dy = move destination_x = player.x + dx destination_y = player.y + dy # check if direction of movement is towards blocked tile if not game_map.is_blocked(player.x + dx, player.y + dy): # check if there is a blocking Entity target = get_blocking_entities_at_location( entities, destination_x, destination_y) if target: print("You kick the" + target.name + " in the shins!") else: # if not blocked, move player there player.move(dx, dy) # on next map redraw, redraw the FOV fov_recompute = True if exit: return True # toggles full screen based on ALT+ENTER user event if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def play_game(player, entities, game_map, message_log, game_state, root_console, con, panel, mouse_console, constants): tdl.set_font('arial12x12.png', greyscale=True, altLayout=True) fov_recompute = True previous_game_state = game_state targeting_item = None mouse_coordinates = (0, 0) mouse_location_x, mouse_location_y = mouse_coordinates highlight_path = False # MAIN GAME LOOP while not tdl.event.is_window_closed(): if fov_recompute: game_map.compute_fov(player.x, player.y, fov=constants['fov_algorithm'], radius=constants['fov_radius'], light_walls=constants['fov_light_walls']) if highlight_path: path = game_map.compute_path(player.x, player.y, mouse_location_x, mouse_location_y) else: path = [(mouse_location_x, mouse_location_y)] # render all entities render_all(con, panel, mouse_console, entities, player, game_map, fov_recompute, root_console, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], mouse_coordinates, path, game_state) tdl.flush() # clear entities last positions clear_all(con, entities) fov_recompute = False # event handling for event in tdl.event.get(): if event.type == 'KEYDOWN': user_input = event break elif event.type == 'MOUSEMOTION': mouse_coordinates = event.cell mouse_location_x, mouse_location_y = mouse_coordinates elif event.type == 'MOUSEDOWN': user_mouse_input = event break else: user_input = None user_mouse_input = None if not (user_input or user_mouse_input): continue action = handle_keys(user_input, game_state) # check what was pressed mouse_action = handle_mouse(user_mouse_input) move = action.get('move') pickup = action.get('pickup') show_inventory = action.get('show inventory') inventory_index = action.get('inventory index') drop_inventory = action.get('drop inventory') 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 or left_click) and game_state == GameStates.PLAYERS_TURN: # make variables based on type of move if move: dx, dy = move destination_x = player.x + dx destination_y = player.y + dy else: destination_x, destination_y = left_click # Do checks and move player / attack if destination_x == player.x and destination_y == player.y: # player is waiting fov_recompute = True game_state = GameStates.ENEMY_TURN elif game_map.walkable[destination_x, destination_y]: if left_click: path = game_map.compute_path(player.x, player.y, mouse_location_x, mouse_location_y) dx = path[0][0] - player.x dy = path[0][1] - player.y destination_x = path[0][0] destination_y = path[0][1] 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.', colors.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, game_map=game_map)) elif game_state == GameStates.DROP_INVENTORY: player_turn_results.extend(player.inventory.drop_item(item)) if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, game_map=game_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: tdl.set_fullscreen(not tdl.get_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') if message: message_log.add_message(message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, 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_width = 80 screen_height = 50 map_width = 80 map_height = 45 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150) } #The following changes the non-moving character to red player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.red) npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@', libtcod.black) entities = [npc, player] #player = Entity(int(screen_width / 2), int(screen_height / 2), '#', libtcod.white) libtcod.console_set_custom_font( 'arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'CyberChasm', False) con = libtcod.console.Console(screen_width, screen_height) game_map = GameMap(map_width, map_height) key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) render_all(con, entities, game_map, screen_width, screen_height, colors) #changing the color in the following line changes the movable character's color libtcod.console_set_default_foreground(0, libtcod.black) libtcod.console_put_char(0, player.x, player.y, '@', libtcod.BKGND_NONE) libtcod.console_put_char(0, player.x, player.y, '#', libtcod.BKGND_NONE) libtcod.console_flush() libtcod.console_put_char(0, player.x, player.y, ' ', libtcod.BKGND_NONE) clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('Full Screen') 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 main(self): # Game Loop while self.game_running: # Check input streams for an event libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, self.key, self.mouse) # If we need to recompute fov, do so if self.fov_recompute: recompute_fov(self.fov_map, self.player.x, self.player.y) # Render the game world according to current FOV, mark FOV recompute as complete, and flush to console render_all(self.con, self.panel, self.entities, self.player, self.game_map, self.fov_map, self.fov_recompute, self.message_log, self.mouse, self.game_state, self.player_target) self.fov_recompute = False libtcod.console_flush() # Interpret the input into a game action input = handle_keys(self.key, self.game_state) action = input.get('action') inventory_item = input.get( 'inventory_item') if 'inventory_item' in input else None dialogue_option = input.get( 'dialogue_option') if 'dialogue_option' in input else None shop_option = input.get( 'shop_option') if 'shop_option' in input else None unequip_item = input.get('slot') if 'slot' in input else None # If players turned and it's their turn to move if action == 'move' and self.game_state == GameStates.PLAYERS_TURN: # Calculate where they should move dx, dy = input.get('move') destination_x = self.player.x + dx destination_y = self.player.y + dy # TODO: This is where you hid the noclip check. Fix this for release #if not self.game_map.is_blocked(destination_x, destination_y): if True: # If they're not about to walk into a wall, check for enemies at the destination potential_collision_list = self.entities.get_sublist( lambda ent: ent.x == destination_x and ent.y == destination_y and ent.blocks) target = potential_collision_list[ 0] if potential_collision_list else None if target and target.state == AIStates.HOSTILE: # If there are enemies, attack them self.player.get_component("Fighter").attack(target) self.game_state = GameStates.ENEMY_TURN elif target and target.state == AIStates.FRIENDLY: self.previous_game_state = self.game_state self.player_target = target self.game_state = GameStates.DIALOGUE else: # If there are not enemies, move and mark FOV for recomputation self.player.move(dx, dy, self.game_map) self.fov_recompute = True self.game_map.compute_dijkstra_map([self.player], 'player', True) self.game_state = GameStates.ENEMY_TURN # If the player grabs something, check if there is an object at their feet, and either have them pick it up (if it's an Item) or add it to their wallet (if it's money) elif action == 'grab' and self.game_state == GameStates.PLAYERS_TURN: for item in self.entities.get_sublist( lambda entity: (entity.has_component("Item") or entity. has_component("Money")) and entity.x == self.player.x and entity.y == self.player.y): if item.has_component("Money"): self.player.get_component("Fighter").pick_up_money( item) else: self.player.get_component("Inventory").add_item(item) self.entities.remove_entity(item) self.game_state = GameStates.ENEMY_TURN # Open up the inventory menu elif action == 'inventory' and inventory_item is None: self.previous_game_state = self.game_state self.game_state = GameStates.INVENTORY_OPEN # Open up the equipped menu elif action == 'equipped': self.previous_game_state = self.game_state self.game_state = GameStates.EQUIPPED_OPEN elif action == 'unequip' and self.game_state == GameStates.EQUIPPED_OPEN: self.player.get_component("Inventory").unequip_slot( unequip_item) # if the player has selected an inventory item to use, get the item object, and equip it if it's vgear, or use it if it's a consumable (like a potion) elif inventory_item is not None and self.previous_game_state != GameStates.PLAYER_DEAD and inventory_item < len( self.player.get_component("Inventory").items): item_entity = self.player.get_component( "Inventory").items[inventory_item] if ItemType(item_entity.get_component( "Item").item_type) != ItemType.NONE: self.player.get_component("Inventory").equip_item( item_entity) else: print("In the else") if item_entity.get_component("Item").use(self.player): self.player.get_component("Inventory").remove_item( item_entity) # if the player is in dialogue, provide the dialogue option to the target's Character object elif dialogue_option is not None: dialogue_response = self.player_target.get_component( "Character").talk(dialogue_option) if dialogue_response.shop: self.game_state = GameStates.SHOPPING # if the player attempts to go down some stairs, make sure they're on stairs, then build a new map and clear the console elif action == 'go_down' and self.game_state == GameStates.PLAYERS_TURN: stairs_candidates = self.entities.get_sublist( lambda entity: entity.x == self.player.x and entity.y == self.player.y and entity.has_component("Stairs")) if stairs_candidates: self.build_map( stairs_candidates[0].get_component("Stairs").floor) libtcod.console_clear(self.con) # Save the game elif action == 'save': save_game(self.player, self.entities, self.game_map, self.message_log, self.game_state) # if the player draws their gun, change to a player shoot state and await gunfire elif self.game_state == GameStates.PLAYERS_TURN and action == 'gun': if (self.player.get_component("Inventory").slot_filled( "RANGED")): self.previous_game_state = self.game_state self.game_state = GameStates.PLAYER_SHOOT self.message_log.add_message( Message( "Taking aim. Click on your target, or e to holster" )) else: self.message_log.add_message( Message("No ranged weapon equipped!")) # if the player already has their gun drawn and presses the draw button, holster it instead elif self.game_state == GameStates.PLAYER_SHOOT and action == 'holster': self.game_state = self.previous_game_state self.message_log.add_message(Message("Holstered your weapon")) # if the player has their gun drawn and clicks on a target, check if there is line of sight # and if so, shoot the target. This sets the AI to hostile if it isn't already (this should be handled by Fighter) elif self.game_state == GameStates.PLAYER_SHOOT and self.mouse.lbutton_pressed: target = get_shoot_target(self.mouse, self.entities, self.fov_map) if (target): line_of_sight = draw_line((self.player.x, self.player.y), (target.x, target.y)) if not [ space for space in line_of_sight if self.game_map.is_blocked(space[0], space[1]) ]: self.player.get_component("Fighter").ranged_attack( target) target.state = AIStates.HOSTILE self.game_state = GameStates.ENEMY_TURN else: self.message_log.add_message( Message("You don't have a clear line of sight!")) # if the player right clicks something, get open up the inspect menu for that target elif self.mouse.rbutton_pressed and self.game_state != GameStates.INSPECT_OPEN: target = get_shoot_target(self.mouse, self.entities, self.fov_map, False) if (target): self.player_target = target self.previous_game_state = self.game_state self.game_state = GameStates.INSPECT_OPEN # If the player is buying something, they make the purchase elif action == 'buy' and shop_option is not None: target.get_component("Shop").purchase(shop_option, self.player) elif action == 'status': self.previous_game_state = self.game_state self.game_state = GameStates.STATUS # Exit the game if action == 'exit' and (self.game_state in [ GameStates.INVENTORY_OPEN, GameStates.DIALOGUE, GameStates.EQUIPPED_OPEN, GameStates.SHOPPING, GameStates.INSPECT_OPEN, GameStates.STATUS ]): self.game_state = self.previous_game_state elif action == 'exit': return True # Set the game to fullscreen if action == 'fullscreen': libtcod.console_set_fullscreen( not libtcod.console_is_fullscreen()) # cull_dead returns true if the player is dead, so this conditional calls it to cull the dead, and then # checks if the game is over if self.cull_dead(): self.game_state = GameStates.PLAYER_DEAD # when it's the AI's turn, find every entity that has AI and move it (if it's hostile) if self.game_state == GameStates.ENEMY_TURN: for entity in self.entities.get_entity_set(): if entity.has_component( "AI") and entity.state == AIStates.HOSTILE: entity.get_component("AI").take_turn( self.player, self.fov_map, self.game_map, self.entities) if self.cull_dead(): self.game_state = GameStates.PLAYER_DEAD if entity.has_component("StatusContainer"): entity.get_component("StatusContainer").tick_clocks() for status in entity.get_component( "StatusContainer").get_statuses(): status_mapping[status](entity, self.entities, self.game_map) if self.game_state != GameStates.PLAYER_DEAD: self.player.get_component("StatusContainer").tick_clocks() for status in self.player.get_component( "StatusContainer").get_statuses(): status_mapping[status](self.player, self.entities, self.game_map) self.game_map.compute_dijkstra_map( self.entities.get_sublist( lambda x: x.name != "Ascetic"), "enemies") self.game_state = GameStates.PLAYERS_TURN # TODO: need a check somewhere around here to tick condition clocks, and then to apply conditions if action == 'restart': libtcod.console_clear(self.con) self.initialize_game()
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): # FOV init fov_recompute = True fov_map = initialize_fov(game_map) # Game State previous_game_state = game_state # Keyboard + Mouse vars key = libtcod.Key() mouse = libtcod.Mouse() # Targeting system targeting_item = None # Game Loop while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event( libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse) # Rendering if fov_recompute: recompute_fov(fov_map, player.x, player.y, constants['fov_algorithm'], constants['fov_radius'], constants['fov_light_walls']) render_all(con, panel, entities, player, constants['screen_width'], constants['screen_height'], game_map, fov_map, fov_recompute, message_log, 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_stat = action.get("level_up_stat") show_character_screen = action.get("show_character_screen") fullscreen = action.get("fullscreen") exit_game = action.get("exit") left_click = mouse_action.get('left_click') right_click = mouse_action.get('right_click') # Managing player's turn player_turn_results = [] # Handling player waiting if wait: game_state = GameStates.ENEMY_TURN # Handling player movement and fighting elif move and game_state == GameStates.PLAYERS_TURN: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): entities_in_tile = game_map.get_entities( player.x + dx, player.y + dy) if not any(entity.fighter for entity in entities_in_tile): player.move(dx, dy, game_map) fov_recompute = True else: for entity in entities_in_tile: if entity.fighter: target = entity # Avoid attacking items xD if not target.item: player_attack_results = player.fighter.attack(target) player_turn_results.extend(player_attack_results) game_state = GameStates.ENEMY_TURN # Handling picking up items elif pickup and game_state == GameStates.PLAYERS_TURN: entities_in_tile = game_map.get_entities(player.x, player.y) picked = False for entity in entities_in_tile: if entity.item: item = entity pickup_results = player.inventory.add_item(item) player_turn_results.extend(pickup_results) picked = True break if not picked: message_log.add_message( Message('There is nothing to pick up here !', libtcod.yellow)) # Handling inventory if show_inventory: previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len( player.inventory.items): item = player.inventory.items[inventory_index] 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 drop_inventory: previous_game_state = game_state game_state = GameStates.DROP_INVENTORY # Handling 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}) # Handling stairs 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, constants, message_log) 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)) # Handling stats increase when leveling up if level_up_stat: if level_up_stat == "hp": player.fighter.base_max_hp += 20 player.fighter.hp = player.fighter.max_hp elif level_up_stat == "str": player.fighter.base_power += 1 elif level_up_stat == "def": player.fighter.base_defense += 1 game_state = previous_game_state # Handling character screen if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN # Handling player turn results for result in player_turn_results: message = result.get('message') dead_entity = result.get('dead') xp = result.get('xp') item_added = result.get('item_added') item_consumed = result.get("consumed") item_dropped = result.get("item_dropped") equip = result.get("equip") targeting = result.get("targeting") targeting_cancelled = result.get("targeting_cancelled") 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, game_map) message_log.add_message(message) if xp: leveled_up = player.level.add_xp(xp) if leveled_up: message_log.add_message( Message( 'Your battle skills grow stronger! You reached level {0}' .format(player.level.current_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if item_added: entities.remove(item_added) game_map.remove_entity(item_added.x, item_added.y, item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_map.set_entity(item_dropped.x, item_dropped.y, item_dropped) game_state = GameStates.ENEMY_TURN if equip: equip_results = player.equipement.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: # We’re setting the game state to the player’s turn rather than the actual previous state. # This is so that cancelling the targeting will not reopen the inventory screen. previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled.')) # Managing enemy's turn if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = [] enemy_attack_results = entity.ai.take_turn( player, entities, fov_map, game_map) enemy_turn_results.extend(enemy_attack_results) for result in enemy_turn_results: message = result.get('message') dead_entity = 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, game_map) 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 if fullscreen: libtcod.console_set_fullscreen(fullscreen) if exit_game: 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) # libtcod.console_clear(con) return True
def main(): screen_width = 80 screen_height = 50 map_width = 80 map_height = 45 room_max_size = 10 room_min_size = 6 max_rooms = 30 colors = { 'dark_wall': libtcod.Color(0, 0, 100), 'dark_ground': libtcod.Color(50, 50, 150) } player = Entity(int(screen_width / 2), int(screen_height / 2), '@', libtcod.white) npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@', libtcod.yellow) entities = [npc, player] libtcod.console_set_custom_font( 'assets/arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD) libtcod.console_init_root(screen_width, screen_height, 'Babbys furst gam', False) con = libtcod.console_new(screen_width, screen_height) game_map = GameMap(map_width, map_height) game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player) key = libtcod.Key() mouse = libtcod.Mouse() while not libtcod.console_is_window_closed(): libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse) render_all(con, entities, game_map, screen_width, screen_height, colors) libtcod.console_flush() clear_all(con, entities) action = handle_keys(key) move = action.get('move') exit = action.get('exit') fullscreen = action.get('fullscreen') if move: dx, dy = move if not game_map.is_blocked(player.x + dx, player.y + dy): player.move(dx, dy) if exit: return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants): key = libtcod.Key() mouse = libtcod.Mouse() fov_map = initiliase_fov(game_map) fov_recompute = True 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, colours, game_state) fov_recompute = False libtcod.console_flush() clear_all(con, entities) action = handle_keys(key, game_state) player_turn_results = [] if action.get('move') and game_state == GameStates.PLAYER_TURN: dx, dy = action.get('move') if not game_map.is_blocked(player.x + dx, player.y + dy): target = is_blocked_by_entity(player.x + dx, player.y + dy, entities) if target and target.fighter: atk_res = player.fighter.attack(target) player_turn_results.extend(atk_res) else: player.move(dx, dy) fov_recompute = True game_state = GameStates.ENEMY_TURN if action.get('wait'): game_state = GameStates.ENEMY_TURN if action.get('pickup') and game_state == GameStates.PLAYER_TURN: for entity in entities: if entity.item and dst_entities(entity, player) < 2: 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 action.get('show_inventory'): previous_game_state = game_state game_state = GameStates.SHOW_INVENTORY if (action.get('inventory_index') is not None and previous_game_state != game_state.PLAYER_DEAD and player.inventory.items and action.get('inventory_index') < len(player.inventory.items)): item = player.inventory.items[action.get('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 action.get('drop_inventory'): previous_game_state = game_state game_state = GameStates.DROP_INVENTORY if game_state == GameStates.TARGETING: mouse_action = handle_mouse(mouse) l_click = mouse_action.get('left_click') r_click = mouse_action.get('right_click') if l_click: target_x, target_y = l_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_coordinates=(target_x, target_y), target_tile=game_map.tiles[target_x][target_y]) player_turn_results.extend(item_use_results) elif r_click: player_turn_results.append({'targeting_cancelled': True}) if action.get('take_stairs') and game_state == GameStates.PLAYER_TURN: for entity in entities: if entity.stairs and entity.x == player.x and entity.y == player.y: entities = game_map.next_floor(player, message_log, constants) fov_map = initiliase_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 action.get('level_up'): if action.get('level_up') == 'hp': player.fighter.base_max_hp += 20 player.fighter.hp += 20 elif action.get('level_up') == 'str': player.fighter.base_power += 1 elif action.get('level_up') == 'def': player.fighter.base_defense += 1 game_state = previous_game_state if action.get('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 action.get('show_character_screen'): previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if action.get('fullscreen'): libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for p_turn_res in player_turn_results: message = p_turn_res.get('message') dead_entity = p_turn_res.get('dead') item_added = p_turn_res.get('item_added') item_consumed = p_turn_res.get('consumed') item_droppred = p_turn_res.get('item_dropped') targeting = p_turn_res.get('targeting') targeting_cancelled = p_turn_res.get('targeting_cancelled') xp = p_turn_res.get('xp_given') equip = p_turn_res.get('equip') 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_droppred: entities.append(item_droppred) game_state = GameStates.ENEMY_TURN if equip: equip_res = player.equipment.toggle_equip(equip) for equip_result in equip_res: 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_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled.')) if targeting: previous_game_state = GameStates.PLAYER_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message(Message(f'You gain {xp} experience points.')) if leveled_up: message_log.add_message(Message( f'You feel stronger! You reached level {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_res = entity.ai.take_turn(player, fov_map, game_map, entities) for en_turn_res in enemy_turn_res: message = en_turn_res.get('message') dead_entity = en_turn_res.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYER_TURN
player.y + player.last_dy, game_objects) ##print(str(player.x + player.last_dx) +" "+ str(player.y + player.last_dy)) if not get_object is None: ##print(str(get_object)) if isinstance(get_object, NPC): if not get_object.dialog_dict is None: npc_dialog(get_object, player, "main") elif action == terminal.TK_S: ml.log_message(lorem + " " + str(test_count)) elif action == terminal.TK_M: dialog_tree = DialogTree() npc_dialog(dialog_tree, 'main') control = handle_keys(action) move = control.get('move') if move: dx, dy = move new_x = player.x + dx new_y = player.y + dy if game_map.is_transport(new_x, new_y): transport = game_map.spaces[new_x][new_y].transport load_map(terminal, player, game_objects, game_map, transport.new_map_index, dx + transport.dx, dy + transport.dy) elif not game_map.is_blocked(new_x, new_y): game_map.unblock(player.x, player.y) player.move(dx, dy)
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.max_hp += 20 player.fighter.hp += 20 elif level_up == 'str': player.fighter.power += 1 elif level_up == 'def': player.fighter.defense += 1 elif level_up == 'sp': player.fighter.max_sp += 20 elif level_up == 'mp': player.fighter.max_mp += 10 game_state = previous_game_state if show_character_screen: previous_game_state = game_state game_state = GameStates.CHARACTER_SCREEN if game_state == GameStates.TARGETING: if left_click: target_x, target_y = left_click item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y) player_turn_results.extend(item_use_results) elif right_click: player_turn_results.append({'targeting_cancelled': True}) if exit: if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN): game_state = previous_game_state elif game_state == GameStates.TARGETING: player_turn_results.append({'targeting_cancelled': True}) else: save_game(player, entities, game_map, message_log, game_state) return True if fullscreen: libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen()) for player_turn_result in player_turn_results: message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') item_added = player_turn_result.get('item_added') item_consumed = player_turn_result.get('consumed') item_dropped = player_turn_result.get('item_dropped') targeting = player_turn_result.get('targeting') targeting_cancelled = player_turn_result.get('targeting_cancelled') xp = player_turn_result.get('xp') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if item_added: entities.remove(item_added) game_state = GameStates.ENEMY_TURN if item_consumed: game_state = GameStates.ENEMY_TURN if item_dropped: entities.append(item_dropped) game_state = GameStates.ENEMY_TURN if targeting: previous_game_state = GameStates.PLAYERS_TURN game_state = GameStates.TARGETING targeting_item = targeting message_log.add_message(targeting_item.item.targeting_message) if targeting_cancelled: game_state = previous_game_state message_log.add_message(Message('Targeting cancelled')) if xp: leveled_up = player.level.add_xp(xp) message_log.add_message( Message('You gain {0} experience points.'.format(xp))) if leveled_up: message_log.add_message( Message( 'Your battle skills grow stronger! You reached level {0}' .format(player.level.current_level) + '!', libtcod.yellow)) previous_game_state = game_state game_state = GameStates.LEVEL_UP if game_state == GameStates.ENEMY_TURN: for entity in entities: if entity.ai: enemy_turn_results = entity.ai.take_turn( player, fov_map, game_map, entities) for enemy_turn_result in enemy_turn_results: message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') if message: message_log.add_message(message) if dead_entity: if dead_entity == player: message, game_state = kill_player(dead_entity) else: message = kill_monster(dead_entity) message_log.add_message(message) if game_state == GameStates.PLAYER_DEAD: break if game_state == GameStates.PLAYER_DEAD: break else: game_state = GameStates.PLAYERS_TURN