Ejemplo n.º 1
0
    def _Input_Update(self):
        """This will essentially execute all of the system functions that it is told to by the Input_Manager. And it will return the new lNextState variable, which
        should be ["NULL","NULL"] if a state change isn't needed."""

        #Loop through all of the inputs that are active according to the Input_Manager class
        for (sSystemFuncName, lEntities) in Input_Manager._Get_Active_Inputs():

            sNextState = self._Call_System_Func(sSystemFuncName, lEntities)

            #print sNextState

            #Only strings are allowed to be returned from the system functions and only if the state needs to be changed.
            #Otherwise, we'll just keep calling system functions and eventually return something that makes no state change occur.
            if sNextState != "NULL,NULL":

                return sNextState.split(',')

        return ["NULL","NULL"]
Ejemplo n.º 2
0
    def _Input_Update(self):
        """This will essentially execute all of the system functions that it is told to by the Input_Manager. And it will return the new lNextState variable, which
        should be ["NULL","NULL"] if a state change isn't needed."""

        #Loop through all of the inputs that are active according to the Input_Manager class
        for (sSystemFuncName, lEntities) in Input_Manager._Get_Active_Inputs():

            sNextState = self._Call_System_Func(sSystemFuncName, lEntities)

            #print sNextState

            #Only strings are allowed to be returned from the system functions and only if the state needs to be changed.
            #Otherwise, we'll just keep calling system functions and eventually return something that makes no state change occur.
            if sNextState != "NULL,NULL":

                return sNextState.split(',')

        return ["NULL", "NULL"]
Ejemplo n.º 3
0
def main():
    #Initialize the window and windowView (the windowView won't be setup until the state changes!)
    Init()
    
    #These variables will track our position within the game.
    lCurrentState = ["NULL","NULL"]
    lNextState = ["Menu","Intro"]

    #This will be updated when we change to a state.
    EntityManager = Entity_Manager()

    ChangeState(lCurrentState, lNextState, config.window, config.windowView, EntityManager)

    t = sf.Time(0.0)

    accumulator = sf.Time(0.0)
    
    MAX_FRAMESKIP = 5

    timer = sf.Clock()

    lastKeyPress = sf.Clock()

    #This will be False if the player clicks outside of the program's window and "pause" the program
    windowIsActive = True
    
    bQuit = False
    while not bQuit:

        frameTime = timer.elapsed_time

        timer.restart()

        #This caps the time inbetween frames to
        #   prevent a spiral of death (which happens when the computer
        #   can't keep up.)
        if frameTime > sf.Time(0.25):

            print "preventing spiral of death"
            frameTime = sf.Time(0.25)

        accumulator += frameTime


        #This will loop through all of the events that have been triggered by player input
        for event in config.window.iter_events():

            if event.type == sf.Event.MOUSE_MOVED:
                Input_Manager._Mouse_Has_Moved(config.window.convert_coords(event.x,event.y))

            #elif event.type == sf.Event.TEXT_ENTERED:
                #Input_Manager._Key_Input(event.unicode, True, lastKeyPress.elapsed_time)

                #This restarts the Timer for the lastKeyPress since a new key just
                #   got pressed.
                #lastKeyPress.restart()
            
            elif event.type == sf.Event.KEY_PRESSED:
                Input_Manager._Key_Input(event.code, True, lastKeyPress.elapsed_time)

                #This restarts the Timer for the lastKeyPress since a new key just
                #   got pressed.
                lastKeyPress.restart()
                
            elif event.type == sf.Event.KEY_RELEASED:
                #The time elapsed isn't necessary for the released key.
                Input_Manager._Key_Input(event.code)
            
            elif event.type == sf.Event.MOUSE_BUTTON_PRESSED:
                Input_Manager._Mouse_Input(event.button, True)
            
            elif event.type == sf.Event.MOUSE_BUTTON_RELEASED:
                Input_Manager._Mouse_Input(event.button,False)

            elif event.type == sf.Event.CLOSED:
                for stateIndx in xrange(len(lNextState)):                     
                    lNextState[stateIndx] = "QUIT"
                bQuit = True
                
            elif event.type == sf.Event.LOST_FOCUS:
                windowIsActive = False

            elif event.type == sf.Event.GAINED_FOCUS:
                windowIsActive = True

        iLoops = 0  #A counter for the amount of game update loops that are made in sucession whilst skipping rendering updates.
        
        #This loop will start if it is time to commence the next update and will keep going if we are behind schedule and need to catch up.
        while accumulator >= sf.Time(1./config.FRAME_RATE) and iLoops < MAX_FRAMESKIP:

            #This makes the program so that it basically pauses all of its game updates when a user clicks outside of the window. And it waits until the user clicks on the window.
            if windowIsActive:
                #We don't want to change lNextState if the game has been set to QUIT
                if not bQuit:                
                    #lNextState will contain "NULL"s when no state change is signaled
                    #lNextState will have all of its elements change when switching to a new state.
                    lNextState = EntityManager._Input_Update()

                    #Check to see if we have signaled to quit the game thus far
                    if lNextState[0] == "QUIT":
                        bQuit = True

                    #If one of the lNextState elements is changed, they all are (just how it goes.)
                    if lNextState[0] != "NULL" and lNextState[0] != "QUIT":
                        ChangeState(lCurrentState, lNextState, config.window, config.windowView, EntityManager)

                    #Finally after we've handled input and have correctly adjusted to the nextState (in most cases it won't happen,)
                    #we can then update our game's model with stuff that will happen in the respective state with each game update.

                    #Notice that DT is a constant variable that represents how much time is going by during
                    #   this update.
                    lNextState = EntityManager._Logic_Update(sf.Time(1./config.FRAME_RATE))

                    #Check to see if we have signaled to quit the game thus far
                    if lNextState[0] == "QUIT":
                        bQuit = True

                    #If one of the lNextState elements is changed, they all are (just how it goes.)
                    if lNextState[0] != "NULL" and lNextState[0] != "QUIT":
                        ChangeState(lCurrentState, lNextState, config.window, config.windowView, EntityManager)


            #If we have received a quit signal, we should stop our loop and quit the game!
            if bQuit:
                break


            #The accumulator contains the time that hasn't yet been used for the updates.
            #Each update will assume that dt time is going by, so the accumulator just
            #   needs to subtract by the time that is being used up.
            accumulator -= sf.Time(1./config.FRAME_RATE)
            
            #This counts the Update loop
            iLoops += 1
            
        #This makes the program so that it basically pauses all of its game updates when a user clicks outside of the window. And it waits until the user clicks on the window.
        if windowIsActive:
            EntityManager._Render_Update(config.window, config.windowView)
            
        config.window.display()

    #This closes our RenderWindow!
    config.window.close()
