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
 14from __future__ import annotations
 15
 16import arcade
 17
 18SPRITE_SCALING = 0.5
 19
 20SCREEN_WIDTH = 800
 21SCREEN_HEIGHT = 600
 22SCREEN_TITLE = "Better Move Sprite with Keyboard Example"
 23
 24MOVEMENT_SPEED = 5
 25
 26
 27class Player(arcade.Sprite):
 28
 29    def update(self):
 30        """ Move the player """
 31        # Move player.
 32        # Remove these lines if physics engine is moving player.
 33        self.center_x += self.change_x
 34        self.center_y += self.change_y
 35
 36        # Check for out-of-bounds
 37        if self.left < 0:
 38            self.left = 0
 39        elif self.right > SCREEN_WIDTH - 1:
 40            self.right = SCREEN_WIDTH - 1
 41
 42        if self.bottom < 0:
 43            self.bottom = 0
 44        elif self.top > SCREEN_HEIGHT - 1:
 45            self.top = SCREEN_HEIGHT - 1
 46
 47
 48class MyGame(arcade.Window):
 49    """
 50    Main application class.
 51    """
 52
 53    def __init__(self, width, height, title):
 54        """
 55        Initializer
 56        """
 57
 58        # Call the parent class initializer
 59        super().__init__(width, height, title)
 60
 61        # Variables that will hold sprite lists
 62        self.player_list = None
 63
 64        # Set up the player info
 65        self.player_sprite = None
 66
 67        # Track the current state of what key is pressed
 68        self.left_pressed = False
 69        self.right_pressed = False
 70        self.up_pressed = False
 71        self.down_pressed = False
 72
 73        # Set the background color
 74        self.background_color = arcade.color.AMAZON
 75
 76    def setup(self):
 77        """ Set up the game and initialize the variables. """
 78
 79        # Sprite lists
 80        self.player_list = arcade.SpriteList()
 81
 82        # Set up the player
 83        self.player_sprite = Player(":resources:images/animated_characters/female_person/femalePerson_idle.png",
 84                                    scale=SPRITE_SCALING)
 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()
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    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
157    window.setup()
158    arcade.run()
159
160
161if __name__ == "__main__":
162    main()