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
 18SCREEN_WIDTH = 800
 19SCREEN_HEIGHT = 600
 20SCREEN_TITLE = "Better Move Sprite with Keyboard Example"
 21
 22MOVEMENT_SPEED = 5
 23
 24
 25class Player(arcade.Sprite):
 26
 27    def update(self):
 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 > SCREEN_WIDTH - 1:
 38            self.right = SCREEN_WIDTH - 1
 39
 40        if self.bottom < 0:
 41            self.bottom = 0
 42        elif self.top > SCREEN_HEIGHT - 1:
 43            self.top = SCREEN_HEIGHT - 1
 44
 45
 46class MyGame(arcade.Window):
 47    """
 48    Main application class.
 49    """
 50
 51    def __init__(self, width, height, title):
 52        """
 53        Initializer
 54        """
 55
 56        # Call the parent class initializer
 57        super().__init__(width, height, title)
 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(":resources:images/animated_characters/female_person/femalePerson_idle.png",
 82                                    scale=SPRITE_SCALING)
 83        self.player_sprite.center_x = 50
 84        self.player_sprite.center_y = 50
 85        self.player_list.append(self.player_sprite)
 86
 87    def on_draw(self):
 88        """ Render the screen. """
 89
 90        # Clear the screen
 91        self.clear()
 92
 93        # Draw all the sprites.
 94        self.player_list.draw()
 95
 96    def update_player_speed(self):
 97
 98        # Calculate speed based on the keys pressed
 99        self.player_sprite.change_x = 0
100        self.player_sprite.change_y = 0
101
102        if self.up_pressed and not self.down_pressed:
103            self.player_sprite.change_y = MOVEMENT_SPEED
104        elif self.down_pressed and not self.up_pressed:
105            self.player_sprite.change_y = -MOVEMENT_SPEED
106        if self.left_pressed and not self.right_pressed:
107            self.player_sprite.change_x = -MOVEMENT_SPEED
108        elif self.right_pressed and not self.left_pressed:
109            self.player_sprite.change_x = MOVEMENT_SPEED
110
111    def on_update(self, delta_time):
112        """ Movement and game logic """
113
114        # Call update to move the sprite
115        # If using a physics engine, call update player to rely on physics engine
116        # for movement, and call physics engine here.
117        self.player_list.update()
118
119    def on_key_press(self, key, modifiers):
120        """Called whenever a key is pressed. """
121
122        if key == arcade.key.UP:
123            self.up_pressed = True
124            self.update_player_speed()
125        elif key == arcade.key.DOWN:
126            self.down_pressed = True
127            self.update_player_speed()
128        elif key == arcade.key.LEFT:
129            self.left_pressed = True
130            self.update_player_speed()
131        elif key == arcade.key.RIGHT:
132            self.right_pressed = True
133            self.update_player_speed()
134
135    def on_key_release(self, key, modifiers):
136        """Called when the user releases a key. """
137
138        if key == arcade.key.UP:
139            self.up_pressed = False
140            self.update_player_speed()
141        elif key == arcade.key.DOWN:
142            self.down_pressed = False
143            self.update_player_speed()
144        elif key == arcade.key.LEFT:
145            self.left_pressed = False
146            self.update_player_speed()
147        elif key == arcade.key.RIGHT:
148            self.right_pressed = False
149            self.update_player_speed()
150
151
152def main():
153    """ Main function """
154    window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
155    window.setup()
156    arcade.run()
157
158
159if __name__ == "__main__":
160    main()