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()
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