示例#1
0
class Application:
    """Info: Application Class: Main Application
    Author: Pitcher, Joshua
    """
    def __init__(self, window_name, window_width, window_height):
        ###
        ### Make our RenderWindow and store window width, and height
        ### and run the misc. setup and run the program...
        ####
        self.window = sf.RenderWindow(sf.VideoMode(window_width, window_height), str(window_name), sf.Style.CLOSE)
        self.window.framerate_limit = 60
        self.window_width = window_width
        self.window_height = window_height
        self.running = True

        ###
        ### Make & Load any assets...
        ### As well as make the our pybot...
        ####
        self.font = sf.Font.from_file("data/04B_08_.TTF")
        self.text = sf.Text("Loading...", self.font, 18)
        self.help = sf.Text("...", self.font, 18)
        self.infoText = sf.Text("", self.font, 18)
        self.listString = sf.Text("Inventory:", self.font, 18)
        self.listString.position = 20, self.window_height - 180

        ###
        ### pybot...
        ####

        ### please look up 
        self.pyBotTexture = sf.Texture.from_file("data/Significon-Android-128.png")
        self.pyBot = sf.Vector2()
        self.pyBot.x = 1129
        self.pyBot.y = 359
        self.pyBotSprite = sf.Sprite(self.pyBotTexture)
        self.pyBotSprite.position = self.pyBot

        ###
        ### Misc.
        ####
        self.backgroundTexture = sf.Texture.from_file("data/factory-700591_960_720.jpg")
        self.background = sf.Sprite(self.backgroundTexture)
        self.nodeTexture = sf.Texture.from_file("data/node.png")
        self.botSpeed = 2.0
        self.nodePadding = 10
        self.nodePaddingPlacement = 80
        self.node_number_padding = 32
        self.nodeList = []
        self.visitedList = []
        self.isPathing = False
        self.NodeCount = 0
        self.TimeToWait = None
        self.Clock = sf.Clock()
        self.clockTriggered = False
        self.isOverHelp = False

        ###
        ### Show where the user can place the nodes on screen...
        ####
        self.myPathlines = sf.VertexArray(sf.PrimitiveType.LINES_STRIP, 5)
        self.myPathlines[0].position = (-1, self.window_height - 180)
        self.myPathlines[1].position = (self.window_width, self.window_height - 180)
        self.myPathlines[2].position = (-1, self.window_height - 180)
        self.myPathlines[3].position = (-1, 64)
        self.myPathlines[4].position = (self.window_width, 64)

        ###
        ### Our Sorting Interface
        ####
        self.Sorting = SortingInterface()

        ###
        ### Used to stop the 'ApplicationInterfacePrintMenu' from being spamed when the time is out...
        ####
        self.waitForNextRun = True
        ###
        ### Run our loop...
        ####
        self.__run()

    def __run(self):
        ###
        ### Run until 'running' is False...
        ####
        while self.running:
            self.__update()
            self.__run_and_render()
        self.__del__()

    def __del__(self):
        ###
        ### Out of Scope Kill the window...
        ####
        self.window.close()

    def __update(self):
        for event in self.window.events:
            ###
            ### Process window events
            ####
            if type(event) is sf.CloseEvent:
                self.running = False
                ###
                ### Kill signal exit program...
                ####
            if type(event) is sf.ResizeEvent:
                self.window.size(event.size)
                ###
                ### Resize viewport if user changed the window dimensions...
                ### (Note: User can not do this.)
                ####

            ###
            ### Left Click Mouse Event...
            ### Prevent placement of a node to close to other nodes.
            ####
            if type(event) is sf.MouseButtonEvent and event.button is sf.Mouse.LEFT and event.pressed:

                ###
                ### This is for the placement of nodes...
                ####
                isOverNode = False
                for node in self.nodeList:
                    if event.position.x > (node.x+20)-self.nodePaddingPlacement and\
                    event.position.x < (node.x+20)+self.nodePaddingPlacement and\
                    event.position.y > (node.y+20)-self.nodePaddingPlacement and\
                    event.position.y < (node.y+20)+self.nodePaddingPlacement:
                            isOverNode = True

                if isOverNode == False and event.position.y < (self.window_height - 200) and\
                   event.position.y > 100 and event.position.x > 40 and\
                   event.position.x < (self.window_width - 40):
                    tmp = Node()
                    tmp.x = (event.position.x - 20)
                    tmp.y = (event.position.y - 20)

                    guiListItems = ApplicationInterface()
                    listFromGui = guiListItems.getInventory()

                    if len(listFromGui) > 0:
                        tmp.setIteams(listFromGui)
                        tmp.setNumber(self.NodeCount)
                        self.nodeList.append(tmp)
                        self.NodeCount += 1
                    else:
                        self.infoText = sf.Text("*** You can not make an empty Node ***", self.font, 18)
                        self.infoText.position = 20, 40

                ###
                ### this is for the help box...
                ####
                if self.isOverHelp == True:
                    myHelp = ApplicationHelp()

            ###
            ### Right Click Mouse Event...
            ### Find the Node under the cursor and gets its Inventory.
            ####
            if type(event) is sf.MouseButtonEvent and event.button is sf.Mouse.RIGHT and event.pressed:
                for node in self.nodeList:
                    node.isCurrunt = False
                    if event.position.x > (node.x+20)-self.nodePadding and\
                    event.position.x < (node.x+20)+self.nodePadding and\
                    event.position.y > (node.y+20)-self.nodePadding and\
                    event.position.y < (node.y+20)+self.nodePadding:

                        tmpstr = str(node.getIteams())
                        tmpstr = re.sub('[(){}<>\'\']', '', tmpstr)
                        tmpstr = re.sub('[,]', '\n', tmpstr)
                        tmpstr = re.sub('[:]', ':  ', tmpstr)

                        self.listString = sf.Text("Inventory:\n"+ " " + str(tmpstr), self.font, 20)
                        self.listString.position = 20, self.window_height - 180
                        node.isCurrunt = True

            ###
            ### Middle Click Mouse Event...
            ### Place the pybot under the cursor location.
            ####
            if type(event) is sf.MouseButtonEvent and event.button is sf.Mouse.MIDDLE and event.pressed:
                tmp = Node()
                tmp.x = (event.position.x - 25)
                tmp.y = (event.position.y - 30)
                self.pyBot = tmp

        ###
        ### Esc key pressed exit program...
        ####
        if sf.Keyboard.is_key_pressed(sf.Keyboard.ESCAPE):
            self.running = False

        ###
        ### E keyboard key pressed start pybot...
        ####
        if sf.Keyboard.is_key_pressed(sf.Keyboard.E):
            if self.NodeCount > 1:
                self.waitForNextRun = False
                self.gui_find = ApplicationInterfaceLookFor()
                self.TimeToWait = sf.seconds(self.gui_find.getTime())
                self.Sorting.Find(self.gui_find.getItem())
                self.isPathing = True
                self.Clock.restart()
                self.clockTriggered = True
            else:
                self.infoText = sf.Text("*** You must have more then 2 nodes for pybot to function. ***", self.font, 18)
                self.infoText.position = 20, 40

        ###
        ### R keyboard key pressed pause pybot...
        ####
        if sf.Keyboard.is_key_pressed(sf.Keyboard.R):
            self.isPathing = False

    ###
    ### Run any rendering functions...
    ####
    def __run_and_render(self):
        ###
        ### Clear the render buffer...
        ####
        self.window.clear(sf.Color(88,75,72))
        self.window.draw(self.background)
        
        ###
        ### Update UI when PYBOT is running...
        ####
        self.pyBotSprite.position = self.pyBot
        if self.isPathing == True:
            self.text = sf.Text("PyBot  Running...", self.font, 20)
        else:
            self.text = sf.Text("Press 'E' to play", self.font, 20)
        self.text.position = 20, 20
        self.infoText.position = 20, 40

        ###
        ### User open the help box...
        ####
        self.help = sf.Text("HELP", self.font, 20)
        self.help.position = (self.window_width - 80), 20
        tmp = sf.Vector2
        tmp = sf.Mouse.get_position(self.window)

        ###
        ### Help Menu
        ####
        if tmp.x > self.window_width - 85 and tmp.y < 55 and tmp.y > 30:
            self.help.color = sf.Color(255, 1, 1)
            self.isOverHelp = True
        else:
            self.help.color = sf.Color.WHITE
            self.isOverHelp = False

        self.__draw_nodes()
        self.__pathing()
        self.__draw_visited_nodes()

        self.window.draw(self.pyBotSprite)
        self.window.draw(self.text)
        self.window.draw(self.listString)
        self.window.draw(self.infoText)
        self.window.draw(self.help)
        self.window.draw(self.myPathlines)
        self.window.display()

    ###
    ### Render all Node in our nodeList
    ####
    def __draw_nodes(self):
        for node in self.nodeList:

            circle = sf.Sprite(self.nodeTexture)
            tmp_node_number = sf.Text(str(node.Number), self.font, 16)
            tmp_node_number.position = (node.x + self.node_number_padding), (node.y + self.node_number_padding)
            ###
            ### Currently selected: Green
            ### Visited Node: Red
            ### Default: While
            ####
            if node.isCurrunt:
                circle.color = sf.Color(155, 155, 155)
            elif node.Visited == True:
                circle.color = sf.Color(253, 243, 231)
            else:
                circle.color = sf.Color(178, 219, 55)
            ###
            ### Draw its ID number next to it...
            ####
            circle.position = node
            self.window.draw(circle)
            self.window.draw(tmp_node_number)

    ###
    ### pyBots internal workings...
    ####
    def __pathing(self):

        mytime = self.Clock.elapsed_time
        
        if self.isPathing and mytime <= self.TimeToWait:
            self.infoText = sf.Text(str(int(mytime.seconds)), self.font, 18)
            self.infoText.position = 20, 40

            bestDistance = -1.0
            whatNode = sf.Vector2

            for node in self.nodeList:
                if node.Visited == False:
                    lines = sf.VertexArray(sf.PrimitiveType.LINES_STRIP, 2)
                    lines[0].position = (self.pyBot.x+5, self.pyBot.y+5)
                    lines[1].position = (node.x+20, node.y+20)

                    distance = math.sqrt(math.pow(((self.pyBot.x+5) - (node.x+20)),2) + math.pow(((self.pyBot.y+5) - (node.y+20)),2))
                    if (distance < bestDistance or bestDistance < 0):
                        bestDistance = distance
                        whatNode = node
                    self.window.draw(lines)

            if(bestDistance >= 0):

                if math.fabs((self.pyBot.x + 5) - (whatNode.x + 20)) < self.botSpeed:
                    self.pyBot.x = whatNode.x + 15
                else:
                    if self.pyBot.x+5 > whatNode.x+20:
                        self.pyBot.x -= self.botSpeed
                    elif self.pyBot.x+5 < whatNode.x+20:
                        self.pyBot.x += self.botSpeed

                if math.fabs((self.pyBot.y + 5) - (whatNode.y + 20)) < self.botSpeed:
                    self.pyBot.y = whatNode.y + 15
                else:
                    if self.pyBot.y+5 > whatNode.y+20:
                        self.pyBot.y -= self.botSpeed

                    elif self.pyBot.y+5 < whatNode.y+20:
                        self.pyBot.y += self.botSpeed

                whatNodeDistance = math.sqrt(math.pow(((self.pyBot.x+5) - (whatNode.x+20)),2) + math.pow(((self.pyBot.y+5) - (whatNode.y+20)),2))
                if whatNodeDistance < 3.0:
                    tmp = Node()
                    tmp = whatNode
                    tmp.Visited = True
                    self.nodeList[self.nodeList.index(whatNode)] = tmp
                    self.visitedList.append(tmp)
                    self.Sorting.Tick(tmp.getIteams(), str(tmp.Number))

                    if len(self.nodeList) == len(self.visitedList):
                        self.isPathing = False
                        self.infoText = sf.Text("All Nodes Have Been Seen...", self.font, 18)
                        self.infoText.position = 20, 40
                        
                        self.__start_sorting()
                        
        elif self.clockTriggered == True and mytime > self.TimeToWait:
            self.infoText = sf.Text("Time Is Up !", self.font, 18)
            self.infoText.position = 20, 40
            if self.waitForNextRun == False:
                self.__start_sorting()
                self.waitForNextRun = True

    ###
    ### Draw the path pybot has taken...
    ####
    def __draw_visited_nodes(self):
        lastVisited = Node()
        isFirst = True
        for visited in self.visitedList:

            if visited.Visited == True:
                if isFirst == False:
                    pathlines = sf.VertexArray(sf.PrimitiveType.LINES_STRIP, 2)
                    pathlines[0].position = (lastVisited.x+20, lastVisited.y+20)
                    pathlines[1].position = (visited.x+20, visited.y+20)
                    self.window.draw(pathlines)
                lastVisited = visited
                isFirst = False

    ###
    ### Call our sorting class, doing by function prevents code duplication.
    ### is called from '__pathing', once the time runs out or all nodes have been seen.
    ####
    def __start_sorting(self):

        ###
        ### Ask the user for the sorting method...
        ####
        tmp = ApplicationInterfacePrintMenu()
        sortCode = tmp.getSortingMethord()
        sortBy = tmp.getSortByMethord()
        useBin = tmp.isBinarySearch()

        mySort = SortingImp(self.Sorting.getList(), useBin)

        if sortCode < 3 and sortCode > -1: # its gonna be 0 or 1
            mySort.SortByValue(sortCode, sortBy)
            myOutput = mySort.getSortedList()
            myList = ApplicationInterfacePrint(myOutput)

        else:
            self.infoText = sf.Text("***You Must Picked A Sort Method***", self.font, 18)
            self.infoText.position = 20, 40
            self.__start_sorting()
