from pygame import key, mouse from collections import defaultdict class Input: _instance = None _initialized = False def __new__(cls): if cls._instance is None: cls._instance = super(Input, cls).__new__(cls) return cls._instance def __init__(self): if not self._initialized: self.action_map = defaultdict(list) self.action_states = defaultdict(bool) self.action_previous_states = defaultdict(bool) self._initialized = True def add_action_bind(self, action: str, key_code): if key_code not in self.action_map[action]: self.action_map[action].append(key_code) def remove_action_bind(self, action: str, key_code): if key_code in self.action_map[action]: self.action_map[action].remove(key_code) def get_action_list(self, action: str): return self.action_map[action] def is_key_pressed(self, key_code): pressed_keys = key.get_pressed() return pressed_keys[key_code] def is_mouse_button_pressed(self, button): pressed_buttons = mouse.get_pressed() if button < len(pressed_buttons): return pressed_buttons[button] return False def get_mouse_position(self): return mouse.get_pos() def is_action_pressed(self, action: str): for key_code in self.action_map[action]: if self.is_key_pressed(key_code): return True return False def is_action_just_pressed(self, action: str): current_state = self.is_action_pressed(action) previous_state = self.action_previous_states[action] self.action_previous_states[action] = current_state return current_state and not previous_state def is_action_just_released(self, action: str): current_state = self.is_action_pressed(action) previous_state = self.action_previous_states[action] self.action_previous_states[action] = current_state return not current_state and previous_state def get_action_strength(self, action: str): return 1.0 if self.is_action_pressed(action) else 0.0 def get_action_raw_strength(self, action: str): return self.get_action_strength(action) def get_axis(self, negative_action: str, positive_action: str): axis_value = 0.0 if self.is_action_pressed(positive_action): axis_value += 1.0 if self.is_action_pressed(negative_action): axis_value -= 1.0 return axis_value def get_vector(self, negative_x: str, positive_x: str, negative_y: str, positive_y: str): x = self.get_axis(negative_x, positive_x) y = self.get_axis(negative_y, positive_y) return (x, y) def update(self): for action in self.action_map: self.action_previous_states[action] = self.is_action_pressed(action)