Ejemplo n.º 4
0
def ChangeState(lCurState, lNxtState, window, windView, EntManager):
    """This function is passed a couple lists representing the info on the different levels of this game's
    hierarchical finite state machine. This function essentially generically sets up the Entity and Asset Managers
    based off of data that can be retreived from xml files.
    @param lCurState This list contains the information on which state the program is in and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param lNxtState This list contains the information on which state the program is to be switched to and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param windView This is SFML's View object and allows us to zoom in on the what would be shown in the window. This
        essentially just gives us the option to zoom in on the stuff visible for a certain state (can be specified in xml data.)
    @param EntManager This is the entity manager and is for loading entities into the game based on the state being switched to.
        The xml data tells which entities need to be loaded for what state."""

    print "NEW STATE!", lNxtState
    #The data will lie within the nextState[0]+".txt" file and the nextState[1] element within that elemthe ent.
    tree = parse("StateData/%s/%s.xml"%(lNxtState[0],lNxtState[1]))
    
    #The root element and the element containing the entities we need will be using this variable.
    root = tree.getroot()


    #This will reset the windowView's dimensions within the actual window with respect to the new state
    #windView.reset(sf.FloatRect((window.width - int(root.find('viewWidth').text))/2, \
    #            (window.height - int(root.find('viewHeight').text))/2,   \
    #            int(root.find('viewWidth').text),    \
    #            int(root.find('viewHeight').text)))

    #print float(root.find('viewWidthRatio').text)

    print "The new view's stats:\nx:%f\ny:%f\nwidth:%f\nheight:%f"%(int(window.width - int(window.width*float(root.find('viewWidthRatio').text)))/2,     \
                                int(window.height - int(window.height*float(root.find('viewHeightRatio').text)))/2,  \
                                int(window.width*float(root.find('viewWidthRatio').text)),                           \
                                int(window.height*float(root.find('viewHeightRatio').text)))
    
    windView.reset(sf.FloatRect((window.width - int(window.width*float(root.find('viewWidthRatio').text)))/2,     \
                                (window.height - int(window.height*float(root.find('viewHeightRatio').text)))/2,  \
                                window.width*float(root.find('viewWidthRatio').text),                           \
                                window.height*float(root.find('viewHeightRatio').text)))
    
    config.Tile_Width = window.width / (config.CHUNK_TILES_WIDE*2.)
    config.Tile_Height = window.height / (config.CHUNK_TILES_HIGH*2.)

    print "TileWidth is %f and TileHeight is %f"%(config.Tile_Width, config.Tile_Height)
    print "Window dimensions are %d x %d"%(window.width, window.height)
    
    #windView.reset(sf.FloatRect(int(window.width - window.width*float(root.find('viewWidthRatio').text)/2), \
    #                int(window.height - window.height*float(root.find('viewHeightRatio').text)/2),            \
    #                int(window.width*float(root.find('viewWidthRatio').text)),               \
    #                int(window.height*float(root.find('viewHeightRatio').text))))

    #This clears all of the things that in the game since the last state
    EntManager._Empty_Entity_Containers()
    AstManager._Empty_Assets()
    Input_Manager._Empty_Inputs()
    System_Manager._Empty_Systems()

    for entity in root.findall('Entity'):

        entityInstance = GetEntityBlueprints(entity)

        EntManager._Add_Entity(entityInstance)

            
    #Each one of these nodes will be an input that will be initialized for the state that is being loaded (and a multitude of kinds.)
    for inpoot in root.findall("Input"):

        #print inpoot.attrib

        #Check to see if this input's type is a hotspot.
        if inpoot.attrib["type"] == "hotspot":
            Input_Manager._Add_Hotspot(inpoot.find("x").text, inpoot.find("y").text, inpoot.find("width").text, inpoot.find("height").text, \
                                       inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,    \
                                       inpoot.find("OnSelected").find("system").text if inpoot.find("OnSelected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnSelected"), \
                                       inpoot.find("OnDeselected").find("system").text if inpoot.find("OnDeselected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnDeselected"), \
                                       inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnPressed"), \
                                       inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                       AssembleEntityInfo(inpoot, "OnReleased"))

        #Check to see if thisinput's type is a action.
        elif inpoot.attrib["type"] == "key":
            #This will add a key_Listener to our Input_Manager given the attribute data from the inpoot elemenet from the xml file.
            Input_Manager._Add_Key_Listener(inpoot.find("key").text,    \
                                            inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,  \
                                            inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnPressed"),    \
                                            inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnReleased"))

        elif inpoot.attrib["type"] == "mouse":
            Input_Manager._Add_Mouse_Listener(inpoot.find("button").text,             \
                                              inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,  \
                                              inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,   \
                                              AssembleEntityInfo(inpoot, "OnPressed"),    \
                                              inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                              AssembleEntityInfo(inpoot, "OnReleased"))

    #These are the systems that are relevant to this state and they will be added into the System_Queue class.
    for system in root.findall("System"):
        
        #This will load a system into the System_Queue and then it will be activated next update.
        System_Manager._Add_System(system.find("type").text, system.find("systemFunc").text,  AssembleEntityInfo(system))
        
            
    #Now we gotta update the state variables so that we aren't signaling to change states anymore
    for i in xrange(len(lCurState)):
        lCurState[i] = lNxtState[i]
        lNxtState[i] = "NULL"