示例#2
0
    def __update(self):
        for event in self.window.events:
            ###
            ### Process window events
            ####
            if type(event) is sf.CloseEvent:
                self.running = False
                ###
                ### Kill signal exit program...
                ####
            if type(event) is sf.ResizeEvent:
                self.window.size(event.size)
                ###
                ### Resize viewport if user changed the window dimensions...
                ### (Note: User can not do this.)
                ####

            ###
            ### Left Click Mouse Event...
            ### Prevent placement of a node to close to other nodes.
            ####
            if type(event) is sf.MouseButtonEvent and event.button is sf.Mouse.LEFT and event.pressed:

                ###
                ### This is for the placement of nodes...
                ####
                isOverNode = False
                for node in self.nodeList:
                    if event.position.x > (node.x+20)-self.nodePaddingPlacement and\
                    event.position.x < (node.x+20)+self.nodePaddingPlacement and\
                    event.position.y > (node.y+20)-self.nodePaddingPlacement and\
                    event.position.y < (node.y+20)+self.nodePaddingPlacement:
                            isOverNode = True

                if isOverNode == False and event.position.y < (self.window_height - 200) and\
                   event.position.y > 100 and event.position.x > 40 and\
                   event.position.x < (self.window_width - 40):
                    tmp = Node()
                    tmp.x = (event.position.x - 20)
                    tmp.y = (event.position.y - 20)

                    guiListItems = ApplicationInterface()
                    listFromGui = guiListItems.getInventory()

                    if len(listFromGui) > 0:
                        tmp.setIteams(listFromGui)
                        tmp.setNumber(self.NodeCount)
                        self.nodeList.append(tmp)
                        self.NodeCount += 1
                    else:
                        self.infoText = sf.Text("*** You can not make an empty Node ***", self.font, 18)
                        self.infoText.position = 20, 40

                ###
                ### this is for the help box...
                ####
                if self.isOverHelp == True:
                    myHelp = ApplicationHelp()

            ###
            ### Right Click Mouse Event...
            ### Find the Node under the cursor and gets its Inventory.
            ####
            if type(event) is sf.MouseButtonEvent and event.button is sf.Mouse.RIGHT and event.pressed:
                for node in self.nodeList:
                    node.isCurrunt = False
                    if event.position.x > (node.x+20)-self.nodePadding and\
                    event.position.x < (node.x+20)+self.nodePadding and\
                    event.position.y > (node.y+20)-self.nodePadding and\
                    event.position.y < (node.y+20)+self.nodePadding:

                        tmpstr = str(node.getIteams())
                        tmpstr = re.sub('[(){}<>\'\']', '', tmpstr)
                        tmpstr = re.sub('[,]', '\n', tmpstr)
                        tmpstr = re.sub('[:]', ':  ', tmpstr)

                        self.listString = sf.Text("Inventory:\n"+ " " + str(tmpstr), self.font, 20)
                        self.listString.position = 20, self.window_height - 180
                        node.isCurrunt = True

            ###
            ### Middle Click Mouse Event...
            ### Place the pybot under the cursor location.
            ####
            if type(event) is sf.MouseButtonEvent and event.button is sf.Mouse.MIDDLE and event.pressed:
                tmp = Node()
                tmp.x = (event.position.x - 25)
                tmp.y = (event.position.y - 30)
                self.pyBot = tmp

        ###
        ### Esc key pressed exit program...
        ####
        if sf.Keyboard.is_key_pressed(sf.Keyboard.ESCAPE):
            self.running = False

        ###
        ### E keyboard key pressed start pybot...
        ####
        if sf.Keyboard.is_key_pressed(sf.Keyboard.E):
            if self.NodeCount > 1:
                self.waitForNextRun = False
                self.gui_find = ApplicationInterfaceLookFor()
                self.TimeToWait = sf.seconds(self.gui_find.getTime())
                self.Sorting.Find(self.gui_find.getItem())
                self.isPathing = True
                self.Clock.restart()
                self.clockTriggered = True
            else:
                self.infoText = sf.Text("*** You must have more then 2 nodes for pybot to function. ***", self.font, 18)
                self.infoText.position = 20, 40

        ###
        ### R keyboard key pressed pause pybot...
        ####
        if sf.Keyboard.is_key_pressed(sf.Keyboard.R):
            self.isPathing = False