def make_platform(b, row, column): psize = random.randint(2, 10) plateform = [] tmp_game = Game() # Only because Game needs it, we don't care. tmp_game.player = Player() tmp_game.add_board(0, b) tmp_game.change_level(0) # print( # f"[d] make_platform at {row}, {column}, psize is {psize} column will be " # f"between {column} and {column + psize + 1}" # ) get_up = 0 # for i in range(column, column + psize + 1): for i in range(column - psize - 1, column): if i >= b.size[0]: break if not isinstance(b.item(row, i), BoardItemVoid): break if i in b.visited_columns: break # Check if we have other platforms around. # If yes moving the platform up. if get_up < 3: for e in tmp_game.neighbors(2, Door(pos=[row, i])): if e.type == "ground": get_up = 3 break if get_up < 4: for e in tmp_game.neighbors(1, Door(pos=[row, i])): if e.type == "ground": get_up = 4 break m = block_color() + " " + Utils.Style.RESET_ALL plateform.append([Wall(model=m, type="platform"), row, i]) for i in plateform: b.place_item(i[0], i[1] - get_up, i[2]) if random.choice([True, False]): generate_treasure(b, i[1] - get_up - 1, i[2]) else: generate_trap(b, i[1] - get_up - 1, i[2]) b.visited_columns.append(i[2])
# 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) blocker = NPC(model=Sprites.SKULL) g.current_board().place_item(blocker, 20, 1)
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 i = 0 for sp in dir(Sprites): if not sp.startswith('__'):
board1 = Board(name='Level 1', ui_borders=Sprites.WALL, ui_board_void_cell=Utils.BLACK_SQUARE, player_starting_position=[0, 0]) board2 = Board(name='Level 2', ui_borders=Utils.RED_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE, player_starting_position=[4, 4]) 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':
## https://astro.hyrul.es/guides/hac-game-lib/tutorial-01-the-game-object.html ## ## ## ################################################################################# mygame = Game(name='Demo game') board1 = Board(name='Level 1', ui_borders=Sprites.WALL, ui_board_void_cell=Utils.BLACK_SQUARE, player_starting_position=[0, 0]) board2 = Board(name='Level 2', ui_borders=Utils.RED_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE, player_starting_position=[4, 4]) mygame.player = Player(name='DaPlay3r', model=Sprites.UNICORN_FACE) mygame.add_board(1, board1) mygame.add_board(2, board2) count = 0 lvl = 1 while count < 10: mygame.clear_screen() mygame.change_level(lvl) mygame.current_board().display() lvl += 1 if lvl > 2: lvl = 1 time.sleep(2) count += 1
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 # First let's display nazbrok's position Utils.debug(f"Nazbrok is at position ({nazbrok.pos[0]}, {nazbrok.pos[0]})" f" -- BEFORE changing level") # Now the only thing we need is to change level mygame.change_level(1) # and Nazbrok is auto-magically at the starting position for our lvl1 board! Utils.debug(f"Nazbrok is at position ({nazbrok.pos[0]}, {nazbrok.pos[0]})" f" -- AFTER changing level to level 1") # Now let's display the current board mygame.current_board().display() # Let's wait a little countdown() # Now do it all again: clear the screen, print Nazbrok's position, change # level, print the new position and wait a little mygame.clear_screen() Utils.debug(f"Nazbrok is at position ({nazbrok.pos[0]},{nazbrok.pos[0]})" f" -- BEFORE changing level")
column = random.randint(0,bonus_board.size[0]-1) # print(f"Game.add_npc() finding a position for NPC {npc.name} trying ({x},{y})") if isinstance(bonus_board.item(row,column), BoardItemVoid): break elif retry > 20: break else: row = None column = None retry += 1 bonus_board.place_item(Treasure(model=Sprites.CROWN, value=5000, name=f'crown_{k}'), row, column) # Create the player object. g.player = Player(name='Mighty Wizard',model=Sprites.MAGE) g.change_level(1) introduction_scene() # 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. for item in g.current_board().get_immovables(): # Here we need to set the functions that are going to be called when the player touches our hidden traps. if item.type == 'simple_explosion' or item.type == 'mega_explosion': # First let's set our model to the same as the current level's board void cell model.
# 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. for item in g.current_board().get_immovables(): # Here we need to set the functions that are going to be called when the player touches our hidden traps. if item.type == 'simple_explosion' or item.type == 'mega_explosion': # First let's set our model to the same as the current level's board void cell model. item.model = g.current_board().ui_board_void_cell
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))