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()