Better Move By Keyboard

Screen shot of moving a sprite by keyboard

If a player presses the left key, the sprite should move left. If the player hits both left and right, the player should stop. If the player lets off the left key, keeping the right key down, the player should move right.

The simpler method of handling keystrokes will not handle this correctly. This code tracks which key is down or up, and handles it properly.

See the highlighted sections.

sprite_move_keyboard_better.py
  1"""
  2Better Move Sprite With Keyboard
  3
  4Simple program to show moving a sprite with the keyboard.
  5This is slightly better than sprite_move_keyboard.py example
  6in how it works, but also slightly more complex.
  7
  8Artwork from https://kenney.nl
  9
 10If Python and Arcade are installed, this example can be run from the command line with:
 11python -m arcade.examples.sprite_move_keyboard_better
 12"""
 13
 14import arcade
 15
 16SPRITE_SCALING = 0.5
 17
 18WINDOW_WIDTH = 1280
 19WINDOW_HEIGHT = 720
 20WINDOW_TITLE = "Better Move Sprite with Keyboard Example"
 21
 22MOVEMENT_SPEED = 5
 23
 24
 25class Player(arcade.Sprite):
 26
 27    def update(self, delta_time: float = 1/60):
 28        """ Move the player """
 29        # Move player.
 30        # Remove these lines if physics engine is moving player.
 31        self.center_x += self.change_x
 32        self.center_y += self.change_y
 33
 34        # Check for out-of-bounds
 35        if self.left < 0:
 36            self.left = 0
 37        elif self.right > WINDOW_WIDTH - 1:
 38            self.right = WINDOW_WIDTH - 1
 39
 40        if self.bottom < 0:
 41            self.bottom = 0
 42        elif self.top > WINDOW_HEIGHT - 1:
 43            self.top = WINDOW_HEIGHT - 1
 44
 45
 46class GameView(arcade.View):
 47    """
 48    Main application class.
 49    """
 50
 51    def __init__(self):
 52        """
 53        Initializer
 54        """
 55
 56        # Call the parent class initializer
 57        super().__init__()
 58
 59        # Variables that will hold sprite lists
 60        self.player_list = None
 61
 62        # Set up the player info
 63        self.player_sprite = None
 64
 65        # Track the current state of what key is pressed
 66        self.left_pressed = False
 67        self.right_pressed = False
 68        self.up_pressed = False
 69        self.down_pressed = False
 70
 71        # Set the background color
 72        self.background_color = arcade.color.AMAZON
 73
 74    def setup(self):
 75        """ Set up the game and initialize the variables. """
 76
 77        # Sprite lists
 78        self.player_list = arcade.SpriteList()
 79
 80        # Set up the player
 81        self.player_sprite = Player(
 82            ":resources:images/animated_characters/female_person/femalePerson_idle.png",
 83            scale=SPRITE_SCALING,
 84        )
 85        self.player_sprite.center_x = 50
 86        self.player_sprite.center_y = 50
 87        self.player_list.append(self.player_sprite)
 88
 89    def on_draw(self):
 90        """ Render the screen. """
 91
 92        # Clear the screen
 93        self.clear()
 94
 95        # Draw all the sprites.
 96        self.player_list.draw()
 97
 98    def update_player_speed(self):
 99
100        # Calculate speed based on the keys pressed
101        self.player_sprite.change_x = 0
102        self.player_sprite.change_y = 0
103
104        if self.up_pressed and not self.down_pressed:
105            self.player_sprite.change_y = MOVEMENT_SPEED
106        elif self.down_pressed and not self.up_pressed:
107            self.player_sprite.change_y = -MOVEMENT_SPEED
108        if self.left_pressed and not self.right_pressed:
109            self.player_sprite.change_x = -MOVEMENT_SPEED
110        elif self.right_pressed and not self.left_pressed:
111            self.player_sprite.change_x = MOVEMENT_SPEED
112
113    def on_update(self, delta_time):
114        """ Movement and game logic """
115
116        # Call update to move the sprite
117        # If using a physics engine, call update player to rely on physics engine
118        # for movement, and call physics engine here.
119        self.player_list.update(delta_time)
120
121    def on_key_press(self, key, modifiers):
122        """Called whenever a key is pressed. """
123
124        if key == arcade.key.UP:
125            self.up_pressed = True
126            self.update_player_speed()
127        elif key == arcade.key.DOWN:
128            self.down_pressed = True
129            self.update_player_speed()
130        elif key == arcade.key.LEFT:
131            self.left_pressed = True
132            self.update_player_speed()
133        elif key == arcade.key.RIGHT:
134            self.right_pressed = True
135            self.update_player_speed()
136
137    def on_key_release(self, key, modifiers):
138        """Called when the user releases a key. """
139
140        if key == arcade.key.UP:
141            self.up_pressed = False
142            self.update_player_speed()
143        elif key == arcade.key.DOWN:
144            self.down_pressed = False
145            self.update_player_speed()
146        elif key == arcade.key.LEFT:
147            self.left_pressed = False
148            self.update_player_speed()
149        elif key == arcade.key.RIGHT:
150            self.right_pressed = False
151            self.update_player_speed()
152
153
154def main():
155    """ Main function """
156    # Create a window class. This is what actually shows up on screen
157    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
158
159    # Create and setup the GameView
160    game = GameView()
161    game.setup()
162
163    # Show GameView on screen
164    window.show_view(game)
165
166    # Start the arcade game loop
167    arcade.run()
168
169
170if __name__ == "__main__":
171    main()