Keyboard in Python and Cockroach

Introduction

Welcome to the third part of a multi-article set of writings for building a top-down perspective video game. In this one we learn to read the keyboard in Python and Cockroach is used for managing GUI screens and Sprite location data.

In this lesson we will learn how to get key press inputs from the user with event handler methods built into the Python Arcade framework. First, we’ll back track over some of the preceding parts in this series and then build more on top of that.

Prerequisites

  • Please be sure to read part one and part two of this series where we get some of the basics out of the way.

  • IMPORTANT: All source code, image files, and sound files are available here. For each lesson we copied only the necessary parts of that source code into the current lesson and analyzing it, explaining how that portion works, so not every lesson will have SQL and/or detailed references to/use of CockroachDB.

  • Install the following libraries: arcade, datetime, flask, math, os, psycopg2, pyautogui, and random. You will see that code in the full source. As we move through each lesson, you will learn more functions that require these frameworks.

  • Arcade documentation. The Python library we used for the game-related classes, methods, and functions in Zombie Feeder.

  • Gain a deeper understanding of Arcade here.

Before we learn to scan for key presses, let’s do a brief recap by creating a screen and placing a player on that GUI.

Create a GUI

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Use the arcade framework.
import arcade

# Initialize variables for GUI width,
# screen height, and GUI window title.
screen_width = 1200
screen_height = 900
screen_title = "Zombie Feeder"

# Open a GUI for game play.
arcade.open_window(screen_width, screen_height, screen_title)

# Set color for the background color.
arcade.set_background_color(arcade.color.BLACK)

# Initialize Sprite and set an image for it.
spritePlayer = arcade.Sprite("sprites/monkey.png")

# Initialize variables for the
# player Sprite's coordinates.
# Divide screen width by two to calculate
# the horizontal center of the GUI.
x_pos = int(screen_width / 2)
# Divide screen height by two to calculate
# the vertical center of the GUI.
y_pos = int(screen_height / 2)

# Set Player Sprite position.
spritePlayer.set_position(x_pos, y_pos)

# Draw the Player Sprite.
spritePlayer.draw()

# Keep the GUI open until
# the player closes it.
arcade.run()

Analysis of the above code:

  • import arcade: The Arcade library provides us with functions useful in making our 2D game.

  • screen_width = 1200: Initialize a variable to store screen width. We used a width of 1200.

  • screen_height = 900: Initialize a variable to store screen height. We used a height of 900.

  • screen_title = “Zombie Feeder”: Initializes a variable for the caption to be placed in the screen’s title bar.

  • arcade.open_window: The open_window function requires three parameters; width, height, and title. Width and height must be integers where title is a string encapsulated in either semi-quotes or quotes.

  • arcade.set_background_color: The set_background_color function needs 1 parameter; color. The color can be set using arcade constants as you see above or you can use an RGBA value.

  • arcade.Sprite: This script line creates a Sprite, names it “spritePlayer”, and provides it with a PNG image.

  • x_pos = int(screen_width / 2): Initialize a variable to handle the distance from the left border of the GUI.

  • y_pos = int(screen_height / 2): Initialize a variable to store the distance from the bottom edge of the GUI. This means zero would be the bottom and 900 would be the top. I want to make it clear this is “from the bottom” because some other systems start at the top.

  • spritePlayer.set_position: Sets the Player Sprite’s coordinate position to be at the x and y coordinates we set to be at the center of the GUI.

  • spritePlayer.draw: Makes the Player’s Sprite visible in the game GUI.

  • arcade.run: Executes the current code.

Now that we have reviewed how to set up a game environment and added a bit more, it is time to look at how to listen for key presses.

IMPORTANT NOTE The code here for reading keyboard was heavily modified from this awesome open source project: Python Arcade Library

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# When a key is clicked, this function is called:
def on_key_press(self, symbol, modifiers):
    # symbol is the key being pressed.
    # If the player hit the space bar and
    # not in respawning mode, shoot a bullet.
    if symbol == arcade.key.SPACE and not self.player_sprite.respawning:
        # Assign an image to the new sprite.
        bullet_sprite = bulletSprite("./resources/images/bullet.png", SCALE)
        # Name the sprite.
        bullet_sprite.guid = "bullet"
        # Assign a speed to the sprite.
        bullet_speed = 8
        # Set direction.
        bullet_sprite.change_y = \
            math.cos(math.radians(self.player_sprite.angle)) * bullet_speed
        bullet_sprite.change_x = \
            -math.sin(math.radians(self.player_sprite.angle)) \
            * bullet_speed
        # Set location.
        bullet_sprite.center_x = self.player_sprite.center_x
        bullet_sprite.center_y = self.player_sprite.center_y
        # Update the sprite in memory.
        bullet_sprite.update()
        # Add new sprite to the two relevant sprite lists.
        self.list_all_sprites.append(bullet_sprite)
        self.list_bullets.append(bullet_sprite)
        # Play a throwing sound.
        arcade.play_sound(self.sound_throw)
    # If they pressed the left cursor control key or the "A" key,
    # change player facing angle 2 degrees counter clockwise.
    if symbol == arcade.key.LEFT or symbol == arcade.key.A:
        self.player_sprite.change_angle = 2
    # If they pressed the right cursor control key or the "D" key,
    # change player facing angle 2 degrees counter counter-clockwise.
    elif symbol == arcade.key.RIGHT or symbol == arcade.key.D:
        self.player_sprite.change_angle = -2
    # If they pressed the up cursor or the "W" key,
    # increase thrust.
    elif symbol == arcade.key.UP or symbol == arcade.key.W:
        self.player_sprite.thrust = 0.15
    # If they pressed the down cursor or the "S" key,
    # decrease thrust toward opposite direction.
    elif symbol == arcade.key.DOWN or symbol == arcade.key.S:
        self.player_sprite.thrust = -.2

# When any movement key is released.
def on_key_release(self, symbol, modifiers):
    # If LEFT cursor or "A" UNpressed: Set change angle to zero
    if symbol == arcade.key.LEFT or symbol == arcade.key.A:
        self.player_sprite.change_angle = 0
    # If RIGHT cursor or "D" UNpressed: Set change angle to zero
    elif symbol == arcade.key.RIGHT or symbol == arcade.key.D:
        self.player_sprite.change_angle = 0
    # If UP cursor or "W" UNpressed: Set thrust to zero
    elif symbol == arcade.key.UP or symbol == arcade.key.W:
        self.player_sprite.thrust = 0
    # If DOWN cursor or "S" UNpressed: Set thrust to zero
    elif symbol == arcade.key.DOWN or symbol == arcade.key.S:
        self.player_sprite.thrust = 0

Conclusion

In this third part of the multi-article for building the Zombie Feeder game, we learned to use the Arcade library to get input from key presses and process that input into changes in the position and angle of direction of the player Sprite. In part four, we will go further with learning code to process the player Sprite’s movement around the GUI. After that, we’ll play with enemy movements, bullets, detection of collisions, music and sound effects, scoring, and allowing the player to change speed and difficulty on the fly.

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.