from time import time as get_secs from pygame import joystick as joy from pygame.key import get_pressed from pygame.locals import * from GameChild import * class Input(GameChild): def __init__(self, game): GameChild.__init__(self, game) self.last_mouse_down_left = None self.joystick = Joystick() self.delegate = self.get_delegate() self.load_configuration() self.set_any_press_ignore_list() self.unsuppress() self.subscribe_to_events() self.build_key_map() self.build_joy_button_map() def load_configuration(self): self.release_suffix = self.get_configuration("input", "release-suffix") self.key_commands = self.get_configuration().items("keys") self.double_click_time_limit = self.get_configuration( "mouse", "double-click-time-limit") def set_any_press_ignore_list(self): self.any_press_ignored = set(["capture-screen", "toggle-fullscreen", "reset-game", "record-video", "quit", "mute", "toggle-interpolator"]) self.any_press_ignored_keys = set() def unsuppress(self): self.suppressed = False def subscribe_to_events(self): self.subscribe(self.translate_key, KEYDOWN) self.subscribe(self.translate_key, KEYUP) self.subscribe(self.translate_joy_button, JOYBUTTONDOWN) self.subscribe(self.translate_joy_button, JOYBUTTONUP) self.subscribe(self.translate_axis_motion, JOYAXISMOTION) self.subscribe(self.translate_mouse_input, MOUSEBUTTONDOWN) self.subscribe(self.translate_mouse_input, MOUSEBUTTONUP) def build_key_map(self): key_map = {} for command, keys in self.key_commands: key_map[command] = [] if type(keys) == str: keys = [keys] for key in keys: key_map[command].append(globals()[key]) self.key_map = key_map def build_joy_button_map(self): self.joy_button_map = self.get_configuration("joy") def suppress(self): self.suppressed = True def translate_key(self, event): if not self.suppressed: cancel = event.type == KEYUP posted = None key = event.key for cmd, keys in self.key_map.iteritems(): if key in keys: self.post_command(cmd, cancel=cancel) posted = cmd if (not posted or posted not in self.any_press_ignored) and \ key not in self.any_press_ignored_keys: self.post_any_command(key, cancel) def post_command(self, cmd, **attributes): self.delegate.post(cmd, **attributes) def post_any_command(self, id, cancel=False): self.post_command("any", id=id, cancel=cancel) def translate_joy_button(self, event): if not self.suppressed: cancel = event.type == JOYBUTTONUP posted = None for command, button in self.joy_button_map.iteritems(): if button == event.button: self.post_command(command, cancel=cancel) posted = command if not posted or posted not in self.any_press_ignored: self.post_any_command(event.button, cancel) def translate_axis_motion(self, event): if not self.suppressed: axis = event.axis value = event.value if not value: for command in "up", "right", "down", "left": self.post_command(command, cancel=True) if command not in self.any_press_ignored: self.post_any_command(command, True) else: if axis == 1: if value < 0: command = "up" elif value > 0: command = "down" else: if value > 0: command = "right" elif value < 0: command = "left" self.post_command(command) if command not in self.any_press_ignored: self.post_any_command(command) def is_command_active(self, command): if not self.suppressed: if self.is_key_pressed(command): return True joystick = self.joystick joy_map = self.joy_button_map if command in joy_map and joystick.get_button(joy_map[command]): return True if command == "up": return joystick.is_direction_pressed(Joystick.up) elif command == "right": return joystick.is_direction_pressed(Joystick.right) elif command == "down": return joystick.is_direction_pressed(Joystick.down) elif command == "left": return joystick.is_direction_pressed(Joystick.left) def is_key_pressed(self, command): poll = get_pressed() for key in self.key_map[command]: if poll[key]: return True def translate_mouse_input(self, event): button = event.button pos = event.pos post = self.post_command if event.type == MOUSEBUTTONDOWN: if button == 1: last = self.last_mouse_down_left if last: limit = self.double_click_time_limit if get_secs() - last < limit: post("mouse-double-click-left", pos=pos) last = get_secs() self.last_mouse_down_left = last def get_axes(self): axes = {} for direction in "up", "right", "down", "left": axes[direction] = self.is_command_active(direction) return axes def register_any_press_ignore(self, *args, **attributes): self.any_press_ignored.update(args) self.any_press_ignored_keys.update(self.extract_keys(attributes)) def extract_keys(self, attributes): keys = [] if "keys" in attributes: keys = attributes["keys"] if type(keys) == int: keys = [keys] return keys def unregister_any_press_ignore(self, *args, **attributes): self.any_press_ignored.difference_update(args) self.any_press_ignored_keys.difference_update( self.extract_keys(attributes)) class Joystick: (up, right, down, left) = range(4) def __init__(self): js = None if joy.get_count() > 0: js = joy.Joystick(0) js.init() self.js = js def is_direction_pressed(self, direction): js = self.js if not js or direction > 4: return False if direction == 0: return js.get_axis(1) < 0 elif direction == 1: return js.get_axis(0) > 0 elif direction == 2: return js.get_axis(1) > 0 elif direction == 3: return js.get_axis(0) < 0 def get_button(self, id): if self.js: return self.js.get_button(id)