예제 #1
0
 def setup(self):
     self.player = Player((500, 300))
     self.enemies.append(Enemy(Enemy.MobType.SLOW, (100, 250)))
     self.enemies.append(Enemy(Enemy.MobType.SLOW, (60, 220)))
     self.enemies.append(Enemy(Enemy.MobType.SLOW, (400, 420)))
     self.enemies.append(Enemy(Enemy.MobType.SLOW, (360, 380)))
     self.enemies.append(Enemy(Enemy.MobType.SLOW, (220, 300)))
예제 #2
0
def create_player(has_infinite_lives, score=PLAYER_INITIAL_SCORE):
    """
    :param has_infinite_lives: whether the player has infinite lives or not
    :param score: the initial score this player has
    :return: A new player with default values
    """
    if has_infinite_lives:
        return Player.infinite_lives(score)
    else:
        return Player.limited_lives(score, PLAYER_INITIAL_LIVES)
예제 #3
0
 def __init__(self, evManager):
     Listener.__init__(self, evManager)
     self.currentmap = None
     # Destination tuple. This will be consumed after a teleport event has occured
     self.teleport_destination = None
     # Player object reference
     self.player = Player()
     # Shadow object reference
     self.shadow = Shadow()
     # State; initialized with "main menu" value
     self.state = STATE_MAIN_MENU
     self.changeHandler(self.state)
     # Broadcast the game state
     self.evManager.post(GameStateChangedEvent(self.state))
예제 #4
0
class StateController:
    __instance = None

    @staticmethod
    def getInstance():
        if StateController.__instance is None:
            StateController.__instance = StateController()
        return StateController.__instance

    lc = LootController.getInstance()
    player: Player = None
    enemies = []
    deadEnemies = []
    map: [[int]] = []
    loot: [Loot] = []

    def setup(self):
        self.player = Player((500, 300))
        self.enemies.append(Enemy(Enemy.MobType.SLOW, (100, 250)))
        self.enemies.append(Enemy(Enemy.MobType.SLOW, (60, 220)))
        self.enemies.append(Enemy(Enemy.MobType.SLOW, (400, 420)))
        self.enemies.append(Enemy(Enemy.MobType.SLOW, (360, 380)))
        self.enemies.append(Enemy(Enemy.MobType.SLOW, (220, 300)))

    def update(self, tick: float):
        self.player.update()
        for enemy in self.enemies:
            enemy.update(self.player, tick)
            if enemy.dead:
                self.enemies.remove(enemy)
                self.deadEnemies.append(enemy)
                # drop loot
                c: [Currency] = self.lc.roll(enemy.level)
                self.loot.append(c)
            dist = self.player.pos.distance_to(enemy.pos)
            if dist < Const.WIN_DIST:
                self.player.curHealth -= enemy.doDamage()

    def enemiesTakeNovaDamage(self, radius: int, amount: int):
        for enemy in self.enemies:
            dist = self.player.pos.distance_to(enemy.pos)
            if dist < radius:
                enemy.takeDamage(amount)

    def makeMap(self):
        xSize = 12 * 4
        ySize = 48 * 2
        m = Map()
        m.generateMap(xSize, ySize)
        m.placeTreasure()
        m.printMap()

        for x in range(0, xSize):
            self.map.append([])
            for y in range(0, ySize):
                self.addTileToMap(m, x, y)

    def addTileToMap(self, m, x, y):
        PLAIN = 20
        EMPTY = 40
        GRASS = 6 * 16 + 1
        if m.isTreasure((x, y)):
            self.map[x].append(GRASS)
        elif m.cellmap[x][y]:
            self.map[x].append(PLAIN)
        else:
            self.map[x].append(EMPTY)
