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