Game Controller

sprite_move_controller.py
  1"""
  2Move Sprite with Controller
  3
  4An example of one way to use controller and controller input to move a
  5sprite.
  6
  7Artwork from https://kenney.nl
  8
  9If Python and Arcade are installed, this example can be run from the
 10command line with:
 11python -m arcade.examples.sprite_move_controller
 12"""
 13import arcade
 14
 15SPRITE_SCALING = 0.5
 16
 17WINDOW_WIDTH = 1280
 18WINDOW_HEIGHT = 720
 19WINDOW_TITLE = "Move Sprite with Controller Example"
 20
 21MOVEMENT_SPEED = 5
 22DEAD_ZONE = 0.05
 23
 24
 25class Player(arcade.Sprite):
 26    """ Player sprite """
 27
 28    def __init__(self, filename, scale):
 29        super().__init__(filename, scale=scale)
 30
 31        self.controller = None
 32
 33        controllers = arcade.get_controllers()
 34
 35        # If we have any...
 36        if controllers:
 37            # Grab the first one in  the list
 38            self.controller = controllers[0]
 39
 40            # Open it for input
 41            self.controller.open()
 42
 43            # Push this object as a handler for controller events.
 44            # Required for the controller events to be called.
 45            self.controller.push_handlers(self)
 46
 47    def update(self, delta_time: float = 1 / 60):
 48        """ Move the player """
 49
 50        # If there is a controller, grab the speed.
 51        if self.controller:
 52
 53            # x-axis
 54            movement_x = self.controller.leftx
 55            if abs(movement_x) < DEAD_ZONE:
 56                self.change_x = 0
 57            else:
 58                self.change_x = movement_x * MOVEMENT_SPEED
 59
 60            # y-axis
 61            movement_y = self.controller.lefty
 62            if abs(movement_y) < DEAD_ZONE:
 63                self.change_y = 0
 64            else:
 65                self.change_y = movement_y * MOVEMENT_SPEED
 66
 67        # Move the player
 68        self.center_x += self.change_x
 69        self.center_y += self.change_y
 70
 71        # Keep from moving off-screen
 72        if self.left < 0:
 73            self.left = 0
 74        elif self.right > WINDOW_WIDTH - 1:
 75            self.right = WINDOW_WIDTH - 1
 76
 77        if self.bottom < 0:
 78            self.bottom = 0
 79        elif self.top > WINDOW_HEIGHT - 1:
 80            self.top = WINDOW_HEIGHT - 1
 81
 82    def on_button_press(self, controller, button_name):
 83        """ Handle button-down event for the controller """
 84        print(f"Button {button_name} down")
 85
 86    def on_button_release(self, controller, button_name):
 87        """ Handle button-up event for the controller """
 88        print(f"Button {button_name} up")
 89
 90    def on_stick_motion(self, controller, stick_name, x, y):
 91        """ Handle hat events """
 92        print(f"Movement on stick {stick_name}: ({x}, {y})")
 93
 94
 95class GameView(arcade.View):
 96    """
 97    Main application class.
 98    """
 99
100    def __init__(self):
101        """
102        Initializer
103        """
104        # Call the parent class initializer
105        super().__init__()
106
107        # Variables that will hold sprite lists
108        self.all_sprites_list = None
109
110        # Set up the player info
111        self.player_sprite = None
112
113        # Set the background color
114        self.background_color = arcade.color.AMAZON
115
116        self.error_text = arcade.Text(
117            "There are no controllers, plug in a controller and run again.",
118            10,
119            10,
120            arcade.color.WHITE,
121            22,
122            width=WINDOW_WIDTH,
123            align="center",
124        )
125
126    def setup(self):
127        """ Set up the game and initialize the variables. """
128
129        # Sprite lists
130        self.all_sprites_list = arcade.SpriteList()
131
132        # Set up the player
133        self.player_sprite = Player(
134            ":resources:images/animated_characters/female_person/"
135            "femalePerson_idle.png",
136            SPRITE_SCALING,
137        )
138        self.player_sprite.position = self.width / 2, self.height / 2
139        self.all_sprites_list.append(self.player_sprite)
140
141    def on_draw(self):
142        """
143        Render the screen.
144        """
145
146        # This command has to happen before we start drawing
147        self.clear()
148
149        # Draw all the sprites.
150        self.all_sprites_list.draw()
151
152        # Print an error if there is no controller
153        if not self.player_sprite.controller:
154            self.error_text.draw()
155
156    def on_update(self, delta_time):
157        """ Movement and game logic """
158
159        # Call update on all sprites (The sprites don't do much in this
160        # example though.)
161        self.all_sprites_list.update(delta_time)
162
163    def on_key_press(self, key, modifiers):
164        """Called whenever a key is pressed. """
165
166        if key == arcade.key.UP:
167            self.player_sprite.change_y = MOVEMENT_SPEED
168        elif key == arcade.key.DOWN:
169            self.player_sprite.change_y = -MOVEMENT_SPEED
170        elif key == arcade.key.LEFT:
171            self.player_sprite.change_x = -MOVEMENT_SPEED
172        elif key == arcade.key.RIGHT:
173            self.player_sprite.change_x = MOVEMENT_SPEED
174
175    def on_key_release(self, key, modifiers):
176        """Called when the user releases a key. """
177
178        if key == arcade.key.UP or key == arcade.key.DOWN:
179            self.player_sprite.change_y = 0
180        elif key == arcade.key.LEFT or key == arcade.key.RIGHT:
181            self.player_sprite.change_x = 0
182
183
184def main():
185    """ Main function """
186    # Create a window class. This is what actually shows up on screen
187    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
188
189    # Create and setup the GameView
190    game = GameView()
191    game.setup()
192
193    # Show GameView on screen
194    window.show_view(game)
195
196    # Start the arcade game loop
197    arcade.run()
198
199
200if __name__ == "__main__":
201    main()