예제 #5
0
class Game(Listener):
    # Constructor
    # Parameter:
    #   evManager   :   EventManager instance to which events are posted to
    def __init__(self, evManager):
        Listener.__init__(self, evManager)
        self.currentmap = None
        # Destination tuple. This will be consumed after a teleport event has occured
        self.teleport_destination = None
        # Player object reference
        self.player = Player()
        # Shadow object reference
        self.shadow = Shadow()
        # State; initialized with "main menu" value
        self.state = STATE_MAIN_MENU
        self.changeHandler(self.state)
        # Broadcast the game state
        self.evManager.post(GameStateChangedEvent(self.state))
        
    # Listener interface implementation. This basically delegates the event handling
    # to the current Handler connected to the Game object in a given situation
    # Parameter:
    #   event   :   The event posted by the EventManager
    def notify(self, event):
        # Catch GameStateChanged events first, and change the current handler object accordingly
        if isinstance(event, GameStateChangedEvent):
            self.changeHandler(event.object)
        else:
            # If it is any other Event subclass object, let the handler deal with it
            self.handler.handle(event)
            
    # Change the handler working for this Game object according to the given state.
    # Parameter:
    #   state   :   The new game state
    def changeHandler(self, state):
        if state == STATE_MAIN_MENU:
            self.handler = MainMenuGameHandler(self)
        elif state == STATE_GAME_MAP_LOADING:
            self.handler = MapLoadingHandler(self)
        elif state == STATE_GAME_RUNNING:
            self.handler = RunningGameHandler(self)
        elif state == STATE_GAME_INVENTORY:
            self.handler = InventoryGameHandler(self)
        elif state == STATE_GAME_MENU:
            self.handler = GameMenuGameHandler(self)
        
    # Convenience method to delete a save game using the given file name
    # Parameter:
    #   name    :   The name of the save game to be deleted
    def deleteSavegame(self, name):
        path = os.path.join(PATH_SAVES, name)
        name = name.lower()
        dirs = [d.lower() for d in os.listdir(PATH_SAVES)]
        #print("delete %s from list" % name)
        #print(dirs)
        dele = False
        for d in dirs:
            if d == name:
                dele = True
        #print("in list? %s" % dele)
        # If this save game folder exists...
        if dele: 
            #...delete it!
            shutil.rmtree(path)
        
    # Save method that saves the current game state to the external shelf
    # of the current save game folder.
    # Parameter:
    #   disp    :   Boolean that toggles a text message to be displayed on screen,
    #               indicating a successful save process, if True. If False,
    #               saving still occurs, but the message is not displayed.
    def save(self, disp=False):                
        # Get the savegame data
        temp = get_savegame()
        # Open the "real" shelf (the one the player can load up again)!
        save = shelve.open(CURRENT_SHELF_FILENAME[0])
        
        # Save persistent data that needs to be stored in order to retrieve the game state.
        # All data that is used to do that is actually the player's current position,
        # the current map where this position applies, and the currently playing background
        # music.
        # Pre-defined keys for the dict
        save['player_position'] = self.player.position
        save['current_map'] = self.currentmap.properties['key_name']
        save['player_inventory'] = self.player.inventory
        save['current_sounds'] = GlobalServices.getAudioDevice().getPlayingSounds()
        
        temp['global_overlays'] = get_global_overlays()
        
        # Update the persistent map properties for the current map
        update_persistent_map_properties(self.currentmap, temp)
        # Copy the rest of the shelf data to the "correct" save file
        copy_to_shelve(temp, save)
        
        # Close the shelves again; that's it!
        save.close()
        
        if disp:
            # Display the optional success message using the TextRenderer module
            tr = GlobalServices.getTextRenderer()
            tr.write("Game saved.", 3)
            
    # Initializes the loading of a map using the MapFactory.
    # Parameter:
    #   name        :   The name of the map to be loaded
    def initMapLoading(self, name):
        # Check if there are MapProperties for this map by looking into the
        # savegame dict object.
        shelf = get_savegame()
        try:
            # Dictionary of saved map properties
            saveds = shelf['saved_maps']
            # Properties of this particular map
            properties = saveds[name]
        except KeyError:
            # No properties found
            properties = None
        # If this map hasn't been loaded yet, do so and place it inside the map dict
        if not MapFactory.mapAlreadyLoaded(name):
            # Map is loading. Change game state and notify other controllers
            # that a loading process is going on right now
            self.state = STATE_GAME_MAP_LOADING
            self.evManager.post(GameStateChangedEvent(self.state))
            
            MapFactory.loadMap(name, properties)
        else:
            # If it has already been loaded, change the map on your own
            # (no need for a 1-frame loading screen, amirite?)
            m = MapFactory.getMap(name)
            if properties is not None:
                m.setInteractives(properties.scripts, properties.objects)
            method = m.init_method
            self.changeMap(m, method)
                
    # Changes the map to the current Map object. This method is invoked whenever
    # the Game object handler receives a "MapLoadingDoneEvent". Then, the Game object
    # can change the necessary Map references and inform other controllers of the changed map!
    # Parameters:
    #   map             :   Map object to be switched to
    #   init_method     :   Method handle to the map's setup stuff, or None
    #   successload     :   Boolean depicting if the loading was successful.
    def changeMap(self, m, init_method=None, successload=True):
        # Set the teleport destination if there is one.
        # After that, change the map
        if successload:
            if self.teleport_destination is not None:
                self.player.setPosition(self.teleport_destination)
        self.teleport_destination = None
        # Set map reference and save the map in the dict
        self.currentmap = m
        # Add the player to the map
        self.currentmap.setPlayer(self.player)
        # Add the shadow to the map
        self.currentmap.setShadow(self.shadow)
        
        # Update the map objects' reference just in case
        for o in self.currentmap.objects:
            o.setMap(self.currentmap)
        for s in self.currentmap.scripts:
            s.setMap(self.currentmap)
        
        # Broadcast that the state is now "running"
        self.state = STATE_GAME_RUNNING
        self.evManager.post(GameStateChangedEvent(self.state))
        # Lastly, send a map changed event to get especially the view controller up-to-date
        self.evManager.post(MapChangedEvent(self.currentmap))
        # Address the map's setup method
        if init_method is not None:
            init_method(self.currentmap)
            
    # Checks if the window mode change can be done right now
    def fullscreenToggleRequest(self):
        if not (ScriptEngine.isRunning() and ObjectEngine.isRunning()):
            self.evManager.post(FullscreenToggleEvent())
            
    # This method switches back to the main menu. It is invoked
    # after the game is finished, or when the user selects the
    # corresponding menu item in the game menu
    def switchToMainMenu(self):
        # Pause all things
        GlobalServices.getAudioDevice().stopAll()
        # Close and delete the temporary shelf
        reset_savegame()
        # Delete the Map cache as well
        MapFactory.clearMaps()
        # Change state
        self.state = STATE_MAIN_MENU
        self.evManager.post(GameStateChangedEvent(self.state))