def refresh_screen(mygame, player, menu): mygame.clear_screen() # print(Utils.magenta_bright(f"\t\t~+~ Welcome to {mygame.name} ~+~")) mygame.display_player_stats() mygame.display_board() if player.inventory.size() > 0: # If inventory is not empty print it items_by_type = {} for item_name in player.inventory.items_name(): item = player.inventory.get_item(item_name) if item.type in items_by_type.keys(): items_by_type[item.type]['cumulated_size'] += item.size() else: items_by_type[item.type] = { 'cumulated_size': item.size(), 'model': item.model, 'name': item.name, } count = 1 for k in items_by_type.keys(): print(f" {items_by_type[k]['model']} : \ {items_by_type[k]['cumulated_size']} ", end='') count += 1 if count == 5: count = 0 print("\n", end='') print("\n", end='') print( Utils.yellow_dim('\nWhere should ') + Utils.cyan_bright(player.name) + Utils.yellow_dim(' go?')) mygame.display_menu(menu) Utils.debug(f"Player stored position is ({player.pos[0]},{player.pos[1]})")
def refresh_screen(): global g global notifications global current_menu global level_2_turns_left g.clear_screen() g.display_player_stats() g.display_board() if g.current_level == 2: print( Utils.cyan_bright(f"Inventory ({g.player.inventory.size()}/{g.player.inventory.max_size}) ") + Utils.green_bright(f"Turns left: {level_2_turns_left} ") ) else: print( Utils.cyan_bright(f"Inventory ({g.player.inventory.size()}/{g.player.inventory.max_size}) ") ) if g.player.inventory.size() > 0: # If inventory is not empty print it items_by_type = {} for item_name in g.player.inventory.items_name(): item = g.player.inventory.get_item(item_name) if item.type in items_by_type.keys(): items_by_type[item.type]['cumulated_size'] += item.size() else: items_by_type[item.type] = {'cumulated_size':item.size(),'model':item.model,'name':item.name} count = 1 for k in items_by_type.keys(): print(f" {items_by_type[k]['model']} : {items_by_type[k]['cumulated_size']} ",end='') count += 1 if count == 5: count = 0 print("\n",end='') print("\n",end='') # Then we display the menu g.display_menu(current_menu,Constants.ORIENTATION_VERTICAL,15) # And finally the notifications for n in notifications: print(n)
def redraw(): global g global chasing g.clear_screen() g.display_player_stats() print(f"Position: {g.player.pos[0]},{g.player.pos[1]}") # if not DEBUG: g.display_board() if chasing: Utils.print_white_on_red("Guard is chasing!!!")
def __init__(self, name='Game', boards={}, menu={}, current_level=None): self.name = name self._boards = boards self._menu = menu self.current_level = current_level self.player = None self.state = Constants.RUNNING self._config_parsers = None self._configuration = None self.object_library = [] Utils.init_term_colors()
def switch_edit_mode(): global edit_mode edit_mode = not edit_mode if edit_mode: game.update_menu_entry( "main", Utils.white_bright("j/i/k/l"), Utils.green_bright("Place") + " the current object and then move cursor Left/Up/Down/Right", ) game.update_menu_entry( "main", Utils.white_bright("0 to 9"), Utils.green_bright("Select") + " an item in history to be the current item", ) else: game.update_menu_entry( "main", Utils.white_bright("j/i/k/l"), "Move cursor Left/Up/Down/Right and " + Utils.red_bright("Delete") + " anything that was at destination.", ) game.update_menu_entry( "main", Utils.white_bright("0 to 9"), Utils.red_bright("Remove") + " an item from history", )
def first_use(): global config_dir global editor_config_dir global base_config_dir global default_map_dir global game print( Utils.yellow_bright("Configuration wizard (fresh install or update)")) print( "You may see that wizard because hgl-editor was updated with new settings.\n" "Please check that everything is fine (your previous values are showned as " "default values)\n") if not os.path.exists(config_dir): os.makedirs(config_dir) if not os.path.exists(os.path.join(base_config_dir, "editor", "maps")): os.makedirs(os.path.join(base_config_dir, "editor", "maps")) if not os.path.exists(editor_config_dir): os.makedirs(editor_config_dir) print( "We need to set up the default directory where we are going to save maps.", f"Default is {default_map_dir}", ) new_default = str(input("Default maps directory: ")) while (not os.path.exists(new_default) or not os.path.isdir(new_default) or not os.path.isabs(new_default)) and new_default != "": print( Utils.red( "The path to directory needs to exists and be absolute.")) new_default = str(input("Default maps directory: ")) if new_default != "": default_map_dir = new_default if not os.path.exists(os.path.join(config_dir, "directories.json")): with open(os.path.join(config_dir, "directories.json"), "w") as fp: fp.write(f'["{default_map_dir}","hac-maps","maps"]') if not os.path.exists(os.path.join(editor_config_dir, "settings.json")): game.create_config("settings") game.config("settings")["directories"] = [ default_map_dir, "hac-maps", "maps" ] game.config("settings")["config_file_version"] = 10100 game.config("settings")["enable_partial_display"] = True game.config("settings")["partial_display_viewport"] = [10, 30] game.config("settings")["menu_mode"] = "full" game.config("settings")["last_used_board_parameters"] = { "name": None, "width": None, "height": None, } game.config("settings")["object_library"] = []
def generate_trap(b, row, column): # Here we just take a chance and put a trap here. # but we should actually explore the rest of the column for other suitable place if b.available_traps > 0: chance = int(b.max_traps_number / b.size[0] * 100) if random.randint(0, 100) >= 100 - chance: if random.choice([True, False]): trap = Wall( model=bg_color + traps_color + Graphics.Blocks.QUADRANT_UPPER_LEFT_AND_LOWER_RIGHT + Graphics.Blocks.QUADRANT_UPPER_RIGHT_AND_LOWER_LEFT + Graphics.Style.RESET_ALL, type="trap.hfire", ) trap.fire_timer = random.uniform(1.0, 4.0) b.place_item(trap, row, column) if isinstance(b.item(row, column - 1), BoardItemVoid): trap.fdir = Constants.LEFT else: trap.fdir = Constants.RIGHT else: trap = Wall( model=bg_color + Utils.red_bright( Graphics.Blocks. QUADRANT_UPPER_RIGHT_AND_LOWER_LEFT_AND_LOWER_RIGHT # noqa E501 + Graphics.Blocks. QUADRANT_UPPER_LEFT_AND_LOWER_LEFT_AND_LOWER_RIGHT # noqa E501 ) + Graphics.Style.RESET_ALL, type="trap.vfire", ) trap.fire_timer = random.uniform(2.0, 6.0) b.place_item(trap, row, column) trap.fdir = Constants.UP b.available_traps -= 1
def refresh_screen(): global g global notifications g.clear_screen() g.display_player_stats() g.display_board() print( Utils.cyan_bright( f"Inventory ({g.player.inventory.size()}/{g.player.inventory.max_size}) " )) if g.player.inventory.size() > 0: # If inventory is not empty print it items_by_type = {} for item_name in g.player.inventory.items_name(): item = g.player.inventory.get_item(item_name) if item.type in items_by_type.keys(): items_by_type[item.type]['cumulated_size'] += item.size() else: items_by_type[item.type] = { 'cumulated_size': item.size(), 'model': item.model, 'name': item.name } count = 1 for k in items_by_type.keys(): print( f" {items_by_type[k]['model']} : {items_by_type[k]['cumulated_size']} ", end='') count += 1 if count == 5: count = 0 print("\n", end='') print("\n", end='') for n in notifications: print(n)
def activate_portal(params): global g level = params[0] if level == 1: if g.current_board().item(3, 3).model == Sprites.CYCLONE: # That logic is just a placeholder for the moment, ultimately it will lead to the next level g.clear_screen() print(Utils.green_bright("CONGRATULATIONS\n\nYOU WIN!")) exit()
def portal_fairy_behavior(): # That function is our portal fairy controller. # It works a bit like the whale controller: look around for a player, offer a dialog and ultimately open the portal. global g global current_menu global fairy_gold fairy = g.current_board().get_movables(type='fairy') portal = g.current_board().get_immovables(type='portal') if g.player in g.neighbors(1,fairy[0]): if portal[0].model == g.current_board().ui_board_void_cell: # If the player is around the fairy, then we set the menu to the portal fairy dialog current_menu = 'portal_fairy_dialog' # And pause the other NPC to refresh the screen g.pause() # Before refreshing we update the dialog update_fairy_dialog() refresh_screen() # If the player has gold in his inventory we give the possibility to give it to the fairy. money_bags = g.player.inventory.search('Money') # Now we want to get the answer immediately, we don't want that function to return. # Note: This is going to be a problem when we multithread this code. But it's going to be a good exercise. key = Utils.get_key() if key == '1': print(Sprites.FAIRY+' That is too bad, good bye.') current_menu = 'default' refresh_screen() elif key == '2': fairy_gold += money_bags[0].value g.player.inventory.delete_item(money_bags[0].name) elif key == '3': fairy_gold += money_bags[0].value fairy_gold += money_bags[1].value g.player.inventory.delete_item(money_bags[0].name) g.player.inventory.delete_item(money_bags[1].name) elif key == '4': for b in money_bags: fairy_gold += b.value g.player.inventory.delete_item(b.name) update_fairy_dialog() refresh_screen() if fairy_gold >= 300: refresh_screen() print(Sprites.FAIRY+' Great! Thank you!! Now let\'s do some magic.') print(Utils.BLACK_SQUARE+Sprites.CYCLONE+' By my powers, cometh forth dimensional portal'+Sprites.CYCLONE) portal[0].model = Sprites.CYCLONE portal[0].set_overlappable(False) time.sleep(2) current_menu = 'default' refresh_screen() elif fairy_gold < 300 and (key == '1' or key == '2' or key == '3' or key == '4'): print(Sprites.FAIRY+' Thank you, that is a good start but I still don\'t have enough gold to open a portal.') # When we are finished we un-pause the game g.start() else: print(Sprites.FAIRY+' I have already opened the only portal I could in this world!')
def switch_edit_mode(): global edit_mode edit_mode = not edit_mode if edit_mode: game.update_menu_entry('main',Utils.white_bright('j/i/k/l'),Utils.green_bright('Place')+' the current object and then move cursor Left/Up/Down/Right') game.update_menu_entry('main',Utils.white_bright('0 to 9'),Utils.green_bright('Select')+' an item in history to be the current item') else: game.update_menu_entry('main',Utils.white_bright('j/i/k/l'),'Move cursor Left/Up/Down/Right and '+Utils.red_bright('Delete')+' anything that was at destination.') game.update_menu_entry('main',Utils.white_bright('0 to 9'),Utils.red_bright('Remove')+' an item from history')
def clear_and_go(direction): global is_modified global game new_x = game.player.pos[0] new_y = game.player.pos[1] if direction == Constants.DOWN: new_x += 1 elif direction == Constants.UP: new_x -= 1 elif direction == Constants.LEFT: new_y -= 1 elif direction == Constants.RIGHT: new_y += 1 if new_x < 0 or new_y < 0 or new_x > (game.current_board().size[1]-1) or new_y > (game.current_board().size[0]-1): Utils.warn(f"Cannot remove anything at [{new_x},{new_y}] as it is out of bound.") else: game.current_board().clear_cell(new_x,new_y) game.move_player(direction,1) is_modified = True
def create_board_wizard(): global game global is_modified game.clear_screen() print( Utils.blue_bright("\t\tNew board") ) print("First we need some information on your new board:") name = str( input('Name: ') ) width = int( input_digit('Width (in number of cells): ') ) height = int( input_digit('Height (in number of cells): ') ) game.add_board(1, Board(name=name,size=[width,height], ui_borders=Utils.WHITE_SQUARE,ui_board_void_cell=Utils.BLACK_SQUARE) ) is_modified=True
def create_board_wizard(): global game global is_modified global current_file global default_map_dir game.clear_screen() print(Utils.blue_bright("\t\tNew board")) print("First we need some information on your new board:") name, width, height = None, None, None if game.config( "settings")["last_used_board_parameters"]["name"] is not None: name = game.config("settings")["last_used_board_parameters"]["name"] else: name = "New Board" name = str(input(f"Name (default: {name}): ")) or name if game.config( "settings")["last_used_board_parameters"]["width"] is not None: width = game.config("settings")["last_used_board_parameters"]["width"] else: width = 20 width = int( input_digit(f"Width (in number of cells) (default: {width}): ") or width) if game.config( "settings")["last_used_board_parameters"]["height"] is not None: height = game.config( "settings")["last_used_board_parameters"]["height"] else: height = 20 height = int( input_digit(f"Height (in number of cells) (default: {height}): ") or height) game.add_board( 1, Board( name=name, size=[width, height], ui_borders=Utils.WHITE_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE, ), ) is_modified = True current_file = os.path.join(default_map_dir, name.replace(" ", "_") + ".json") game.config("settings")["last_used_board_parameters"] = { "name": name, "width": width, "height": height, } if game.get_board(1).size[0] > 20 or game.get_board(1).size[1] > 20: game.enable_partial_display = True game.partial_display_viewport = [10, 10]
def activate_portal(params): global g level = params[0] if level == 1: if g.current_board().item(3,3).model == Sprites.CYCLONE: # That logic is just a placeholder for the moment, ultimately it will lead to the next level g.clear_screen() print( Utils.green_bright("CONGRATULATIONS\n\nYOU WIN!") ) exit() elif level == 2: g.clear_screen() print_animated(f"{Sprites.UNICORN_FACE}: Congratulations {g.player.name}, you found the entrance to a world of riches!\n{Sprites.UNICORN_FACE}: However, your time is limited and you will need to grab as much treasures as you can in 20 moves only!\n{Sprites.UNICORN_FACE}: Good luck!") input("\n\n(Hit ENTER when you are ready to enter the world of riches)") g.player.inventory.max_size += 1500 g.change_level(2)
def model_picker(): global game while True: game.clear_screen() print("What kind of model do you want (you can edit that later)?\n1 - Colored squares and rectangles\n2 - Sprites\n3 - Set your own string of character(s)") choice = str( Utils.get_key() ) if choice == '1': picked = game.get_menu_entry('graphics_utils',color_picker()) if picked != None: return picked['data'] if choice == '2': picked = game.get_menu_entry('graphics_sprites',sprite_picker()) if picked != None: return picked['data'] if choice == '3': return str( input('Enter your string now: ') )
def model_picker(): global game while True: game.clear_screen() print("What kind of model do you want (you can edit that later)?\n" "1 - Colored squares and rectangles\n" "2 - Sprites\n" "3 - Set your own string of character(s)") choice = str(Utils.get_key()) if choice == "1": picked = game.get_menu_entry("graphics_utils", color_picker()) if picked is not None: return picked["data"] if choice == "2": picked = game.get_menu_entry("graphics_sprites", sprite_picker()) if picked is not None: return picked["data"] if choice == "3": return str(input("Enter your string now: "))
g = Game() b = g.load_board('hac-maps/kneighbors.json',1) g.player = Player(model=Sprites.FLYING_SAUCER,name='player') g.change_level(1) key = None while True: if key == 'w': g.move_player(Constants.UP,1) elif key == 's': g.move_player(Constants.DOWN,1) elif key == 'a': g.move_player(Constants.LEFT,1) elif key == 'd': g.move_player(Constants.RIGHT,1) elif key == 'q': break g.clear_screen() g.display_board() for i in g.neighbors(1): print(f'Player: {i.name} ({i.pos[0]},{i.pos[1]})') for i in g.neighbors(1, g.current_board().item(7,7) ): print(f'NPC: {i.name} ({i.pos[0]},{i.pos[1]})') key = Utils.get_key()
def load_board(self, filename, lvl_number=0): """Load a saved board Load a Board saved on the disk as a JSON file. This method creates a new Board object, populate it with all the elements (except a Player) and then return it. If the filename argument is not an existing file, the open function is going to raise an exception. This method, load the board from the JSON file, populate it with all BoardItem included, check for sanity, init the board with BoardItemVoid and then associate the freshly created board to a lvl_number. It then create the NPCs and add them to the board. :param filename: The file to load :type filename: str :param lvl_number: The level number to associate the board to. Default is 0. :type lvl_number: int :returns: a newly created board (see :class:`gamelib.Board.Board`) Example:: mynewboard = game.load_board( 'awesome_level.json', 1 ) game.change_level( 1 ) """ with open(filename, 'r') as f: data = json.load(f) local_board = Board() data_keys = data.keys() if "name" in data_keys: local_board.name = data["name"] if 'size' in data_keys: local_board.size = data['size'] if 'player_starting_position' in data_keys: local_board.player_starting_position = data[ 'player_starting_position'] if 'ui_border_top' in data_keys: local_board.ui_border_top = data['ui_border_top'] if 'ui_border_bottom' in data_keys: local_board.ui_border_bottom = data['ui_border_bottom'] if 'ui_border_left' in data_keys: local_board.ui_border_left = data['ui_border_left'] if 'ui_border_right' in data_keys: local_board.ui_border_right = data['ui_border_right'] if 'ui_board_void_cell' in data_keys: local_board.ui_board_void_cell = data['ui_board_void_cell'] # Now we need to recheck for board sanity local_board.check_sanity() # and re-initialize the board (mainly to attribute a new model to the void cells as it's not dynamic). local_board.init_board() # Then add board to the game self.add_board(lvl_number, local_board) # Define an internal function to transform directions string into constants def _string_to_constant(s): if type(s) is int: return s elif s == "UP": return Constants.UP elif s == "DOWN": return Constants.DOWN elif s == "RIGHT": return Constants.RIGHT elif s == "LEFT": return Constants.LEFT elif s == "DRUP": return Constants.DRUP elif s == "DRDOWN": return Constants.DRDOWN elif s == "DLDOWN": return Constants.DLDOWN elif s == "DLUP": return Constants.DLUP def _ref2obj(ref): obj_keys = ref.keys() local_object = BoardItemVoid() if 'Wall' in ref['object']: local_object = Structures.Wall() elif 'Treasure' in ref['object']: local_object = Structures.Treasure() if 'value' in obj_keys: local_object.value = ref['value'] if 'size' in obj_keys: local_object._size = ref['size'] elif 'GenericStructure' in ref['object']: local_object = Structures.GenericStructure() if 'value' in obj_keys: local_object.value = ref['value'] if 'size' in obj_keys: local_object._size = ref['size'] if 'pickable' in obj_keys: local_object.set_pickable(ref['pickable']) if 'overlappable' in obj_keys: local_object.set_overlappable(ref['overlappable']) elif 'Door' in ref['object']: local_object = Structures.Door() if 'value' in obj_keys: local_object.value = ref['value'] if 'size' in obj_keys: local_object._size = ref['size'] if 'pickable' in obj_keys: local_object.set_pickable(ref['pickable']) if 'overlappable' in obj_keys: local_object.set_overlappable(ref['overlappable']) if 'restorable' in obj_keys: local_object.set_restorable(ref['restorable']) elif 'GenericActionableStructure' in ref['object']: local_object = Structures.GenericActionableStructure() if 'value' in obj_keys: local_object.value = ref['value'] if 'size' in obj_keys: local_object._size = ref['size'] if 'pickable' in obj_keys: local_object.set_pickable(ref['pickable']) if 'overlappable' in obj_keys: local_object.set_overlappable(ref['overlappable']) elif 'NPC' in ref['object']: local_object = NPC() if 'value' in obj_keys: local_object.value = ref['value'] if 'size' in obj_keys: local_object._size = ref['size'] if 'hp' in obj_keys: local_object.hp = ref['hp'] if 'max_hp' in obj_keys: local_object.max_hp = ref['max_hp'] if 'step' in obj_keys: local_object.step = ref['step'] if 'remaining_lives' in obj_keys: local_object.remaining_lives = ref['remaining_lives'] if 'attack_power' in obj_keys: local_object.attack_power = ref['attack_power'] if 'actuator' in obj_keys: if 'RandomActuator' in ref['actuator']['type']: local_object.actuator = RandomActuator(moveset=[]) if 'moveset' in ref['actuator'].keys(): for m in ref['actuator']['moveset']: local_object.actuator.moveset.append( _string_to_constant(m)) elif 'PathActuator' in ref['actuator']['type']: local_object.actuator = PathActuator(path=[]) if 'path' in ref['actuator'].keys(): for m in ref['actuator']['path']: local_object.actuator.path.append( _string_to_constant(m)) # Now what remains is what is common to all BoardItem if not isinstance(local_object, BoardItemVoid): if 'name' in obj_keys: local_object.name = ref['name'] if 'model' in obj_keys: local_object.model = ref['model'] if 'type' in obj_keys: local_object.type = ref['type'] return local_object # Now load the library if any if 'library' in data_keys: self.object_library = [] for e in data['library']: self.object_library.append(_ref2obj(e)) # Now let's place the good stuff on the board if 'map_data' in data_keys: for pos_x in data['map_data'].keys(): x = int(pos_x) for pos_y in data['map_data'][pos_x].keys(): y = int(pos_y) ref = data['map_data'][pos_x][pos_y] obj_keys = ref.keys() if 'object' in obj_keys: o = _ref2obj(ref) if not isinstance(o, NPC) and not isinstance( o, BoardItemVoid): local_board.place_item(o, x, y) elif isinstance(o, NPC): self.add_npc(lvl_number, o, x, y) else: Utils.warn( f'while loading the board in {filename}, at coordinates [{pos_x},{pos_y}] there is an entry without "object" attribute. NOT LOADED.' ) return local_board
mygame = Game(name="Demo game") # Set a message variable to display a message on selected menu item message = None # Now we want to create some menus to tell the player what to do, or to # give some informations/directions # IMPORTANT: Menu do absolutely nothing by themselves, they are just a # structured display of informations. # The syntaxe is game_object.add_menu_entry(category,shortcut,message) option_red = "A cool menu in dim red" option_magenta = "Another cool menu in bright magenta" mygame.add_menu_entry("main_menu", None, "=" * 22) mygame.add_menu_entry("main_menu", "h", "Show the help menu") mygame.add_menu_entry("main_menu", None, "=" * 22) mygame.add_menu_entry("main_menu", "1", Utils.red_dim(option_red)) mygame.add_menu_entry("main_menu", "2", Utils.magenta_bright(option_magenta)) mygame.add_menu_entry("main_menu", "q", "Quit game") mygame.add_menu_entry("help_menu", None, "---------") mygame.add_menu_entry("help_menu", None, "Help Menu") mygame.add_menu_entry("help_menu", None, "---------") mygame.add_menu_entry("help_menu", "j", "Random help menu") mygame.add_menu_entry("help_menu", "b", "Back to main menu") # let's set a variable that hold the current menu category (for navigation) current_menu = "main_menu" # Now let's make a loop to dynamically navigate in the menu key = None while True: # clear screen
def clear_screen(self): """ Clear the whole screen (i.e: remove everything written in terminal) """ Utils.clear_screen()
import gamelib.Constants as Constants # First let's create a Board that uses squares as delimiters myboard = Board( name='A demo board', size=[40,20], ui_border_left=Utils.WHITE_SQUARE, # Borders are going to be white squares ui_border_right=Utils.WHITE_SQUARE, ui_border_top=Utils.WHITE_SQUARE, ui_border_bottom=Utils.WHITE_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE, # Cells with nothing inside are going to be black squares player_starting_position=[10,20] ) # Then create a player playerone = Player( model=Utils.yellow_bright('××') ) # Place it on the board myboard.place_item(playerone, 10,10) # Now let's display our board myboard.display() # And make a short loop that moves the player and display the board # WARNING: in real life we would use the Game object to manage the game and the screen for k in range(1,10,1): # Clear screen Utils.clear_screen() # Print a debug message Utils.debug(f'Round {k} player position is ({playerone.pos[0]},{playerone.pos[1]}) -- BEFORE moving')
# On that board the player starts at the center lvl2 = Board(ui_borders=Utils.MAGENTA_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE, player_starting_position=[5, 5]) # And on that board the player starts at the bottom right corner lvl3 = Board(ui_borders=Utils.RED_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE, player_starting_position=[9, 9]) # Now let's create a game object. mygame = Game(name='demo') # And a Player nazbrok = Player(name='Nazbrok', model=Utils.green_bright("¤¤")) # Now add the boards to the game so the Game object can manage them # the parameters of add_board() are a level number and a board. mygame.add_board(1, lvl1) mygame.add_board(2, lvl2) mygame.add_board(3, lvl3) # Now we also want our player to be managed by the game mygame.player = nazbrok # Now let's show a clean screen to our player mygame.clear_screen() # We haven't place nazbrok on any board, but that's ok because we are going # to use Game to manage the starting position of our player
mygame.player = Player(name='DaPlay3r', model=Sprites.UNICORN_FACE) mygame.add_board(1, board1) mygame.add_board(2, board2) mygame.change_level(1) key = None # Main game loop while True: mygame.clear_screen() mygame.display_board() # Key handler if key == 'q': print(Utils.yellow_bright("Good bye and thank you for playing!")) break elif key == 'a': # Left mygame.move_player(Constants.LEFT, 1) elif key == 'd': # Right mygame.move_player(Constants.RIGHT, 1) elif key == 'w': # Up mygame.move_player(Constants.UP, 1) elif key == 's': # Down mygame.move_player(Constants.DOWN, 1) elif key == '3': mygame.move_player(Constants.DRDOWN, 1)
import examples_includes # noqa: F401 # First import the Utils module import gamelib.Utils as Utils # Then get creative! # you directly print colored messages: print(Utils.magenta_bright("This is a rather flashy magenta...")) # Each color function has 3 variations : regular, dim and bright print(Utils.yellow_dim("This is dim.")) print(Utils.yellow("This is regular.")) print(Utils.yellow_bright("This is bright.")) # Now, the color functions are just that: functions. So you can store the # results in a variable and use them: blue = Utils.blue_bright("blue") white = Utils.white_bright("white") red = Utils.red_bright("red") print(f"France's flag is {blue} {white} {red}!")
name = str( input('Name: ') ) width = int( input_digit('Width (in number of cells): ') ) height = int( input_digit('Height (in number of cells): ') ) game.add_board(1, Board(name=name,size=[width,height], ui_borders=Utils.WHITE_SQUARE,ui_board_void_cell=Utils.BLACK_SQUARE) ) is_modified=True # Main program game = Game() game.player = Player(model='[]') key = 'None' current_object = BoardItemVoid(model='None') object_history = [] current_menu = 'main' while True: game.clear_screen() print( Utils.cyan_bright("HAC-GAME-LIB - EDITOR v"+Constants.HAC_GAME_LIB_VERSION) ) print('Looking for existing maps in hac-maps/ directory...',end='') hmaps = [] try: hmaps = os.listdir('hac-maps/') print(Utils.green('OK')) except FileNotFoundError as e: print(Utils.red('KO')) if len(hmaps) > 0: map_num = 0 game.add_menu_entry('boards_list',None,"Choose a map to edit") for m in hmaps: print(f"{map_num} - edit hac-maps/{m}") game.add_menu_entry('boards_list',str(map_num),f"edit hac-maps/{m}",f"hac-maps/{m}")
ui_board_void_cell=Utils.BLACK_SQUARE)) is_modified = True # Main program game = Game() current_file = '' game.player = Player(model='[]') key = 'None' current_object = BoardItemVoid(model='None') object_history = [] current_menu = 'main' while True: game.clear_screen() print( Utils.cyan_bright("HAC-GAME-LIB - EDITOR v" + Constants.HAC_GAME_LIB_VERSION)) print('Looking for existing maps in selected directories...', end='') with open('directories.json') as paths: directories = json.load(paths) hmaps = [] try: for directory in directories: files = [f'{directory}/{f}' for f in os.listdir(directory)] hmaps += files print(Utils.green('OK')) except FileNotFoundError as e: print(Utils.red('KO')) if len(hmaps) > 0: map_num = 0
if key == "Q": break elif key == "1": viewport = [10, 10] g.partial_display_viewport = viewport elif key == "2": viewport = [15, 30] g.partial_display_viewport = viewport elif key == "3": viewport = [20, 20] g.partial_display_viewport = viewport if key == " ": if g.player.mp >= 4: fireball = Projectile( name="fireball", model=Utils.red_bright(black_circle), hit_model=Sprites.EXPLOSION, ) fireball.animation = Animation( auto_replay=True, animated_object=fireball, refresh_screen=None, display_time=0.5, ) fireball.animation.add_frame(Utils.red_bright(black_circle)) fireball.animation.add_frame(Utils.red_bright(circle_jot)) fireball.range = 7 fireball.set_direction(Constants.RIGHT) g.add_projectile(1, fireball, g.player.pos[0], g.player.pos[1] + 1) g.player.mp -= 4
def create_wizard(): global game key = '' while True: game.clear_screen() print(Utils.green_bright("\t\tObject creation wizard")) print('What do you want to create: a NPC or a structure?') print('1 - NPC (Non Playable Character)') print('2 - Structure (Wall, Door, Treasure, Portal, Trees, etc.)') key = Utils.get_key() if key == '1' or key == '2': break if key == '1': game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.cyan_bright("NPC")) new_object = NPC() print("First give a name to your NPC. Default value: " + new_object.name) r = str(input('(Enter name)> ')) if len(r) > 0: new_object.name = r print( "Then give it a type. A type is important as it allows grouping.\nType is a string. Default value: " + new_object.type) r = str(input('(Enter type)> ')) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.cyan_bright("NPC") + f' - {new_object.model}') print( 'We now needs to go through some basic statistics. You can decide to go with default by simply hitting the "Enter" key.' ) r = input_digit( f'Number of cell crossed in one turn. Default: {new_object.step}(type: int) > ' ) if len(r) > 0: new_object.step = int(r) else: # If it's 0 it means it's going to be a static NPC so to prevent python to pass some random pre-initialized default, we explicitly set the Actuator to a static one new_object.actuator = SimpleActuators.RandomActuator(moveset=[]) r = input_digit( f'Max HP (Health Points). Default: {new_object.max_hp}(type: int) > ' ) if len(r) > 0: new_object.max_hp = int(r) new_object.hp = new_object.max_hp r = input_digit( f'Max MP (Mana Points). Default: {new_object.max_mp}(type: int) > ' ) if len(r) > 0: new_object.max_mp = int(r) new_object.mp = new_object.max_mp r = input_digit( f'Remaining lives (it is advised to set that to 1 for a standard NPC). Default: {new_object.remaining_lives}(type: int) > ' ) if len(r) > 0: new_object.remaining_lives = int(r) r = input_digit( f'AP (Attack Power). Default: {new_object.attack_power}(type: int) > ' ) if len(r) > 0: new_object.attack_power = int(r) r = input_digit( f'DP (Defense Power). Default: {new_object.defense_power}(type: int) > ' ) if len(r) > 0: new_object.defense_power = int(r) r = input_digit( f'Strength. Default: {new_object.strength}(type: int) > ') if len(r) > 0: new_object.strength = int(r) r = input_digit( f'Intelligence. Default: {new_object.intelligence}(type: int) > ') if len(r) > 0: new_object.intelligence = int(r) r = input_digit( f'Agility. Default: {new_object.agility}(type: int) > ') if len(r) > 0: new_object.agility = int(r) game.clear_screen() print( "We now need to give some life to that NPC. What kind of movement should it have:" ) print("1 - Randomly chosen from a preset of directions") print("2 - Following a predetermined path") r = Utils.get_key() if r == '1': new_object.actuator = SimpleActuators.RandomActuator(moveset=[]) print( 'Random it is! Now choose from which preset of movements should we give it:' ) print('1 - UP,DOWN,LEFT, RIGHT') print('2 - UP,DOWN') print('3 - LEFT, RIGHT') print('4 - UP,DOWN,LEFT, RIGHT + all DIAGONALES') print( '5 - DIAGONALES (DIAG UP LEFT, DIAG UP RIGHT, etc.) but NO straight UP, DOWN, LEFT and RIGHT' ) print('6 - No movement') r = Utils.get_key() if r == '1': new_object.actuator.moveset = [ Constants.UP, Constants.DOWN, Constants.LEFT, Constants.RIGHT ] elif r == '2': new_object.actuator.moveset = [Constants.UP, Constants.DOWN] elif r == '3': new_object.actuator.moveset = [Constants.RIGHT, Constants.LEFT] elif r == '4': new_object.actuator.moveset = [ Constants.UP, Constants.DOWN, Constants.LEFT, Constants.RIGHT, Constants.DLDOWN, Constants.DLUP, Constants.DRDOWN, Constants.DRUP ] elif r == '5': new_object.actuator.moveset = [ Constants.DLDOWN, Constants.DLUP, Constants.DRDOWN, Constants.DRUP ] elif r == '6': new_object.actuator.moveset = [] else: Utils.warn( f'"{r}" is not a valid choice. Movement set is now empty.') new_object.actuator.moveset = [] elif r == '2': new_object.actuator = SimpleActuators.PathActuator(path=[]) print("Great, so what path this NPC should take:") print('1 - UP/DOWN patrol') print('2 - DOWN/UP patrol') print('3 - LEFT/RIGHT patrol') print('4 - RIGHT/LEFT patrol') print('5 - Circle patrol: LEFT, DOWN, RIGHT, UP') print('6 - Circle patrol: LEFT, UP, RIGHT, DOWN') print('7 - Circle patrol: RIGHT, DOWN, LEFT, UP') print('8 - Circle patrol: RIGHT, UP, LEFT, DOWN') print('9 - Write your own path') r = Utils.get_key() if r == '1': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == '2': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '3': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] elif r == '3': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] elif r == '4': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '5': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '6': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == '7': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '8': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == '9': print( "Write your own path using only words from this list: UP, DOWN, LEFT, RIGHT, DLDOWN, DLUP, DRDOWN, DRUP." ) print('Each direction has to be separated by a coma.') r = str(input('Write your path: ')).upper() new_object.actuator.path = r.split(',') else: Utils.warn(f'"{r}" is not a valid choice. Path is now empty.') new_object.actuator.path = [] return new_object elif key == '2': while True: game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.magenta_bright("Structure")) print("What kind of structure do you want to create:") print( '1 - A wall like structure (an object that cannot be picked-up and is not overlappable). Ex: walls, trees, non moving elephant (try to go through an elephant or to pick it up in your backpack...)' ) print('2 - A door (player and/or NPC can go through)') print( '3 - A treasure (can be picked up, take space in the inventory, give points to the player)' ) print( '4 - A generic object (you can set the properties to make it pickable or overlappable)' ) print( '5 - A generic actionable object (to make portals, heart to replenish life, etc.)' ) key = Utils.get_key() new_object = None if key == '1': new_object = Structures.Wall() new_object.name = str(uuid.uuid1()) new_object.model = model_picker() break elif key == '2': new_object = Structures.Door() new_object.name = str(uuid.uuid1()) new_object.model = model_picker() break elif key == '3': new_object = Structures.Treasure() print("First give a name to your Treasure. Default value: " + new_object.name) r = str(input('(Enter name)> ')) if len(r) > 0: new_object.name = r print( "Then give it a type. A type is important as it allows grouping (in this case probably in the inventory).\nType is a string. Default value: " + new_object.type) r = str(input('(Enter type)> ')) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() break elif key == '4' or key == '5': if key == '4': new_object = Structures.GenericStructure() else: new_object = Structures.GenericActionableStructure() new_object.set_overlappable(False) new_object.set_pickable(False) print("First give a name to your structure. Default value: " + new_object.name) r = str(input('(Enter name)> ')) if len(r) > 0: new_object.name = r print( "Then give it a type. \nType is a string. Default value: " + new_object.type) r = str(input('(Enter type)> ')) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() print( 'Is this object pickable? (can it be picked up by the player)?' ) print('0 - No') print('1 - Yes') r = Utils.get_key() if r == '1': new_object.set_pickable(True) print( 'Is this object overlappable? (can it be walked over by player?' ) print('0 - No') print('1 - Yes') r = Utils.get_key() if r == '1': new_object.set_overlappable(True) break return new_object #Placeholder return BoardItemVoid()
Treasure, GenericStructure, GenericActionableStructure, ) import gamelib.Constants as cst from gamelib.Actuators.SimpleActuators import PathActuator import gamelib.Utils as Utils import gamelib.Sprites as Sprites import time import sys import random sprite_mode = 'nosprite' sprite_player = { 'left': Utils.red_bright('-|'), 'right': Utils.red_bright('|-'), } sprite_npc = None sprite_npc2 = None sprite_portal = None sprite_treasure = None sprite_treasure2 = None sprite_tree = None sprite_wall = None sprite_heart = None sprite_heart_minor = None # The following code is used to switch rendering between # emojis enabled terminal and the others. # Use 'nosprite' if you see unicode codes displayed in your terminal.