"translate pygame events to controls" import pygame.joystick from pygame.locals import * import game repeat_delay = 120 repeat_interval = 30 # keyboard state constants (for repeat delay, interval) KEYSTATE_UP = 0 KEYSTATE_DOWN = 1 KEYSTATE_REPEAT = 2 # key state tuple keystate = None # control constants UP = 1 DOWN = 2 LEFT = 3 RIGHT = 4 PRESS = 5 RELEASE = 6 END = 7 FIRE = 8 PAUSE = 9 DEBUG = 10 SELECT = 11 CHEAT = 12 LASTEVENT = 32 # event lists for filtering joystick_events = [JOYAXISMOTION,JOYBUTTONUP,JOYBUTTONDOWN] #translation tables keyboard_table = { K_a: UP, K_UP: UP, K_z: DOWN, K_DOWN: DOWN, K_LEFT: LEFT, K_RIGHT: RIGHT, K_SPACE: FIRE, K_ESCAPE: END, K_p: PAUSE, K_RETURN: SELECT, K_d: DEBUG, K_c: CHEAT } # repeat timers - filled in by init() keypress_times = {} # last states for repeat - filled in by init() key_last_state = {} all_keys = [K_a, K_UP, K_z, K_DOWN, K_LEFT, K_RIGHT, K_SPACE, K_RETURN, K_ESCAPE, K_d, K_c, K_p] joystick = None lastjoyx = RELEASE lastjoyy = RELEASE def init(): "init the input system" global joystick global all_keys, key_press_time,key_last_state try: num = pygame.joystick.get_count() if num > 0: joystick = pygame.joystick.Joystick(0) joystick.init() except pygame.error: joystick = None for key in all_keys: keypress_times[key] = 0 key_last_state[key] = 0 def joyindex(val): return int(val*1.9)+1 def translate(event): global lastjoyx, lastjoyy if event.type == KEYDOWN: return keyboard_table.get(event.key, None) elif event.type == JOYAXISMOTION: if event.axis == 1: joy = (UP,RELEASE,DOWN)[joyindex(event.value)] if joy != lastjoyy: lastjoyy = joy if joy == RELEASE: joy = (LEFT, RELEASE, RIGHT)[joyindex(joystick.get_axis(0))] lastjoyx = joy if joy != RELEASE: return joy elif event.axis == 0: joy = (LEFT,RELEASE,RIGHT)[joyindex(event.value)] if joy != lastjoyx: lastjoyx = joy if joy == RELEASE: joy = (UP, RELEASE, DOWN)[joyindex(joystick.get_axis(1))] lastjoyy = joy if joy != RELEASE: return joy elif event.type == JOYBUTTONDOWN: if event.button == 0: return FIRE elif event.button > 2: return ABORT elif event.type == JOYBUTTONUP and event.button == 0: return RELEASE def get_key_events(): """get key events- if single-frame mode is on, wait for next event on queue before returning""" if game.single_frame == 0: # normal mode- get keys return get_key_events1() else: # single step mode - wait for an event (keyboard or mouse) event = pygame.event.wait() if event.type in [KEYDOWN] and event.key == K_RETURN: game.single_frame = 0 return [event] def get_key_events1(): """build a list of keydown events by looking at the keyboard state- we need to do this because we need to be able to handle having two keys down at the same time. This routine gets called every tick and has to do a lot of processing, so it is (somewhat) optimized.""" global keystate keystate = pygame.key.get_pressed() # call map_keystate once for each item in all_keys, return a list of keys pressed keys_pressed = map(map_keystate,all_keys) # call new_key_event for each item in keys_pressed, return a list of new key events new_events = map(new_key_event,keys_pressed) # filter out the None elements new_events = filter(lambda x: x != None,new_events) return new_events def map_keystate(key): global keystate keylaststate = key_last_state[key] if keystate[key]: if keylaststate == KEYSTATE_UP: # key was up last we checked key_last_state[key] = KEYSTATE_DOWN return key #print "keystate down" else: # key was down or repeating last we checked now = pygame.time.get_ticks() if keylaststate == KEYSTATE_DOWN: if now - keypress_times[key] > repeat_delay: keypress_times[key] = now key_last_state[key] = KEYSTATE_REPEAT return key #print "keystate down-repeat" else: # keylaststate must be KEYSTATE_REPEAT if now - keypress_times[key] > repeat_interval: keypress_times[key] = now return key #print "keystate repeat" else: key_last_state[key] = KEYSTATE_UP return None def new_key_event(key): if key != None: return(pygame.event.Event(KEYDOWN,{'key':key})) else: return None