Python Arcade Game Register and Postgres

Have a Database Problem? Speak with an Expert for Free
Get Started >>

Introduction

This is part 11 of a multi-part group of tutorials that teach how to build a 2D game. In this part 11, we amp-up the fun by learning how to use Python Arcade for game register and Postgres for saving score, users, and storing the screen state. In this part, we see how to allow users to register using the database. In the article following this one, we’ll add user login. After that part, we will begin to explore adding online multiplayer ability to the game using sockets!

Prerequisites

  • Explore ALL of the source code for the complete and playable game, including images and sound files is available for download.

  • NOTE: You can study starting at part 1 where we began by (a) learning how to create and set up a game screen window with Postgres; (b) how to create Sprites with images and group those Sprites into Sprite Lists; (c) how to check key press event and move the Player’s Sprite around the game window; (d) how to move enemies with randomness and semi-intelligence, depending on difficulty level; (e) exploring the player firing multiple bullets with the space bar, moving those bullets; (f) dealing with collisions between Sprites and Sprite Lists; (g) adding various sound effects, including background music; (h) keeping score and storing that score in the database; and (i) changing game difficulty and speed during game play and displaying that difficulty on the screen.

  • If you are interested or curious about all the functions in Python Arcade, here is the documentation.

Let’s begin by building a simple registration screen using HTML.

Script for registration screen

Below is a registration screen built in HTML. This will render the same in most all web browsers. Name this page “game_registration.html” and put it in a folder called “templates” off the root of your project folder:

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
<html>
    <head>
        <link rel="shortcut icon" href="favicon.ico">
        <title>Pyngo Skater Game Registration</title>
    </head>
<body>
<!-- The "t_message_value" you see below is part of this page being a "template" -->
<!-- Since this page is "dynamic", the server can fill in at the -->
<!-- placeholder of {{t_message_value}} with the value you sent via -->
<!-- render_template("game_registration.html", t_message_value = "A text string to be placed in the h1 tag below") -->
<h1>{{t_message_value}}</h1>
<!-- Open outer container div -->
<div>
    <!-- Set up html POSTing form to allow user input -->
    <!-- method='post' sends the data back to Python as a post for request to pick up. -->
    <form id='frmRegister' name='frmRegister' action='' method='post' onsubmit='return true;'>
    <!-- Input field for the user to enter their email. -->
    <!-- Input has a 'name' parameter of 't_email_user'. -->
    <!-- So our request function in Python will use this -->
    <!--   to get data from this field. -->
    <div class="formrow">
    User Name: <input name="t_email_user" type="text">
    </div>
    <div class="formrow">
    Password: <input name="t_password_user" type="text">
    </div>
    <!-- button for the user to submit the field values in the form. -->
    <div>
      <input name="btnSubmitAddUser" value='Register Now' type="submit">
    </div>
    <!-- Close the HTML form. -->
    </form>
<!-- Close the outer container div. -->
</div>
<!-- Close the HTML body of the template. -->
</body>
</html>

The next feature to understand is how we call that “game_registration.html” page – called a “template” – from within our Python game code.

Python Flask render_template

Flask’s Render_Template() shows the user an HTML page in their web browser. This page can even be filled with dynamic content we determine by using parameters in the render template function.

1
2
3
4
# Render_template requires the Flask framework.
from flask import Flask
from flask import render_template
return render_template("/templates/game_registration.html", t_message_value = "Welcome to Pyngo Skater!")

Analysis

  • t_message_value: The contents of “t_message_value” will be sent, along with the user, to game_registration.html, the html template we built earlier in this part. The page is dynamic, so it can receive and use t_message_value. Note: instead of “t_message_value”, you can call your variable anything you like and can send more parameters and values, if needed, using commas to separate each.

Next, we will write some Python to request the information the user submitted via the HTML form we created. First, let’s do a quick study of how Flask’s request function works.

Python Flask Request Syntax

1
2
value_received = request.args.get(field_in_URL, default value) # GET, which is a querystring.
value_received = request.form.get(field_on_html_form, default value) # POST, from method=post in an HTML form.

Analysis

  • field_on_html_form or field_in_URL: This uses field name, as designated in your querystring or on the form. A querystring is data tacked on to the end of a URL, like so: “https://domain.ext?field_in_URL=5”.
  • default value: If no value was sent by the user, this is the value that will be placed into value_received.

