class GeoGame(Frame): def __init__(self, master): self.master = master self.master.title("GeoGame") self.master.protocol('WM_DELETE_WINDOW', self.close) self.smallim = Image.open("textures/maps/medium_map.jpg") self.bigim = Image.open("textures/maps/big_map.jpg") self.bigim.load() self.customFont = tkFont.Font(family="Comic Sans MS", size=12) self.im2 = ImageTk.PhotoImage(self.smallim) self.click = [] self.topFrame = Frame(master) self.topFrame.pack(side=TOP) self.bottomFrame = Frame(master) self.bottomFrame.pack(side=BOTTOM, fill="both") self.canvas = Canvas(self.topFrame, width = 1200, height=600) self.canvas.pack(expand="yes", fill="both") self.label = self.canvas.create_image(0,0, image=self.im2, anchor='nw') click = self.canvas.bind("<Button-1>", self.callback) self.crosshairs = Image.open("textures/crosshairs/targetcrosshair.gif") #GIFs ONLY, PNG's transparency doesn't work self.crosshairs2 = Image.open("textures/crosshairs/clickcrosshair.gif") self.cross_width, self.cross_height = self.crosshairs.size self.cross_width2, self.cross_height2 = self.crosshairs2.size self.cross = ImageTk.PhotoImage(self.crosshairs) self.cross2 = ImageTk.PhotoImage(self.crosshairs2) self.first_round = 0 self.zoomed = False self.d = database.Database() self.tot_score = 0 self.level = 1 self.level_pass = self.max_score() self.difficulty = 50 self.go_number = 1 self.level_score = 0 self.asked_index = [ (len(self.d.data)+1)] self.text = Text(self.bottomFrame, height=1, width=40, font=self.customFont) self.text.pack(side=LEFT) self.scoreText = Text(self.bottomFrame, height=1,width=10) self.scoreText.pack(side=RIGHT) self.scoreText.insert(END, str(self.tot_score)) self.scoreText.config(state=DISABLED) self.scoreLabel = Label(self.bottomFrame, text="Total Score") self.scoreLabel.pack(side=RIGHT) self.text.insert(END, "Your next city is: ") self.text.config(state=DISABLED) self.levelText = Text(self.bottomFrame, height=1, width=10) self.levelText.pack(side=RIGHT) self.levelText.insert(END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) self.levelLabel = Label(self.bottomFrame, text='Level 1 Score') self.levelLabel.pack(side=RIGHT) self.gamesetup() def close(self): self.master.destroy() self.d.close() def zoom_in(self): self.canvas.delete(self.label) self.zoomposition_x = self.click[0] - 60 self.zoomposition_y = self.click[1] - 30 self.upper = (self.click[1]*10) - 300 self.left = (self.click[0]*10) - 600 right = (self.click[0]*10) + 600 lower = (self.click[1]*10) + 300 self.crop_big = self.bigim.crop((self.left, self.upper, right, lower)) self.crop_big2 = ImageTk.PhotoImage(self.crop_big) self.zoom = self.canvas.create_image(0, 0, image=self.crop_big2, anchor='nw') self.zoomed = True def zoom_out(self): self.canvas.delete(self.zoom) self.label = self.canvas.create_image(0,0, image=self.im2, anchor='nw') self.zoomed = False def callback(self, event): self.click = [event.x, event.y] if self.zoomed == False: self.zoom_in() else: x = int(int(self.city.xcord))-self.left y = int(int(self.city.ycord))-self.upper self.target3 = self.canvas.create_image(x - self.cross_width/2, y - self.cross_height/2,image=self.cross, anchor='nw') self.target4 = self.canvas.create_image(self.click[0] - self.cross_width2/2, self.click[1]-self.cross_height2/2, image=self.cross2, anchor='nw') self.master.update() time.sleep(2) self.canvas.delete(self.target3) self.gameplay() def gamesetup(self): self.city, self.asked_index = self.d.choose_city(self.asked_index, self.difficulty) self.text.config(state="normal") self.text.delete("1.19", END) self.text.insert(END, self.city.cityname + ", " + self.city.country ) self.text.config(state=DISABLED) self.score = 0 def gameplay(self): if self.first_round != 0: self.canvas.delete(self.target) go_score = self.distance_score() self.tot_score += go_score self.level_score += go_score self.scoreText.config(state="normal") self.scoreText.delete("1.00", END) self.scoreText.insert(END, str(self.tot_score)) self.scoreText.config(state=DISABLED) self.levelText.config(state="normal") self.levelText.delete("1.00", END) self.levelText.insert(END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) self.zoom_out() x = int(int(self.city.xcord)/10) y = int(int(self.city.ycord)/10) self.x_click = self.zoomposition_x + int(self.click[0]/10) self.y_click = self.zoomposition_y + int(self.click[1]/10) self.target = self.canvas.create_image(int(x)-self.cross_width/2, int(y)-self.cross_height/2, image=self.cross, anchor='nw') self.target2 = self.canvas.create_image(int(self.x_click)-self.cross_width2/2, int(self.y_click)-self.cross_height2/2, image=self.cross2, anchor='nw') self.canvas.tag_raise(self.target2) self.first_round = 1 self.city.update_difficulty(self.dist) self.go_number += 1 if self.go_number == 10: if self.level_score > self.level_pass: self.level_up() else: self.level_fail() self.gamesetup() def distance_score(self): self.offset_x = float(self.click[0]+self.left) self.offset_y = float(self.click[1]+self.upper) click_long = (self.offset_x - 6000) * 0.03 click_lat = (3000 - self.offset_y) * 0.03 city_long = (int(self.city.xcord) - 6000) * 0.03 city_lat = (3000 - int(self.city.ycord)) * 0.03 self.dist = self.global_distance(click_long, click_lat, city_long, city_lat) if self.dist == 0: score = self.max_score() else: score = int( self.max_score() / (self.dist**0.5) ) if score < 0: score = 0 print "You scored: " + str(score) return score def global_distance(self, lon1, lat1, lon2, lat2): """ Calculate the great circle distance between two points on the earth (specified in decimal degrees) """ # convert decimal degrees to radians lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) # haversine formula dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 c = 2 * asin(sqrt(a)) r = 6371 # Radius of earth in kilometers. Use 3956 for miles return c * r def level_up(self): self.level += 1 self.levelLabel.config(text="Level " + str(self.level) + " Score") self.level_pass = self.max_score() print "LEVEL UP, Begin Level " + str(self.level) self.difficulty += 50 self.go_number = 1 self.level_score = 0 self.levelText.config(state="normal") self.levelText.delete("1.00", END) self.levelText.insert(END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) def level_fail(self): self.level = 1 self.levelLabel.config(text="Level " + str(self.level) + " Score") self.level_pass = self.max_score() print "YOU FAILED, Begin Level 1" self.difficulty = 50 self.go_number = 1 self.level_score = 0 self.tot_score = 0 self.scoreText.config(state="normal") self.scoreText.delete("1.00", END) self.scoreText.insert(END, str(self.tot_score)) self.scoreText.config(state=DISABLED) self.levelText.config(state="normal") self.levelText.delete("1.00", END) self.levelText.insert(END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) def max_score(self): return int(1000 * (1.2 ** (self.level-1)))
class TkFlameGraphRenderer: """Renders a call forest to a flame graph using Tk graphics.""" def __init__(self, call_forest, tk, width, height, colours): self.call_forest = call_forest self.tk = tk self.width = width self.height = height self.colours = colours self.font = ('Courier', 12) self.character_width = 0.1 * Font(family='Courier', size=12).measure('mmmmmmmmmm') self.min_width_for_text = 3 * self.character_width self.min_height_for_text = 10 self.x_scale = float(width) / call_forest.samples() self.y_scale = float(height) / call_forest.depth() self.top = Toplevel(tk) self.top.title(call_forest.name) self.canvas = Canvas(self.top, width=width, height=height) self.canvas.pack() def render(self): x = 2.0 # ************************************ y = self.height - self.y_scale sorted_roots = sorted(self.call_forest.roots, key=lambda n: n.signature) for root in sorted_roots: self.render_call_tree(root, x, y) x += self.x_scale * root.samples # Not sure why I need this self.canvas.tag_raise('signature') def render_call_tree(self, root, x, y): self.render_call_tree_node(root, x, y) child_x = x child_y = y - self.y_scale sorted_children = sorted(root.children, key=lambda n: n.signature) for child in sorted_children: self.render_call_tree(child, child_x, child_y) child_x += self.x_scale * child.samples def render_call_tree_node(self, node, x, y): bbox = self.bounding_box(node, x, y) colour = self.colours.colour_for(node) id = self.canvas.create_rectangle(bbox, fill=colour) self.bind_events(id, node) self.text(node, x, y) def bounding_box(self, node, x, y): left = x right = left + self.x_scale * node.samples top = y bottom = y + self.y_scale bbox = (left, top, right, bottom) return bbox def text(self, node, x, y): height = self.y_scale width = self.x_scale * node.samples if height > self.min_height_for_text and width > self.min_width_for_text: sig = node.signature i = sig.rfind('.') method = sig[i:] char_width = int(width / self.character_width) chars = method[:char_width] if len( method) >= char_width else sig[-char_width:] # chars = node.signature[:char_width] id = self.canvas.create_text((x + width / 2, y + height / 2), text=chars, anchor='center', font=self.font, tags='signature') self.bind_events(id, node) def bind_events(self, id, node): self.canvas.tag_bind(id, '<Enter>', lambda e: self.mouse_enter(e, node)) self.canvas.tag_bind(id, '<Leave>', self.mouse_leave) self.canvas.tag_bind(id, '<Double-Button-1>', lambda e: self.zoom_in(e, node)) def mouse_enter(self, event, node): self.show_tooltip(self.canvas.canvasx(event.x), self.canvas.canvasy(event.y), node) def mouse_leave(self, event): self.hide_tooltip() def zoom_in(self, event, new_root): new_call_forest = CallForest(new_root.signature) new_call_forest.add_root(new_root) new_renderer = TkFlameGraphRenderer(new_call_forest, self.tk, self.width, self.height, self.colours) new_renderer.render() def show_tooltip(self, x, y, node): signature, samples = node.signature, node.samples percentage = (100.0 * samples) / self.call_forest.samples() text = '{} {} {:.2f}%'.format(signature, samples, percentage) c = self.canvas y_offset = (-10 if y > 30 else 20) anchor = 'sw' if x < self.width * 0.3 else 's' if x < self.width * 0.7 else 'se' label = c.create_text((x, y + y_offset), text=text, anchor=anchor, tags='tooltip', font=('Courier', 12)) bounds = c.bbox(label) c.create_rectangle(bounds, fill='white', width=0, tags='tooltip') c.tag_raise(label) pass def hide_tooltip(self): self.canvas.delete('tooltip')
class GeoGame(Frame): def __init__(self, master): self.master = master self.master.title("GeoGame") self.master.protocol('WM_DELETE_WINDOW', self.close) self.smallim = Image.open("textures/maps/medium_map.jpg") self.bigim = Image.open("textures/maps/big_map.jpg") self.bigim.load() self.customFont = tkFont.Font(family="Comic Sans MS", size=12) self.im2 = ImageTk.PhotoImage(self.smallim) self.click = [] self.topFrame = Frame(master) self.topFrame.pack(side=TOP) self.bottomFrame = Frame(master) self.bottomFrame.pack(side=BOTTOM, fill="both") self.canvas = Canvas(self.topFrame, width=1200, height=600) self.canvas.pack(expand="yes", fill="both") self.label = self.canvas.create_image(0, 0, image=self.im2, anchor='nw') click = self.canvas.bind("<Button-1>", self.callback) self.crosshairs = Image.open( "textures/crosshairs/targetcrosshair.gif" ) #GIFs ONLY, PNG's transparency doesn't work self.crosshairs2 = Image.open("textures/crosshairs/clickcrosshair.gif") self.cross_width, self.cross_height = self.crosshairs.size self.cross_width2, self.cross_height2 = self.crosshairs2.size self.cross = ImageTk.PhotoImage(self.crosshairs) self.cross2 = ImageTk.PhotoImage(self.crosshairs2) self.first_round = 0 self.zoomed = False self.d = database.Database() self.tot_score = 0 self.level = 1 self.level_pass = self.max_score() self.difficulty = 50 self.go_number = 1 self.level_score = 0 self.asked_index = [(len(self.d.data) + 1)] self.text = Text(self.bottomFrame, height=1, width=40, font=self.customFont) self.text.pack(side=LEFT) self.scoreText = Text(self.bottomFrame, height=1, width=10) self.scoreText.pack(side=RIGHT) self.scoreText.insert(END, str(self.tot_score)) self.scoreText.config(state=DISABLED) self.scoreLabel = Label(self.bottomFrame, text="Total Score") self.scoreLabel.pack(side=RIGHT) self.text.insert(END, "Your next city is: ") self.text.config(state=DISABLED) self.levelText = Text(self.bottomFrame, height=1, width=10) self.levelText.pack(side=RIGHT) self.levelText.insert( END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) self.levelLabel = Label(self.bottomFrame, text='Level 1 Score') self.levelLabel.pack(side=RIGHT) self.gamesetup() def close(self): self.master.destroy() self.d.close() def zoom_in(self): self.canvas.delete(self.label) self.zoomposition_x = self.click[0] - 60 self.zoomposition_y = self.click[1] - 30 self.upper = (self.click[1] * 10) - 300 self.left = (self.click[0] * 10) - 600 right = (self.click[0] * 10) + 600 lower = (self.click[1] * 10) + 300 self.crop_big = self.bigim.crop((self.left, self.upper, right, lower)) self.crop_big2 = ImageTk.PhotoImage(self.crop_big) self.zoom = self.canvas.create_image(0, 0, image=self.crop_big2, anchor='nw') self.zoomed = True def zoom_out(self): self.canvas.delete(self.zoom) self.label = self.canvas.create_image(0, 0, image=self.im2, anchor='nw') self.zoomed = False def callback(self, event): self.click = [event.x, event.y] if self.zoomed == False: self.zoom_in() else: x = int(int(self.city.xcord)) - self.left y = int(int(self.city.ycord)) - self.upper self.target3 = self.canvas.create_image(x - self.cross_width / 2, y - self.cross_height / 2, image=self.cross, anchor='nw') self.target4 = self.canvas.create_image( self.click[0] - self.cross_width2 / 2, self.click[1] - self.cross_height2 / 2, image=self.cross2, anchor='nw') self.master.update() time.sleep(2) self.canvas.delete(self.target3) self.gameplay() def gamesetup(self): self.city, self.asked_index = self.d.choose_city( self.asked_index, self.difficulty) self.text.config(state="normal") self.text.delete("1.19", END) self.text.insert(END, self.city.cityname + ", " + self.city.country) self.text.config(state=DISABLED) self.score = 0 def gameplay(self): if self.first_round != 0: self.canvas.delete(self.target) go_score = self.distance_score() self.tot_score += go_score self.level_score += go_score self.scoreText.config(state="normal") self.scoreText.delete("1.00", END) self.scoreText.insert(END, str(self.tot_score)) self.scoreText.config(state=DISABLED) self.levelText.config(state="normal") self.levelText.delete("1.00", END) self.levelText.insert( END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) self.zoom_out() x = int(int(self.city.xcord) / 10) y = int(int(self.city.ycord) / 10) self.x_click = self.zoomposition_x + int(self.click[0] / 10) self.y_click = self.zoomposition_y + int(self.click[1] / 10) self.target = self.canvas.create_image(int(x) - self.cross_width / 2, int(y) - self.cross_height / 2, image=self.cross, anchor='nw') self.target2 = self.canvas.create_image( int(self.x_click) - self.cross_width2 / 2, int(self.y_click) - self.cross_height2 / 2, image=self.cross2, anchor='nw') self.canvas.tag_raise(self.target2) self.first_round = 1 self.city.update_difficulty(self.dist) self.go_number += 1 if self.go_number == 10: if self.level_score > self.level_pass: self.level_up() else: self.level_fail() self.gamesetup() def distance_score(self): self.offset_x = float(self.click[0] + self.left) self.offset_y = float(self.click[1] + self.upper) click_long = (self.offset_x - 6000) * 0.03 click_lat = (3000 - self.offset_y) * 0.03 city_long = (int(self.city.xcord) - 6000) * 0.03 city_lat = (3000 - int(self.city.ycord)) * 0.03 self.dist = self.global_distance(click_long, click_lat, city_long, city_lat) if self.dist == 0: score = self.max_score() else: score = int(self.max_score() / (self.dist**0.5)) if score < 0: score = 0 print "You scored: " + str(score) return score def global_distance(self, lon1, lat1, lon2, lat2): """ Calculate the great circle distance between two points on the earth (specified in decimal degrees) """ # convert decimal degrees to radians lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) # haversine formula dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2 c = 2 * asin(sqrt(a)) r = 6371 # Radius of earth in kilometers. Use 3956 for miles return c * r def level_up(self): self.level += 1 self.levelLabel.config(text="Level " + str(self.level) + " Score") self.level_pass = self.max_score() print "LEVEL UP, Begin Level " + str(self.level) self.difficulty += 50 self.go_number = 1 self.level_score = 0 self.levelText.config(state="normal") self.levelText.delete("1.00", END) self.levelText.insert( END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) def level_fail(self): self.level = 1 self.levelLabel.config(text="Level " + str(self.level) + " Score") self.level_pass = self.max_score() print "YOU FAILED, Begin Level 1" self.difficulty = 50 self.go_number = 1 self.level_score = 0 self.tot_score = 0 self.scoreText.config(state="normal") self.scoreText.delete("1.00", END) self.scoreText.insert(END, str(self.tot_score)) self.scoreText.config(state=DISABLED) self.levelText.config(state="normal") self.levelText.delete("1.00", END) self.levelText.insert( END, str(self.level_score) + "/" + str(int(self.max_score()))) self.levelText.config(state=DISABLED) def max_score(self): return int(1000 * (1.2**(self.level - 1)))