map_num += 1 game.add_menu_entry('boards_list', 'B', "Go Back to main menu") else: print('No pre-existing map found.') print('n - create a new map') print('q - Quit the editor') choice = input('Enter your choice (and hit ENTER): ') if choice == 'q': print('Good Bye!') exit() elif choice == 'n': create_board_wizard() break elif choice.isdigit() and int(choice) < len(hmaps): current_file = hmaps[int(choice)] game.load_board(hmaps[int(choice)], 1) break game.change_level(1) if len(game.object_library) > 0: object_history += game.object_library # Build the menus i = 0 for sp in dir(Utils): if sp.endswith('_SQUARE') or sp.endswith('_RECT'): game.add_menu_entry('graphics_utils', str(i), '"' + getattr(Utils, sp) + '"', getattr(Utils, sp)) i += 1
g.clear_screen() g.display_board() # Destination (24,24) is the center of the labyrinth dest_row = 24 dest_col = 24 if len(sys.argv) > 1: dest_row = int(sys.argv[1]) if len(sys.argv) > 2: dest_col = int(sys.argv[2]) g = Game() b = g.load_board('hac-maps/Maze.json', 1) g.player = Player(name='The Mighty Wizard', model=Sprites.MAGE) g.change_level(1) g.actuate_npcs(1) pf = PathFinder(game=g, actuated_object=g.player) pf.add_waypoint(dest_row, dest_col) pf.add_waypoint(24, 24) pf.add_waypoint(21, 40) pf.circle_waypoints = True pf.set_destination(dest_row, dest_col)
from gamelib.Game import Game from gamelib.Characters import Player import gamelib.Sprites as Sprites import gamelib.Utils as Utils import gamelib.Constants as Constants 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 == Utils.key.UP: g.move_player(Constants.UP, 1) elif key == Utils.key.DOWN: g.move_player(Constants.DOWN, 1) elif key == Utils.key.LEFT: g.move_player(Constants.LEFT, 1) elif key == Utils.key.RIGHT: 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]})")
from gamelib.Game import Game from gamelib.Characters import Player import gamelib.Sprites as Sprites import gamelib.Utils as Utils import gamelib.Constants as Constants 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]})')
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}") map_num += 1 else: print("No pre-existing map found.") print("n - create a new map") print("q - Quit the editor") choice = str( Utils.get_key() ) if choice == "q": print("Good Bye!") exit() elif choice == "n": create_board_wizard() break elif choice.isdigit() and int(choice) < len(hmaps): game.load_board('hac-maps/'+hmaps[int(choice)],1) break game.change_level(1) if len(game.object_library)>0: object_history += game.object_library # Build the menus i = 0 for sp in dir(Utils): if sp.endswith('_SQUARE') or sp.endswith('_RECT'): game.add_menu_entry('graphics_utils',str(i), '"'+getattr(Utils,sp)+'"', getattr(Utils,sp)) i += 1 i = 0
from gamelib.Board import Board from gamelib.Characters import Player, NPC from gamelib.Structures import Door, Treasure from gamelib.BoardItem import BoardItemVoid import gamelib.Sprites as Sprites import gamelib.Constants as Constants import gamelib.Utils as Utils import time import random ## Here are our global variables (it is usually a bad idea to use global variables but it will simplify that tutorial, keep in mind that we don't usually rely on global variables) # Create the game object. We are going to use this as a global variable. g = Game() # Load the board as level 1 b = g.load_board('levels/TutoMap-hac-game-lib.json', 1) def refresh_screen(): global g g.clear_screen() g.display_player_stats() g.display_board() def damage_player(params): pass def explosion(params):
g.clear_screen() g.display_board() # Destination (24,24) is the center of the labyrinth dest_row = 24 dest_col = 26 if len(sys.argv) > 1: dest_row = int(sys.argv[1]) if len(sys.argv) > 2: dest_col = int(sys.argv[2]) g = Game() b = g.load_board("hac-maps/Maze.json", 1) g.player = Player(name="The Mighty Wizard", model=Sprites.MAGE) g.change_level(1) g.actuate_npcs(1) pf = PathFinder(game=g, actuated_object=g.player) pf.add_waypoint(dest_row, dest_col) pf.add_waypoint(24, 24) pf.add_waypoint(21, 40) pf.circle_waypoints = True pf.set_destination(dest_row, dest_col)
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 teleport_player(row,column): g.current_board().clear_cell(g.player.pos[0],g.player.pos[1]) g.current_board().place_item(g.player,row,column) # Load the board as level 1 b = g.load_board(level_1,1) # The game over screen is going to be level 999. There is no reason for that, it is just a convention as I don't think that this game is going to have more than 998 levels. g.load_board(game_over,999) # And help 998 g.load_board(help_menu,998) # Now let's build a random generated bonus stage! # First we need a board. Same size 50x30 but the player starting position is random. player_starting_row = random.randint(0,29) player_starting_column = random.randint(0,49) bonus_board = Board(name='Bonus Stage', size=[50,30], player_starting_position=[player_starting_row,player_starting_column], ui_borders=Utils.YELLOW_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE) g.add_board(2,bonus_board) # To place the treasures we have 30*50 = 1500 cells available on the map, minus the player it brings the total to 1499. # Now let's randomely place 300 money bags. Each bag increase the score by 100. for k in range(0,300): row = None
# The board we want to load for the first level level_1 = 'levels/TutoMap-hac-game-lib.json' # And the game over screen game_over = 'levels/Game_Over.json' # The notifications are going to be used to give info to the player without entering a full dialog mode. # IMPORTANT: The player movement clears the notifications not the rest of the game. As we are going to multithread the game at some point it's important to take the right decision from start. notifications = [] # Create the game object. We are going to use this as a global variable. g = Game() # Load the board as level 1 b = g.load_board(level_1, 1) # The game over screen is going to be level 999. There is no reason for that, it is just a convention as I don't think that this game is going to have more than 998 levels. g.load_board(game_over, 999) # Create the player object. g.player = Player(name='The Mighty Wizard', model=Sprites.MAGE) g.change_level(1) # Now we need to fix the river (it's missing 2 tiles of water) # First let's move the NPCs so the whales are not replaced by our new tiles. g.actuate_npcs(1) # Now let's place the 2 river tiles (we use the Door object as a shortcut to get a overlapable, restorable item) g.current_board().place_item(Door(model=Utils.BLUE_SQUARE), 0, 26) g.current_board().place_item(Door(model=Utils.BLUE_SQUARE), 11, 0) # Now we need to take care of the explosions. Hide them and set the callback functions.
import gamelib.Utils as Utils import time import sys board_to_load = 'hac-maps/test-board.json' if len(sys.argv) > 1: board_to_load = sys.argv[1] max_iter = 10 if len(sys.argv) > 2: max_iter = int(sys.argv[2]) g = Game() b = g.load_board(board_to_load, 1) print(b) g.player = Player(model=Sprites.FLYING_SAUCER) g.change_level(1) idx = 0 key = None while idx < max_iter or max_iter == 0: if key == 'w': g.move_player(Constants.UP, 1) elif key == 's': g.move_player(Constants.DOWN, 1) elif key == 'a':
from gamelib.Game import Game # noqa: E402 from gamelib.Characters import Player # noqa: E402 from gamelib.Structures import Door # noqa: E402 import gamelib.Sprites as Sprites # noqa: E402 import gamelib.Constants as Constants # noqa: E402 import gamelib.Utils as Utils # noqa: E402 # Here are our global variables (it is usually a bad idea to use global variables but # it will simplify that tutorial, keep in mind that we don't usually rely on global # variables) # Create the game object. We are going to use this as a global variable. g = Game() # Load the board as level 1 b = g.load_board("levels/TutoMap-hac-game-lib.json", 1) def refresh_screen(): global g g.clear_screen() g.display_player_stats() g.display_board() def damage_player(params): pass def explosion(params):
map_num += 1 game.add_menu_entry("boards_list", "B", "Go Back to main menu") else: print("No pre-existing map found.") print("n - create a new map") print("q - Quit the editor") choice = input("Enter your choice (and hit ENTER): ") if choice == "q": print("Good Bye!") exit() elif choice == "n": create_board_wizard() break elif choice.isdigit() and int(choice) < len(hmaps): current_file = hmaps[int(choice)] board = game.load_board(hmaps[int(choice)], 1) if board.size[0] >= viewport_height or board.size[1] >= viewport_width: game.enable_partial_display = True game.partial_display_viewport = [viewport_height, viewport_width] else: game.enable_partial_display = False break game.change_level(1) if len(game.object_library) > 0: object_history += game.object_library for i in game.object_library: if i not in game.config("settings")["object_library"]: game.config("settings")["object_library"].append(i)
# f"Updating winner with {winner} and deltas {dc_r},{dc_c} " # f"and sum_dc = {sum_dc}" # ) if DEBUG: reset_drawn_path() g.current_board().place_item( Door(model=Utils.GREEN_SQUARE, type="path_marker"), winner[0], winner[1]) redraw() # input(f'Winner: {winner}') return winner g = Game() # b = g.load_board('/home/arnaud/Code/Games/hgl-editor/TestChasing.json', 1) b = g.load_board("hac-maps/The_Castle.json", 1) g.player = Player(name="The Mighty Wizard", model=Sprites.MAGE) g.change_level(1) guards = [] for item in g.current_board().get_movables(type="guard"): guards.append(item) nm = None key = None chasing = False while nm != Constants.NO_DIR: if g.player.hp <= 0:
# Finally place the water on the board b.place_item(d, r, c) # Redraw the screen and wait to see the nice animation of the algorithm working. # Otherwise it's instantanous. redraw_screen(g) time.sleep(0.1) # Now make recursive calls to fill the cells around this one. flood_filler(g, b, r + 1, c) flood_filler(g, b, r - 1, c) flood_filler(g, b, r, c + 1) flood_filler(g, b, r, c - 1) # Using the Game object just to load the board easily g = Game() b = g.load_board("/home/arnaud/Code/Games/hgl-editor/Filler.json", 1) g.player = Player(model=Graphics.Sprites.MAGE) g.change_level(1) # We need the player out of our way g.move_player(Constants.LEFT, 5) # Now let's flood the floor!! flood_filler(g, b, 5, 6) # Show the animated lake for 200 turns (~40 secondes) i = 0 while i < 200: i += 1 redraw_screen(g) g.animate_items(1) time.sleep(0.2)
class GameNeighborTestCase(unittest.TestCase): def setUp(self): super().setUp() self.game = Game() self.board = self.game.load_board("hac-maps/kneighbors.json", 1) self.game.player = Player(name="player") self.game.change_level(1) self.tree26 = self.board.item(2, 6) self.treasure38 = self.board.item(3, 8) self.tree39 = self.board.item(3, 9) self.wall45 = self.board.item(4, 5) self.wall46 = self.board.item(4, 6) self.wall47 = self.board.item(4, 7) self.wall57 = self.board.item(5, 7) self.npc77 = self.board.item(7, 7) self.treasure1212 = self.board.item(12, 12) self.tree1310 = self.board.item(13, 10) self.npc168 = self.board.item(16, 8) def test_player_neighbors(self): testcases = ( ([3, 3], []), ([3, 5], [self.tree26, self.wall45, self.wall46]), ([3, 6], [self.tree26, self.wall45, self.wall46, self.wall47]), ([3, 7], [self.tree26, self.wall46, self.wall47, self.treasure38]), ([4, 8], [self.wall47, self.wall57, self.treasure38, self.tree39]), ([5, 6], [self.wall45, self.wall46, self.wall47, self.wall57]), ) for pos, expected_board_items in testcases: with self.subTest(str(pos)): self.game.player.pos = pos actual_board_items = self.game.neighbors() assertion_message = " ".join([ readable_board_items(expected_board_items), "!=", readable_board_items(actual_board_items), ]) self.assertSetEqual( set(expected_board_items), set(actual_board_items), assertion_message, ) def test_npc_neighbors(self): def move_player_next_to_npc77(): pos_next_to_npc = [7, 8] self.game.move_player(Constants.DOWN, pos_next_to_npc[0]) self.game.move_player(Constants.RIGHT, pos_next_to_npc[1]) self.assertEqual(pos_next_to_npc, self.game.player.pos) actual_board_items = self.game.neighbors(1, self.npc77) self.assertSetEqual(set(), set(actual_board_items)) move_player_next_to_npc77() actual_board_items = self.game.neighbors(1, self.npc77) self.assertSetEqual({self.game.player}, set(actual_board_items)) def dump_board_items(self): h, w = self.board.size for y in range(h): for x in range(w): boarditem = self.board.item(y, x) assert isinstance(boarditem, BoardItem) if isinstance(boarditem, BoardItemVoid): continue print(readable_board_item(boarditem))