def input(self, event): self.x_speed = 0.0 self.y_speed = 0.0 x, y = mouse.get_pos() if event.type == MOUSEBUTTONDOWN and event.button == MOUSE.MIDDLE: self.x_first = x self.y_first = y elif event.type == MOUSEBUTTONUP and event.button == MOUSE.MIDDLE: self.x_first = None self.y_first = None elif event.type == MOUSEMOTION and mouse.get_pressed()[1] and \ self.x_first and self.y_first: self.x_delta = x - self.x_first self.y_delta = y - self.y_first else: if mouse.get_focused(): if x > self.w - self.scroll_width and x < self.w: self.x_speed = self.speed elif x < self.scroll_width: self.x_speed = -self.speed if y > self.h - self.scroll_width: self.y_speed = self.speed elif y < self.scroll_width: self.y_speed = -self.speed if key.get_focused(): if key.get_pressed()[K_RIGHT]: self.x_speed = self.speed elif key.get_pressed()[K_LEFT]: self.x_speed = -self.speed if key.get_pressed()[K_DOWN]: self.y_speed = self.speed elif key.get_pressed()[K_UP]: self.y_speed = -self.speed
def log(audio_elements, log_file_path, audio_file, start_pos=0, resume=False): # Helper functions def advance(to, pos, prev_pos): # Actually do the logging # Get our position in the audio file and the current audio_element (a.k.a. the div in the TEI file) audio_element = audio_elements[to] # Tell us what's going on print 'logged at time:', pos, 'count:', count print '\t', audio_elements[to+1]['text'], '(file', audio_elements[to+1]['file_name'], ')' # TEI XML files can have unicode, don'tchaknow # The values of text_audio_element are being put into the correct order text_audio_element = map(unicode, [audio_element['id'], audio_element['text'], audio_element['file_name'], audio_element['count']]) # Convert to tab-separated tabbed_audio_element = string.join(text_audio_element, '\t') # Remove line breaks no_line_breaks = tabbed_audio_element.replace ('\n', ' ') # And write it to the file log.write(str(prev_pos) + '\t' + str(pos) + '\t' + no_line_breaks + '\n') return # Print a warning message to the log file def warn(warning_message = ['DANGER,', 'WILL', 'ROBINSON,', 'DANGER!']): # Pretty much as in advance() pos = mixer.music.get_pos()/1000 log.write(str(pos) + '\t' + str(pos) + '\t' + string.join(warning_message, '\t') +'\n') print warning_string, pos return count = 0 log = codecs.open(log_file_path, 'w', 'utf-8') paused = False prev_pos = 0 pos = 0 # Initialise pygame pygame.init() screen = pygame.display.set_mode((100,100)) mixer.music.load(audio_file) mixer.music.play(0, start_pos) mixer.init() pygame.event.set_grab(True) # Print some startup info print "lumberjack: starting to log" print "Press space to log the end of the section displayed on the screen" print "Press q to quit" print "Press p to pause" print "Press any other key to log a warning to file, along with the current timestamp\n" # Print some info about the first audio_element print '\t', audio_elements[0]['text'], '(', audio_elements[0], ')' # Main logging loop while True: if not key.get_focused(): mixer.music.pause() while (not key.get_focused()): time.wait(100) print "Waiting" mixer.music.unpause() else: keydown = [event for event in pygame.event.get() if event.type == KEYDOWN] for e in keydown: if e.key == K_SPACE: prev_pos = pos pos = mixer.music.get_pos() advance(count, pos, prev_pos) count = count + 1 elif e.key == K_q: return elif e.key == K_p: if not paused: mixer.music.pause() else: mixer.music.unpause() #paused = !paused paused = not paused else: warn()
def log(audio_elements, log_file_path, audio_file, start_pos=0, resume=False): # Helper functions def advance(to, pos, prev_pos): # Actually do the logging # Get our position in the audio file and the current audio_element (a.k.a. the div in the TEI file) audio_element = audio_elements[to] # Tell us what's going on print "logged at time:", pos, "count:", count print "\t", audio_elements[to + 1]["text"], "(file", audio_elements[to + 1]["file_name"], ")" # TEI XML files can have unicode, don'tchaknow # The values of text_audio_element are being put into the correct order text_audio_element = map( unicode, [audio_element["id"], audio_element["text"], audio_element["file_name"], audio_element["count"]] ) # Convert to tab-separated tabbed_audio_element = string.join(text_audio_element, "\t") # Remove line breaks no_line_breaks = tabbed_audio_element.replace("\n", " ") # And write it to the file log.write(str(prev_pos) + "\t" + str(pos) + "\t" + no_line_breaks + "\n") return # Print a warning message to the log file # This contains four words so that the make_ functions don't throw a wobbly # when trying to parse a logfile with error messages def warn(warning_message=["DANGER,", "WILL", "ROBINSON,", "DANGER!"]): # Pretty much as in advance() # Audacity format requires seconds rather than miliseconds pos = mixer.music.get_pos() / 1000 log.write(str(pos) + "\t" + str(pos) + "\t" + string.join(warning_message, "\t") + "\n") print warning_string, pos return count = 0 log = codecs.open(log_file_path, "w", "utf-8") paused = False prev_pos = 0 pos = 0 # Initialise pygame pygame.init() screen = pygame.display.set_mode((100, 100)) mixer.music.load(audio_file) mixer.music.play(0, start_pos) mixer.init() event.set_grab(True) # Print some startup info print "lumberjack: starting to log" print "Press space to log the end of the section displayed on the screen" print "Press q to quit" print "Press p to pause" print "Press any other key to log a warning to file, along with the current timestamp\n" # Print some info about the first audio_element print "\t", audio_elements[0]["text"], "(", audio_elements[0], ")" # Main logging loop while True: if not key.get_focused(): mixer.music.pause() while not key.get_focused(): time.wait(100) print "Waiting" mixer.music.unpause() else: keydown = [e for e in event.get() if event.type == KEYDOWN] for e in keydown: if e.key == K_SPACE: prev_pos = pos pos = mixer.music.get_pos() advance(count, pos, prev_pos) count = count + 1 elif e.key == K_q: return elif e.key == K_p: if not paused: mixer.music.pause() else: mixer.music.unpause() # paused = !paused paused = not paused else: warn()
def main(): init() running = True size = 1000, 1000 # these are the width and height of the simulation grid grid_x, grid_y = int(argv[1]), int(argv[2]) # this is how many pixels per cell in the simulation grid # We need to use the grid factor because the pygame window is not # the same width and height of the simulation grid size. Therefore, # we scale the pygame window down to fit the simulation size grid_factor_x, grid_factor_y = 1000 / grid_x, 1000 / grid_y screen = display.set_mode(size) # used to track either the setting of the topleft of a rectangle, # or the bottom right (if bottom right, the rectangle is completed) num_clicks_patch = 0 num_clicks_patch_temp = 0 num_clicks_exit = 0 num_clicks_exit_temp = 0 # the position of the mouse when the left or right mouse button is clicked mouse_pos_patch = () mouse_pos_exit = () # the position of the patch's top left corner in pixels patch_tl = () # the position of the patch's bottom right corner in pixels patch_br = () # the position of the exits's top left corner in pixels exit_tl = () # the position of the exits's bottom right corner in pixels exit_br = () patch_temp = Rect(-1, -1, 0, 0) exit_temp = Rect(-1, -1, 0, 0) # a list of patches as pygame rectangles that are being displayed # on screen patch_list = [] # a list of patches removed from the screen. The user can recall these # with a keybind patch_discard_list = [] # a list of exits as pygame rectangles that are being displayed # on screen exit_list = [] # a list of exits removed from the screen. The user can recall these # with a keybind exit_discard_list = [] # a list of 1 pixel-wide pygame rectangles that are drawn to the screen # to create grid lines gridline_list = [] # populate `gridline_list` gridline_list = populate_gridline_list(gridline_list, grid_x, grid_y, grid_factor_x, grid_factor_y) # main game loop will run until the user clicks the exit button in the top right corner (Windows) while running: # event loop for pygame_event in event.get(): # if the user hits the window's exit button, stop the app if pygame_event.type == QUIT: running = False # if the user hits the mouse button in the app window if pygame_event.type == MOUSEBUTTONDOWN and mouse.get_focused(): # return a list of booleans for the three major buttons on a mouse: # left mouse, right mouse, and middle mouse. If an element is True, # the corresponding button is pressed mouse_depressed = mouse.get_pressed(num_buttons=3) # if the user clicks ONLY the left mouse button, they are creating # a patch. if mouse_depressed[0] and not mouse_depressed[2]: # get the mouse's position with respect to the window mouse_pos_patch = mouse.get_pos() num_clicks_patch += 1 num_clicks_patch_temp = num_clicks_patch # if the user clicks ONLY the right mouse button, they are creating # an exit. if mouse_depressed[2] and not mouse_depressed[0]: mouse_pos_exit = mouse.get_pos() num_clicks_exit += 1 num_clicks_exit_temp = num_clicks_exit if pygame_event.type == KEYDOWN and key.get_focused(): # return a list of booleans for all the keys on the keyboard # If an element is True, the corresponding key is pressed keys_depressed = key.get_pressed() # if the user presses CTRL+Z, remove the previously added patches # from most recent to least recent if keys_depressed[K_LCTRL] and keys_depressed[ K_z] and not keys_depressed[K_LSHIFT]: # if the user has begun to create a new patch, they can # cancel it by hitting CTRL+Z. Otherwise, CTRL+Z removes a # patch that has already been drawn if patch_list and num_clicks_patch == 0: patch_discard_list.append(patch_list.pop()) print("Number of patches:", len(patch_list)) else: patch_tl = () num_clicks_patch = 0 num_clicks_patch_temp = 0 print("Undid patch topleft!") # if the user pressed CTRL+SHIFT+Z, remove the previously added exits # from most recent to least recent elif keys_depressed[K_LSHIFT] and keys_depressed[ K_LCTRL] and keys_depressed[K_z]: # if the user has begun to create a new exit, they can # cancel it by hitting CTRL+SHIFT+Z. Otherwise, CTRL+SHIFT+Z removes a # exit that has already been drawn if exit_list and num_clicks_exit == 0: exit_discard_list.append(exit_list.pop()) print("Number of exits:", len(exit_list)) else: exit_tl = () num_clicks_exit = 0 num_clicks_exit_temp = 0 print("Undid exit topleft!") # if the user presses CTRL+Y, restore the previously removed patch # from the discard patch list from most recent to least recent if keys_depressed[K_LCTRL] and keys_depressed[ K_y] and not keys_depressed[K_LSHIFT]: # the user can only restore a deleted patch if they haven't # started drawing another one. Easy fix for this: press CTRL+Z # to undo the topleft of the already-begun patch, then do CTRL+Y if patch_discard_list and num_clicks_patch == 0: patch_list.append(patch_discard_list.pop()) print("Number of patches:", len(patch_list)) # if the user pressed CTRL+SHIFT+Y, restore the previously removed exit # from the discard exit list from most recent to least recent elif keys_depressed[K_LSHIFT] and keys_depressed[ K_LCTRL] and keys_depressed[K_y]: # the user can only restore a deleted exit if they haven't # started drawing another one. Easy fix for this: press CTRL+SHIFT+Z # to undo the topleft of the already-begun exit, then do CTRL+SHIFT+Y if exit_discard_list and num_clicks_exit == 0: exit_list.append(exit_discard_list.pop()) print("Number of exits:", len(exit_list)) # if the user has clicked the mouse once, store the mouse position # as the top left of the rectangle to be drawn if num_clicks_patch_temp == 1: patch_tl = mouse_pos_patch num_clicks_patch_temp = 0 patch_temp.topleft = patch_tl print("Patch topleft set at", patch_tl) # if the user has clicked the mouse for the second time, elif num_clicks_patch_temp == 2: patch_br = mouse_pos_patch patch_list.append( Rect(patch_tl[0], patch_tl[1], patch_br[0] - patch_tl[0], patch_br[1] - patch_tl[1])) num_clicks_patch = 0 num_clicks_patch_temp = 0 print("Number of patches:", len(patch_list)) # if the user has clicked the mouse once, store the mouse position # as the top left of the rectangle to be drawn if num_clicks_exit_temp == 1: exit_tl = mouse_pos_exit num_clicks_exit_temp = 0 exit_temp.topleft = exit_tl print("Exit topleft set at", exit_tl) # if the user has clicked the mouse for the second time, elif num_clicks_exit_temp == 2: exit_br = mouse_pos_exit exit_list.append( Rect(exit_tl[0], exit_tl[1], exit_br[0] - exit_tl[0], exit_br[1] - exit_tl[1])) num_clicks_exit = 0 num_clicks_exit_temp = 0 print("Number of exits:", len(exit_list)) # first blacken the screen screen.fill("black") # draw the grid lines for gridline in gridline_list: draw.rect(screen, "blue", gridline) # draw the patches on top of the grid lines for patch in patch_list: patch.normalize() draw.rect(screen, "white", patch, width=1) # then draw the exits over the grid lines and patches for exit in exit_list: exit.normalize() draw.rect(screen, "red", exit) # if the user has clicked to begin drawing either a patch # or an exit, display the box growing and shrinking as they # move their mouse so they can see what the patch/exit will look # like when it's drawn if num_clicks_patch == 1: patch_temp.size = tuple( map(sub, mouse.get_pos(), patch_temp.topleft)) # we'll use `patch_temp_copy` to display a proper rectangle if the user defines # `patch_temp`'s topleft and then moves the mouse above or farther left than # that point. Doing so creates a negative width/height in the rectangle which # does not draw to the screen without glitching. Normalizing the rectangle # removes the negative width/height and reassigns the topleft point in the process. # Without using a copy of `patch_temp`, its top left would change every game loop, # and the rectangle would not change with mouse movement correctly. If this # description doesn't make sense, just trust me. If you're the kind of person # who likes to define the bottom right corner first, this code lets you see # that normalized (looks like a rectangle, not a cross road) rectangle change # size as your mouse moves around :D patch_temp_copy = Rect(-1, -1, 0, 0) # I have to define `patch_temp_copy` like this instead of `patch_temp_copy = patch_temp` # since that would just make `patch_temp_copy` an alias of `patch_temp` patch_temp_copy.topleft = patch_temp.topleft patch_temp_copy.size = patch_temp.size patch_temp_copy.normalize() draw.rect(screen, "white", patch_temp_copy, width=1) print(patch_temp_copy.size, " ", end='\r') if num_clicks_exit == 1: # same theory as with `patch_temp_copy` so I'm not gonna repeat it... exit_temp.size = tuple(map(sub, mouse.get_pos(), exit_temp.topleft)) exit_temp_copy = Rect(-1, -1, 0, 0) exit_temp_copy.topleft = exit_temp.topleft exit_temp_copy.size = exit_temp.size exit_temp_copy.normalize() draw.rect(screen, "red", exit_temp_copy) print(exit_temp_copy.size, " ", end='\r') # this updates the contents of the surface display.flip() # if the user has clicked the exit button, ask them if they either want to create # the terrain or completely exit the editor. Give them a second chance if they # want to quit. That way they don't accidentally lose their progress. if not running: response = input( "Would you like to create the terrain with this model? (y/n) ") if response == 'y': # create the terrain grid from the rectangles drawn in the pygame window terrain_grid = create_terrain_grid(patch_list, exit_list, grid_x, grid_y, grid_factor_x, grid_factor_y) # draw converted rectangles to the .txt file output_to_file(grid_x, grid_y, terrain_grid) # save the pygame screen as a .png to use as the background image of the simulation # visualization .gif save_screen_as_bkgr(screen) # update the patches document in the `params.json` file update_patches(patch_list, grid_factor_x, grid_factor_y) elif response == 'n': second_response = input("Are you sure? (Y/N) ") if second_response == "Y": print("Quitting terrain editor.") elif second_response == "N": running = True print("Continuing terrain editor.") else: running = True print( "Invalid response ('Y' or 'N' only, please). Continuing terrain editor." ) else: running = True print( "Invalid response ('y' or 'n' only, please). Continuing terrain editor." ) quit()