Python Flask Request Examples

Examples of how the syntax will look in applications. We’ll leave out “get” as it has no use in our current project:

1
2
t_email_user = request.form.get("t_email_user", "")
t_password_user = request.form.get("t_password_user", "")

Analysis

  • t_email_user: This gets the value the user put into the HTML field called “t_email_user” and places that value in the local Python text variable also named “t_email_user”.

  • t_password_user: Same exact concept as the above example for t_email_user.

Finally, let’s start looking at some Python code for requesting the user-submitted email address and password.

Python request from form

We’ll start by using the render_template() function we studied above to send the user to the HTML page created above and then request the data submitted by the prospective player.

1
2
3
4
5
@app.route("/registration", methods=["POST","GET"])
def registration():
    return RENDER_TEMPLATE("game_registration.html", t_message_value = "Pyngo Skater Registration")
    t_email_user = REQUEST.form.get("t_email_user", "")
    t_password_user = REQUEST.form.get("t_password_user", "")

Secure user input with hashing

1
2
    t_password_hashed = hashlib.sha3_512(t_password_user.encode())
    t_password_user = t_password_hashed.hexdigest()

Analysis

  • We start with the value a new player put into “t_password_user”, use the hashlib function to “encrypt” it, and store the resulting encrypted value in a variable we named “t_value_hashed”.
  • We then use hexdigest() to convert the byte value returned by hashlib() into hex type data.

Insert Into Postgres

1
2
3
4
5
6
7
8
9
10
s = ""
s += "INSERT INTO tbl_game_users "
s += "("
s += " t_email_user"
s += ", t_password_user"
s += ") VALUES ("
s += " '(%t_email_user)'"
s += ", '(%t_password_user)'"
s += ")"
data_cursor.execute(s, [t_email_user, t_password_user])

Analysis: Here we are using an SQL statement to build a parameterized query for safety, where the parameters are t_email_user and t_password_user, both to be INSERTed into tbl_game_users in Postgres.

Full Python Code Listing

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
# Be sure to install the following libraries with PIP
from flask import Flask
from flask import request
from flask import render_template
import psycopg2
import hashlib

# Set up
app = Flask(__name__)
@app.route("/", methods=["POST","GET"])

# Database credentials
t_host = "db host address"
t_port = "5432"
t_dbname = "db name"
t_user = "db user name"
t_pw = "db user password"
data_connection = psycopg2.connect(host=t_host, port=t_port, dbname=t_dbname, user=t_user, password=t_pw)
data_cursor = data_connection.cursor()

def registration():
    return render_template("game_registration.html", t_message_value = "Register to get save game capability")
    t_email_user = request.form.get("t_email_user", "")
    t_password_user = request.form.get("t_password_user", "")

    # Check to be sure user email field is not empty.
    if t_email_user == "":
        t_message_value = "Empty email field."
        # Send player back to the dynamic html template with the above message.
        return render_template("game_registration.html", t_message_value = t_message_value)
    # Check to be sure user password is not empty.
    if t_password_user == "":
        t_message_value = "Please create a password"
        # Send player back to the template with the above message.
        return render_template("game_registration.html", t_message_value = t_message_value)

    # Encrypt the password they entered.
    t_value_hashed = hashlib.sha256(t_password_user.encode())
    t_password_user = t_value_hashed.hexdigest()

    # Build a parameterized query for insertion of user data into PostgreSQL
    s = ""
    s += "INSERT INTO tbl_game_users "
    s += "("
    s += " t_email_user"
    s += ",t_password_user"
    s += ") VALUES ("
    s += " '(%t_email_user)'"
    s += ",'(%t_password_user)'"
    s += ")"
    # Use error catching via "try" and "except" command.
    try:
        data_cursor.execute(s, [t_email_user, t_password_user])
        data_connection.commit()
    except psycopg2.Error as e:
        t_message_value = "Database error: " + e + "/n SQL: " + s
        return render_template("game_registration.html", t_message_value = t_message_value)
    data_cursor.close()

Conclusion

In this part 11 of a multi-part set of articles where we learn how to build an action game, we learned how to use Python Arcade for game registration and Postgres for saving that user data, score, and saving and retrieving screen state. In this part, we explored allowing users to register using Postgres. In the article following this one, we will add user login. THEN we’ll start exploring online multiplayer ability using sockets!

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.