Ejemplo n.º 5
0
def main():
    #Initialize the window and windowView (the windowView won't be setup until the state changes!)
    window, windowView = Init()
    
    #These variables will track our position within the game.
    lCurrentState = ["NULL","NULL"]
    lNextState = ["Menu","MainMenu"]

    #This will be updated when we change to a state.
    EntityManager = Entity_Manager()

    #The AssetManager will be used by ChangeState in order to retrieve sounds/textures for a particular type of entity.
    AssetManager = assets.Asset_Manager()

    ChangeState(lCurrentState, lNextState, windowView, EntityManager, AssetManager)

    timer = sf.Clock()
    
    SKIP_TICKS = 1/config.TICKS_PER_SEC
    MAX_FRAMESKIP = 5
    
    iLoops = None
    fNextGameTick = timer.elapsed_time

    #This will be False if the player clicks outside of the program's window and "pause" the program
    windowIsActive = True
    
    bQuit = False
    while not bQuit:
    
        #This will loop through all of the events that have been triggered by player input
        for event in window.iter_events():

            if event.type == sf.Event.MOUSE_MOVED:
                Input_Manager._Mouse_Has_Moved(window.convert_coords(event.x,event.y))

            elif event.type == sf.Event.TEXT_ENTERED:
                Input_Manager._Key_Input(event.unicode, True, timer.elapsed_time)
            
            elif event.type == sf.Event.KEY_PRESSED:
                Input_Manager._Key_Input(event.code, True, timer.elapsed_time)
                
            elif event.type == sf.Event.KEY_RELEASED:
                Input_Manager._Key_Input(event.code, False, timer.elapsed_time)
            
            elif event.type == sf.Event.MOUSE_BUTTON_PRESSED:
                Input_Manager._Mouse_Input(event.button, True)
            
            elif event.type == sf.Event.MOUSE_BUTTON_RELEASED:
                Input_Manager._Mouse_Input(event.button,False)
                
            elif event.type == sf.Event.LOST_FOCUS:
                windowIsActive = False

            elif event.type == sf.Event.GAINED_FOCUS:
                windowIsActive = True
                
            elif event.type == sf.Event.CLOSED:
                for stateIndx in xrange(len(lNextState)):                     
                    lNextState[stateIndx] = "QUIT"
                bQuit = True


        iLoops = 0  #A counter for the amount of game update loops that are made in sucession whilst skipping rendering updates.
        
        #This loop will start if it is time to commence the next update and will keep going if we are behind schedule and need to catch up.
        while timer.elapsed_time > fNextGameTick and iLoops < MAX_FRAMESKIP:
    
            #This makes the program so that it basically pauses all of its game updates when a user clicks outside of the window. And it waits until the user clicks on the window.
            if windowIsActive:

                #We don't want to change lNextState if the game has been set to QUIT
                if not bQuit:
                
                    #lNextState will contain "NULL"s when no state change is signaled
                    #lNextState will have all of its elements change when switching to a new state.
                    lNextState = EntityManager._Input_Update()

                    #Check to see if we have signaled to quit the game thus far
                    if lNextState[0] == "QUIT":
                        bQuit = True

                    #If one of the lNextState elements is changed, they all are (just how it goes.)
                    if lNextState[0] != "NULL" and lNextState[0] != "QUIT":
                        ChangeState(lCurrentState, lNextState, windowView, EntityManager, AssetManager)

                #Finally after we've handled input and have correctly adjusted to the nextState (in most cases it won't happen,)
                #we can then update our game's model with stuff that will happen in the respective state with each game update.
                if not bQuit:
                    EntityManager._Logic_Update(timer.elapsed_time - fNextGameTick)           #This updates our model depending on what is going on in the current state

            #If we have received a quit signal, we should stop our loop and quit the game!
            if bQuit:
                break
                
            iLoops += 1
            fNextGameTick += sf.Time(seconds=SKIP_TICKS)

        EntityManager._Render_Update(window, windowView)
        window.display()

    #This closes our RenderWindow!
    window.close()
