From 6b9a762bfd426301514ebcfdc7206f68c85594ef Mon Sep 17 00:00:00 2001 From: Jakub Skokan Date: Thu, 14 Jul 2016 11:05:31 +0200 Subject: [PATCH] Add support for game controllers --- monorail/koon/gui.py | 24 +++++++++++++++++++----- monorail/koon/input.py | 29 ++++++++++++++++++++++++++++- monorail/menu.py | 6 +++++- monorail/monorail.py | 5 +++-- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/monorail/koon/gui.py b/monorail/koon/gui.py index 9714462..581d76f 100644 --- a/monorail/koon/gui.py +++ b/monorail/koon/gui.py @@ -45,9 +45,11 @@ def _update_active( self, userinput, component ): interactives = GuiState._get_interactive_components( component ) if self.active is not None and not self.active.has_input_lock(): - if userinput.key.went_down( K_UP ): + if userinput.key.went_down( K_UP ) or \ + userinput.joys.any_went_down( Joystick.DPAD_UP ): self.activate_prev() - if userinput.key.went_down( K_DOWN ): + if userinput.key.went_down( K_DOWN ) or \ + userinput.joys.any_went_down( Joystick.DPAD_DOWN ): self.activate_next() if userinput.mouse.has_moved() and \ @@ -280,6 +282,12 @@ def tick( self, userinput, guistate ): guistate.get_active() == self and \ userinput.key.any_went_down( Button.SELECT_KEYS ): self._went_down = True + + # Check if joy button went down on this button + if guistate is not None and \ + guistate.get_active() == self and \ + userinput.joys.any_went_down( Joystick.BTN_A ): + self._went_down = True self.is_down = False if userinput.mouse.is_down( Mouse.LEFT ) and \ @@ -570,10 +578,14 @@ def tick( self, userinput, guistate ): LARGE_STEP = 0.2 if guistate.active == self.button: - if userinput.key.is_down( K_LEFT ): + if userinput.key.is_down( K_LEFT ) or \ + userinput.joys.any_is_down( Joystick.DPAD_LEFT ): self.set_value( self.get_value() - STEP ) - if userinput.key.is_down( K_RIGHT ): + + if userinput.key.is_down( K_RIGHT ) or \ + userinput.joys.any_is_down( Joystick.DPAD_RIGHT ): self.set_value( self.get_value() + STEP ) + if userinput.key.any_went_down( Button.SELECT_KEYS ): new_value = self.get_value() + LARGE_STEP new_value = (int(new_value * 5) / 5.0) @@ -586,7 +598,9 @@ def tick( self, userinput, guistate ): self._went_up = True self._is_sliding = False - if userinput.key.any_went_up( [K_LEFT, K_RIGHT] ): + if userinput.key.any_went_up( [K_LEFT, K_RIGHT] ) or \ + userinput.joys.any_went_up( Joystick.DPAD_LEFT ) or \ + userinput.joys.any_went_up( Joystick.DPAD_RIGHT ): self._went_up = True def draw( self, surface, interpol, time_sec ): diff --git a/monorail/koon/input.py b/monorail/koon/input.py index 36f03c7..f6e79d2 100644 --- a/monorail/koon/input.py +++ b/monorail/koon/input.py @@ -102,14 +102,41 @@ def has_moved( self ): self._prev_pos <> self.pos class Joystick (ButtonLogger): + BTN_A, BTN_B, BTN_X, BTN_Y, BTN_LB, BTN_RB, BTN_BACK, BTN_START, \ + BTN_GUIDE = range( 9 ) + + DPAD_LEFT, DPAD_RIGHT, DPAD_UP, DPAD_DOWN = range( 11, 15 ) + def get_name( self, key ): return "joy " + str(key) +class Joysticks (list): + def any_went_up( self, button ): + for joy in self: + if joy.went_up(button): + return True + + return False + + def any_went_down( self, button ): + for joy in self: + if joy.went_down(button): + return True + + return False + + def any_is_down( self, button ): + for joy in self: + if joy.is_down(button): + return True + + return False + class UserInput: def __init__( self ): self.key = Keyboard() self.mouse = Mouse() - self.joys = [] + self.joys = Joysticks() for i in range( 0, pygame.joystick.get_count() ): joy = pygame.joystick.Joystick( i ) joy.init() diff --git a/monorail/menu.py b/monorail/menu.py index 0aeda9e..9f2e726 100644 --- a/monorail/menu.py +++ b/monorail/menu.py @@ -675,7 +675,8 @@ def tick( self, userinput, guistate ): self.player_count = i+1 i += 1 - if userinput.key.went_down( K_ESCAPE ): + if userinput.key.went_down( K_ESCAPE ) or \ + userinput.joys.any_went_down( Joystick.BTN_BACK ): self.player_count = -1 SingleSwitch.tick( userinput, self.guistate ) @@ -707,6 +708,9 @@ def __init__( self, game_data, player_cnt ): self.forbidden_buttons = [input.Button(self.game_data.userinput.key, K_ESCAPE)] + for joy in self.game_data.userinput.joys: + self.forbidden_buttons.append(input.Button(joy, Joystick.BTN_BACK)) + def tick( self, userinput, guistate ): Component.tick( self, userinput, guistate ) diff --git a/monorail/monorail.py b/monorail/monorail.py index 4cd5af8..929c9bc 100755 --- a/monorail/monorail.py +++ b/monorail/monorail.py @@ -60,7 +60,7 @@ def get_main_dir(): import koon.app from koon.app import Game -from koon.input import UserInput, Mouse +from koon.input import UserInput, Mouse, Joystick from koon.geo import Vec3D, Vec2D, Rectangle from koon.res import resman from koon.gui import ImageButton, GuiState @@ -320,7 +320,8 @@ def do_tick( self, indev ): SingleSwitch.tick( indev, None ) if indev.key.went_down( K_ESCAPE ) or \ self.hud.menu_btn.went_down() or \ - SingleSwitch.esc_went_down: + SingleSwitch.esc_went_down or \ + indev.joys.any_went_down( Joystick.BTN_BACK ): resman.get("gui.paper_sound").play() self.ingame_menu = IngameMenu(self.game_data.is_single_player(), self.game_data)