Ejemplo n.º 6
0
def ChangeState(lCurState, lNxtState, windView, EntManager, AstManager):
    """This function is passed a couple lists representing the info on the different levels of this game's
    hierarchical finite state machine. This function essentially generically sets up the Entity and Asset Managers
    based off of data that can be retreived from xml files.
    @param lCurState This list contains the information on which state the program is in and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param lNxtState This list contains the information on which state the program is to be switched to and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param windView This is SFML's View object and allows us to zoom in on the what would be shown in the window. This
        essentially just gives us the option to zoom in on the stuff visible for a certain state (can be specified in xml data.)
    @param EntManager This is the entity manager and is for loading entities into the game based on the state being switched to.
        The xml data tells which entities need to be loaded for what state.
    @param AstManager This is the asset manager and it is for loading in assets that are needed by entities. The xml data
        specifies what assets are to be fetched and used for the assembling of each entity. Once an asset is fetched once,
        it won't need to be loaded the second time because it's stored in the AstManager."""

    print "NEW STATE!", lNxtState
    #The data will lie within the nextState[0]+".txt" file and the nextState[1] element within that elemthe ent.
    tree = parse("StateData/StateInit.xml")
    
    #The root element and the element containing the entities we need will be using this variable.
    root = tree.getroot()

    if root.find(lNxtState[0]) != None:
        #This changes the node to the one that represents the state we're switching to.
        root = root.find(lNxtState[0]).find(lNxtState[1])
        
        if root == None:
            print "There was a problem finding %s in the StateInit.xml file."%(lNxtState[1])
    else:
        print "There was a problem finding %s in the StateInit.xml file."%(lNxtState[0])

    #This will reset the windowView's dimensions within the actual window with respect to the new state
    windView.reset(sf.FloatRect(int(int(root.find('viewWidth').text)//4), \
                int(int(root.find('viewHeight').text)//4),   \
                int(int(root.find('viewWidth').text)//2),    \
                int(int(root.find('viewHeight').text)//2)))

    #This clears all of the things that in the game since the last state
    EntManager._Empty_Entity_Containers()
    AstManager._Empty_Assets()
    Input_Manager._Empty_Inputs()
    System_Manager._Empty_Systems()

    for entity in root.findall('Entity'):

        entityInstance = None

        #This checks to see if there is a function that exists that will assemble this entity.
        if entity.find('assembleFunc') != None:

            #This will hold all of the attributes needed to assemble the entity (using the xml files to get the data later on.)
            dEntityAttribs = {}

            #This will loop through all of the attribute names for each entity.
            for attrib in entity.find('Attributes').getiterator():
                
                #Check to see if this is a sound for the entity!
                if attrib.tag == 'Sound':
                    #THis will start a new list of Sounds if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    #Query the AssetManager for a sound that is associated with this entity, then throw that into the dictionary of attributes!
                    dEntityAttribs[attrib.tag].append(AstManager._Get_Sound(attrib.attrib['name']))

                elif attrib.tag == 'Music':

                    #THis will start a new list of Musics if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    dEntityAttribs[attrib.tag].append(AstManager._Get_Music(attrib.attrib['name']))

                #Check to see if this is a texture for the entitititity.
                elif attrib.tag == 'Texture':

                    #THis will start a new list of Textures if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    #Query the AssetManager for a texture that is associated with this entity, then throw that into the dictionary of attributes!
                    dEntityAttribs[attrib.tag].append(AstManager._Get_Texture(attrib.attrib['name']))

                #Check to see if this is a font for the entitititity.
                elif attrib.tag == 'Font':

                    #THis will start a new list of Fonts if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    #Query the AssetManager for a font that is associated with this entity, then throw that into the dictionary of attributes!
                    dEntityAttribs[attrib.tag].append(AstManager._Get_Font(attrib.attrib['name']))

                else:
                    #Anything else will just be put in the dictionary as an attribute
                    dEntityAttribs[attrib.tag] = attrib.text

            module = importlib.import_module('entities')

            assembleFunc = getattr(module, entity.find('assembleFunc').text)
               
            #Here we're using the Assemble*() function associated with the name of this entity to assemble the entity so that
            #we can add it to the EntityManager.
            #And all Assemble*() functions will use the same arguments(using a dictionary to allow dynamic arguments.)
            entityInstance = assembleFunc(entity.attrib['name'], entity.attrib['type'], dEntityAttribs)

        else:
            #Here we will add in a default entity instance.
            entityInstance = entities.Entity(entity.attrib['name'], entity.attrib['type'],{})
        
        #THis adds in the components that exist in the xml file for this entity (it allows custom/variations of entities to exist.)
        for component in entity.findall('Component'):

            #These are for getting the actual 
            module = importlib.import_module('components')

            componentClass = getattr(module, component.attrib['name'])

            #This will add in a component into the entity we just created.
            #And note that it is giving the component a dictionary of the data in the xml files.
            entityInstance._Add_Component(componentClass({DataTag.tag: DataTag.text for DataTag in component.getiterator()}))

        EntManager._Add_Entity(entityInstance)

            
    #Each one of these nodes will be an input that will be initialized for the state that is being loaded (and a multitude of kinds.)
    for inpoot in root.findall("Input"):

        #Check to see if this input's type is a hotspot.
        if inpoot.attrib["type"] == "hotspot":
            Input_Manager._Add_Hotspot(inpoot.find("x").text, inpoot.find("y").text, inpoot.find("width").text, inpoot.find("height").text, \
                                       inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,    \
                                       inpoot.find("OnSelected").find("system").text if inpoot.find("OnSelected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnSelected"), \
                                       inpoot.find("OnDeselected").find("system").text if inpoot.find("OnDeselected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnDeselected"), \
                                       inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnPressed"), \
                                       inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                       AssembleEntityInfo(inpoot, "OnReleased"))

        #Check to see if thisinput's type is a action.
        elif inpoot.attrib["type"] == "key":
            #This will add a key_Listener to our Input_Manager given the attribute data from the inpoot elemenet from the xml file.
            Input_Manager._Add_Key_Listener(inpoot.find("key").text,    \
                                            inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,  \
                                            inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnPressed"),    \
                                            inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnReleased"))

        elif inpoot.attrib["type"] == "mouse":
            pass

    #These are the systems that are relevant to this state and they will be added into the System_Queue class.
    for system in root.findall("System"):

        #This will load a system into the System_Queue and then it will be activated next update.
        systems.System_Queue._Add_System(system.find("type").text, system.find("system").text, AssembleEntityInfo(root))
        
            
    #Now we gotta update the state variables so that we aren't signaling to change states anymore
    for i in xrange(len(lCurState)):
        lCurState[i] = lNxtState[i]
        lNxtState[i] = "NULL"
Ejemplo n.º 7
0
def main():
    #Initialize the window and windowView (the windowView won't be setup until the state changes!)
    window, windowView = Init()

    #These variables will track our position within the game.
    lCurrentState = ["NULL", "NULL"]
    lNextState = ["Menu", "MainMenu"]

    #This will be updated when we change to a state.
    EntityManager = Entity_Manager()

    #The AssetManager will be used by ChangeState in order to retrieve sounds/textures for a particular type of entity.
    AssetManager = assets.Asset_Manager()

    ChangeState(lCurrentState, lNextState, windowView, EntityManager,
                AssetManager)

    timer = sf.Clock()

    SKIP_TICKS = 1 / config.TICKS_PER_SEC
    MAX_FRAMESKIP = 5

    iLoops = None
    fNextGameTick = timer.elapsed_time

    #This will be False if the player clicks outside of the program's window and "pause" the program
    windowIsActive = True

    bQuit = False
    while not bQuit:

        #This will loop through all of the events that have been triggered by player input
        for event in window.iter_events():

            if event.type == sf.Event.MOUSE_MOVED:
                Input_Manager._Mouse_Has_Moved(
                    window.convert_coords(event.x, event.y))

            elif event.type == sf.Event.TEXT_ENTERED:
                Input_Manager._Key_Input(event.unicode, True,
                                         timer.elapsed_time)

            elif event.type == sf.Event.KEY_PRESSED:
                Input_Manager._Key_Input(event.code, True, timer.elapsed_time)

            elif event.type == sf.Event.KEY_RELEASED:
                Input_Manager._Key_Input(event.code, False, timer.elapsed_time)

            elif event.type == sf.Event.MOUSE_BUTTON_PRESSED:
                Input_Manager._Mouse_Input(event.button, True)

            elif event.type == sf.Event.MOUSE_BUTTON_RELEASED:
                Input_Manager._Mouse_Input(event.button, False)

            elif event.type == sf.Event.LOST_FOCUS:
                windowIsActive = False

            elif event.type == sf.Event.GAINED_FOCUS:
                windowIsActive = True

            elif event.type == sf.Event.CLOSED:
                for stateIndx in xrange(len(lNextState)):
                    lNextState[stateIndx] = "QUIT"
                bQuit = True

        iLoops = 0  #A counter for the amount of game update loops that are made in sucession whilst skipping rendering updates.

        #This loop will start if it is time to commence the next update and will keep going if we are behind schedule and need to catch up.
        while timer.elapsed_time > fNextGameTick and iLoops < MAX_FRAMESKIP:

            #This makes the program so that it basically pauses all of its game updates when a user clicks outside of the window. And it waits until the user clicks on the window.
            if windowIsActive:

                #We don't want to change lNextState if the game has been set to QUIT
                if not bQuit:

                    #lNextState will contain "NULL"s when no state change is signaled
                    #lNextState will have all of its elements change when switching to a new state.
                    lNextState = EntityManager._Input_Update()

                    #Check to see if we have signaled to quit the game thus far
                    if lNextState[0] == "QUIT":
                        bQuit = True

                    #If one of the lNextState elements is changed, they all are (just how it goes.)
                    if lNextState[0] != "NULL" and lNextState[0] != "QUIT":
                        ChangeState(lCurrentState, lNextState, windowView,
                                    EntityManager, AssetManager)

                #Finally after we've handled input and have correctly adjusted to the nextState (in most cases it won't happen,)
                #we can then update our game's model with stuff that will happen in the respective state with each game update.
                if not bQuit:
                    EntityManager._Logic_Update(
                        timer.elapsed_time - fNextGameTick
                    )  #This updates our model depending on what is going on in the current state

            #If we have received a quit signal, we should stop our loop and quit the game!
            if bQuit:
                break

            iLoops += 1
            fNextGameTick += sf.Time(seconds=SKIP_TICKS)

        EntityManager._Render_Update(window, windowView)
        window.display()

    #This closes our RenderWindow!
    window.close()
Ejemplo n.º 8
0
def ChangeState(lCurState, lNxtState, windView, EntManager, AstManager):
    """This function is passed a couple lists representing the info on the different levels of this game's
    hierarchical finite state machine. This function essentially generically sets up the Entity and Asset Managers
    based off of data that can be retreived from xml files.
    @param lCurState This list contains the information on which state the program is in and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param lNxtState This list contains the information on which state the program is to be switched to and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param windView This is SFML's View object and allows us to zoom in on the what would be shown in the window. This
        essentially just gives us the option to zoom in on the stuff visible for a certain state (can be specified in xml data.)
    @param EntManager This is the entity manager and is for loading entities into the game based on the state being switched to.
        The xml data tells which entities need to be loaded for what state.
    @param AstManager This is the asset manager and it is for loading in assets that are needed by entities. The xml data
        specifies what assets are to be fetched and used for the assembling of each entity. Once an asset is fetched once,
        it won't need to be loaded the second time because it's stored in the AstManager."""

    print "NEW STATE!", lNxtState
    #The data will lie within the nextState[0]+".txt" file and the nextState[1] element within that elemthe ent.
    tree = parse("StateData/StateInit.xml")

    #The root element and the element containing the entities we need will be using this variable.
    root = tree.getroot()

    if root.find(lNxtState[0]) != None:
        #This changes the node to the one that represents the state we're switching to.
        root = root.find(lNxtState[0]).find(lNxtState[1])

        if root == None:
            print "There was a problem finding %s in the StateInit.xml file." % (
                lNxtState[1])
    else:
        print "There was a problem finding %s in the StateInit.xml file." % (
            lNxtState[0])

    #This will reset the windowView's dimensions within the actual window with respect to the new state
    windView.reset(sf.FloatRect(int(int(root.find('viewWidth').text)//4), \
                int(int(root.find('viewHeight').text)//4),   \
                int(int(root.find('viewWidth').text)//2),    \
                int(int(root.find('viewHeight').text)//2)))

    #This clears all of the things that in the game since the last state
    EntManager._Empty_Entity_Containers()
    AstManager._Empty_Assets()
    Input_Manager._Empty_Inputs()
    System_Manager._Empty_Systems()

    for entity in root.findall('Entity'):

        entityInstance = None

        #This checks to see if there is a function that exists that will assemble this entity.
        if entity.find('assembleFunc') != None:

            #This will hold all of the attributes needed to assemble the entity (using the xml files to get the data later on.)
            dEntityAttribs = {}

            #This will loop through all of the attribute names for each entity.
            for attrib in entity.find('Attributes').getiterator():

                #Check to see if this is a sound for the entity!
                if attrib.tag == 'Sound':
                    #THis will start a new list of Sounds if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    #Query the AssetManager for a sound that is associated with this entity, then throw that into the dictionary of attributes!
                    dEntityAttribs[attrib.tag].append(
                        AstManager._Get_Sound(attrib.attrib['name']))

                elif attrib.tag == 'Music':

                    #THis will start a new list of Musics if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    dEntityAttribs[attrib.tag].append(
                        AstManager._Get_Music(attrib.attrib['name']))

                #Check to see if this is a texture for the entitititity.
                elif attrib.tag == 'Texture':

                    #THis will start a new list of Textures if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    #Query the AssetManager for a texture that is associated with this entity, then throw that into the dictionary of attributes!
                    dEntityAttribs[attrib.tag].append(
                        AstManager._Get_Texture(attrib.attrib['name']))

                #Check to see if this is a font for the entitititity.
                elif attrib.tag == 'Font':

                    #THis will start a new list of Fonts if we haven't already loaded a sound into this entity's attributes.
                    if dEntityAttribs.get(attrib.tag, None) == None:
                        dEntityAttribs[attrib.tag] = []

                    #Query the AssetManager for a font that is associated with this entity, then throw that into the dictionary of attributes!
                    dEntityAttribs[attrib.tag].append(
                        AstManager._Get_Font(attrib.attrib['name']))

                else:
                    #Anything else will just be put in the dictionary as an attribute
                    dEntityAttribs[attrib.tag] = attrib.text

            module = importlib.import_module('entities')

            assembleFunc = getattr(module, entity.find('assembleFunc').text)

            #Here we're using the Assemble*() function associated with the name of this entity to assemble the entity so that
            #we can add it to the EntityManager.
            #And all Assemble*() functions will use the same arguments(using a dictionary to allow dynamic arguments.)
            entityInstance = assembleFunc(entity.attrib['name'],
                                          entity.attrib['type'],
                                          dEntityAttribs)

        else:
            #Here we will add in a default entity instance.
            entityInstance = entities.Entity(entity.attrib['name'],
                                             entity.attrib['type'], {})

        #THis adds in the components that exist in the xml file for this entity (it allows custom/variations of entities to exist.)
        for component in entity.findall('Component'):

            #These are for getting the actual
            module = importlib.import_module('components')

            componentClass = getattr(module, component.attrib['name'])

            #This will add in a component into the entity we just created.
            #And note that it is giving the component a dictionary of the data in the xml files.
            entityInstance._Add_Component(
                componentClass({
                    DataTag.tag: DataTag.text
                    for DataTag in component.getiterator()
                }))

        EntManager._Add_Entity(entityInstance)

    #Each one of these nodes will be an input that will be initialized for the state that is being loaded (and a multitude of kinds.)
    for inpoot in root.findall("Input"):

        #Check to see if this input's type is a hotspot.
        if inpoot.attrib["type"] == "hotspot":
            Input_Manager._Add_Hotspot(inpoot.find("x").text, inpoot.find("y").text, inpoot.find("width").text, inpoot.find("height").text, \
                                       inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,    \
                                       inpoot.find("OnSelected").find("system").text if inpoot.find("OnSelected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnSelected"), \
                                       inpoot.find("OnDeselected").find("system").text if inpoot.find("OnDeselected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnDeselected"), \
                                       inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnPressed"), \
                                       inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                       AssembleEntityInfo(inpoot, "OnReleased"))

        #Check to see if thisinput's type is a action.
        elif inpoot.attrib["type"] == "key":
            #This will add a key_Listener to our Input_Manager given the attribute data from the inpoot elemenet from the xml file.
            Input_Manager._Add_Key_Listener(inpoot.find("key").text,    \
                                            inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,  \
                                            inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnPressed"),    \
                                            inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnReleased"))

        elif inpoot.attrib["type"] == "mouse":
            pass

    #These are the systems that are relevant to this state and they will be added into the System_Queue class.
    for system in root.findall("System"):

        #This will load a system into the System_Queue and then it will be activated next update.
        systems.System_Queue._Add_System(
            system.find("type").text,
            system.find("system").text, AssembleEntityInfo(root))

    #Now we gotta update the state variables so that we aren't signaling to change states anymore
    for i in xrange(len(lCurState)):
        lCurState[i] = lNxtState[i]
        lNxtState[i] = "NULL"
Ejemplo n.º 9
0
def main():
    #Initialize the window and windowView (the windowView won't be setup until the state changes!)
    Init()

    #These variables will track our position within the game.
    lCurrentState = ["NULL", "NULL"]
    lNextState = ["Menu", "Intro"]

    #This will be updated when we change to a state.
    EntityManager = Entity_Manager()

    ChangeState(lCurrentState, lNextState, config.window, config.windowView,
                EntityManager)

    t = sf.Time(0.0)

    accumulator = sf.Time(0.0)

    MAX_FRAMESKIP = 5

    timer = sf.Clock()

    lastKeyPress = sf.Clock()

    #This will be False if the player clicks outside of the program's window and "pause" the program
    windowIsActive = True

    bQuit = False
    while not bQuit:

        frameTime = timer.elapsed_time

        timer.restart()

        #This caps the time inbetween frames to
        #   prevent a spiral of death (which happens when the computer
        #   can't keep up.)
        if frameTime > sf.Time(0.25):

            print "preventing spiral of death"
            frameTime = sf.Time(0.25)

        accumulator += frameTime

        #This will loop through all of the events that have been triggered by player input
        for event in config.window.iter_events():

            if event.type == sf.Event.MOUSE_MOVED:
                Input_Manager._Mouse_Has_Moved(
                    config.window.convert_coords(event.x, event.y))

            #elif event.type == sf.Event.TEXT_ENTERED:
            #Input_Manager._Key_Input(event.unicode, True, lastKeyPress.elapsed_time)

            #This restarts the Timer for the lastKeyPress since a new key just
            #   got pressed.
            #lastKeyPress.restart()

            elif event.type == sf.Event.KEY_PRESSED:
                Input_Manager._Key_Input(event.code, True,
                                         lastKeyPress.elapsed_time)

                #This restarts the Timer for the lastKeyPress since a new key just
                #   got pressed.
                lastKeyPress.restart()

            elif event.type == sf.Event.KEY_RELEASED:
                #The time elapsed isn't necessary for the released key.
                Input_Manager._Key_Input(event.code)

            elif event.type == sf.Event.MOUSE_BUTTON_PRESSED:
                Input_Manager._Mouse_Input(event.button, True)

            elif event.type == sf.Event.MOUSE_BUTTON_RELEASED:
                Input_Manager._Mouse_Input(event.button, False)

            elif event.type == sf.Event.CLOSED:
                for stateIndx in xrange(len(lNextState)):
                    lNextState[stateIndx] = "QUIT"
                bQuit = True

            elif event.type == sf.Event.LOST_FOCUS:
                windowIsActive = False

            elif event.type == sf.Event.GAINED_FOCUS:
                windowIsActive = True

        iLoops = 0  #A counter for the amount of game update loops that are made in sucession whilst skipping rendering updates.

        #This loop will start if it is time to commence the next update and will keep going if we are behind schedule and need to catch up.
        while accumulator >= sf.Time(
                1. / config.FRAME_RATE) and iLoops < MAX_FRAMESKIP:

            #This makes the program so that it basically pauses all of its game updates when a user clicks outside of the window. And it waits until the user clicks on the window.
            if windowIsActive:
                #We don't want to change lNextState if the game has been set to QUIT
                if not bQuit:
                    #lNextState will contain "NULL"s when no state change is signaled
                    #lNextState will have all of its elements change when switching to a new state.
                    lNextState = EntityManager._Input_Update()

                    #Check to see if we have signaled to quit the game thus far
                    if lNextState[0] == "QUIT":
                        bQuit = True

                    #If one of the lNextState elements is changed, they all are (just how it goes.)
                    if lNextState[0] != "NULL" and lNextState[0] != "QUIT":
                        ChangeState(lCurrentState, lNextState, config.window,
                                    config.windowView, EntityManager)

                    #Finally after we've handled input and have correctly adjusted to the nextState (in most cases it won't happen,)
                    #we can then update our game's model with stuff that will happen in the respective state with each game update.

                    #Notice that DT is a constant variable that represents how much time is going by during
                    #   this update.
                    lNextState = EntityManager._Logic_Update(
                        sf.Time(1. / config.FRAME_RATE))

                    #Check to see if we have signaled to quit the game thus far
                    if lNextState[0] == "QUIT":
                        bQuit = True

                    #If one of the lNextState elements is changed, they all are (just how it goes.)
                    if lNextState[0] != "NULL" and lNextState[0] != "QUIT":
                        ChangeState(lCurrentState, lNextState, config.window,
                                    config.windowView, EntityManager)

            #If we have received a quit signal, we should stop our loop and quit the game!
            if bQuit:
                break

            #The accumulator contains the time that hasn't yet been used for the updates.
            #Each update will assume that dt time is going by, so the accumulator just
            #   needs to subtract by the time that is being used up.
            accumulator -= sf.Time(1. / config.FRAME_RATE)

            #This counts the Update loop
            iLoops += 1

        #This makes the program so that it basically pauses all of its game updates when a user clicks outside of the window. And it waits until the user clicks on the window.
        if windowIsActive:
            EntityManager._Render_Update(config.window, config.windowView)

        config.window.display()

    #This closes our RenderWindow!
    config.window.close()
Ejemplo n.º 10
0
def ChangeState(lCurState, lNxtState, window, windView, EntManager):
    """This function is passed a couple lists representing the info on the different levels of this game's
    hierarchical finite state machine. This function essentially generically sets up the Entity and Asset Managers
    based off of data that can be retreived from xml files.
    @param lCurState This list contains the information on which state the program is in and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param lNxtState This list contains the information on which state the program is to be switched to and it takes acount into
        sub-states. So each element of the list is a sub-state of the previous element.
    @param windView This is SFML's View object and allows us to zoom in on the what would be shown in the window. This
        essentially just gives us the option to zoom in on the stuff visible for a certain state (can be specified in xml data.)
    @param EntManager This is the entity manager and is for loading entities into the game based on the state being switched to.
        The xml data tells which entities need to be loaded for what state."""

    print "NEW STATE!", lNxtState
    #The data will lie within the nextState[0]+".txt" file and the nextState[1] element within that elemthe ent.
    tree = parse("StateData/%s/%s.xml" % (lNxtState[0], lNxtState[1]))

    #The root element and the element containing the entities we need will be using this variable.
    root = tree.getroot()

    #This will reset the windowView's dimensions within the actual window with respect to the new state
    #windView.reset(sf.FloatRect((window.width - int(root.find('viewWidth').text))/2, \
    #            (window.height - int(root.find('viewHeight').text))/2,   \
    #            int(root.find('viewWidth').text),    \
    #            int(root.find('viewHeight').text)))

    #print float(root.find('viewWidthRatio').text)

    print "The new view's stats:\nx:%f\ny:%f\nwidth:%f\nheight:%f"%(int(window.width - int(window.width*float(root.find('viewWidthRatio').text)))/2,     \
                                int(window.height - int(window.height*float(root.find('viewHeightRatio').text)))/2,  \
                                int(window.width*float(root.find('viewWidthRatio').text)),                           \
                                int(window.height*float(root.find('viewHeightRatio').text)))

    windView.reset(sf.FloatRect((window.width - int(window.width*float(root.find('viewWidthRatio').text)))/2,     \
                                (window.height - int(window.height*float(root.find('viewHeightRatio').text)))/2,  \
                                window.width*float(root.find('viewWidthRatio').text),                           \
                                window.height*float(root.find('viewHeightRatio').text)))

    config.Tile_Width = window.width / (config.CHUNK_TILES_WIDE * 2.)
    config.Tile_Height = window.height / (config.CHUNK_TILES_HIGH * 2.)

    print "TileWidth is %f and TileHeight is %f" % (config.Tile_Width,
                                                    config.Tile_Height)
    print "Window dimensions are %d x %d" % (window.width, window.height)

    #windView.reset(sf.FloatRect(int(window.width - window.width*float(root.find('viewWidthRatio').text)/2), \
    #                int(window.height - window.height*float(root.find('viewHeightRatio').text)/2),            \
    #                int(window.width*float(root.find('viewWidthRatio').text)),               \
    #                int(window.height*float(root.find('viewHeightRatio').text))))

    #This clears all of the things that in the game since the last state
    EntManager._Empty_Entity_Containers()
    AstManager._Empty_Assets()
    Input_Manager._Empty_Inputs()
    System_Manager._Empty_Systems()

    for entity in root.findall('Entity'):

        entityInstance = GetEntityBlueprints(entity)

        EntManager._Add_Entity(entityInstance)

    #Each one of these nodes will be an input that will be initialized for the state that is being loaded (and a multitude of kinds.)
    for inpoot in root.findall("Input"):

        #print inpoot.attrib

        #Check to see if this input's type is a hotspot.
        if inpoot.attrib["type"] == "hotspot":
            Input_Manager._Add_Hotspot(inpoot.find("x").text, inpoot.find("y").text, inpoot.find("width").text, inpoot.find("height").text, \
                                       inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,    \
                                       inpoot.find("OnSelected").find("system").text if inpoot.find("OnSelected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnSelected"), \
                                       inpoot.find("OnDeselected").find("system").text if inpoot.find("OnDeselected") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnDeselected"), \
                                       inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,    \
                                       AssembleEntityInfo(inpoot, "OnPressed"), \
                                       inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                       AssembleEntityInfo(inpoot, "OnReleased"))

        #Check to see if thisinput's type is a action.
        elif inpoot.attrib["type"] == "key":
            #This will add a key_Listener to our Input_Manager given the attribute data from the inpoot elemenet from the xml file.
            Input_Manager._Add_Key_Listener(inpoot.find("key").text,    \
                                            inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,  \
                                            inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnPressed"),    \
                                            inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                            AssembleEntityInfo(inpoot, "OnReleased"))

        elif inpoot.attrib["type"] == "mouse":
            Input_Manager._Add_Mouse_Listener(inpoot.find("button").text,             \
                                              inpoot.find("OnPressed").find("type").text if inpoot.find("OnPressed") != None else None,  \
                                              inpoot.find("OnPressed").find("system").text if inpoot.find("OnPressed") != None else None,   \
                                              AssembleEntityInfo(inpoot, "OnPressed"),    \
                                              inpoot.find("OnReleased").find("system").text if inpoot.find("OnReleased") != None else None,   \
                                              AssembleEntityInfo(inpoot, "OnReleased"))

    #These are the systems that are relevant to this state and they will be added into the System_Queue class.
    for system in root.findall("System"):

        #This will load a system into the System_Queue and then it will be activated next update.
        System_Manager._Add_System(
            system.find("type").text,
            system.find("systemFunc").text, AssembleEntityInfo(system))

    #Now we gotta update the state variables so that we aren't signaling to change states anymore
    for i in xrange(len(lCurState)):
        lCurState[i] = lNxtState[i]
        lNxtState[i] = "NULL"