Python Arcade Sprite Lists and Postgres
Welcome to part 2 of a multi-part tutorial on building a top-down 80’s style video game. In this part we learn to use Python Arcade Sprite Lists and Postgres for storing screens and some of the Sprites.
In this lesson we learn about Sprites and Sprite Lists. We’ll back track over some of part 1 of this series and add new functions and information.
IMPORTANT: All of the source code, image files, and sound files are available here for you to download. For each lesson, we are copying parts of that full source code into the lesson and analyzing it, explaining in detail how each part works.
Be sure to read part 1 of this series where we get some of the basics out of the way.
Use PIP to install Flask, psycopg2, random, and the Arcade libraries. Arcade Library documentation here. The Python library we will use for much of the purely game-related functionality of this game is Arcade.
Get a basic understanding of Python Arcade resources here.
What is a Sprite?
The first thing to do is understand what a Python Arcade Sprite is. In video games, a sprite is a bitmap placed on a screen. Sprites were created by Daniel Hillis at Texas Instruments. Earliest systems with built-in sprites include Atari computers from the 80’s, Texas Instruments TI-99/4A, Commodore Vic20, 64, and Amiga, Sega Genesis, NES, and many arcade games from the 1980’s.
Create a single Arcade Sprite
Before creating a sprite, we’ll assume you went through part 1 and learned to create a window.
# install Python's arcade library.
# Set up variables for screen width and height and title (caption)
screen_width = 1200
screen_height = 900
screen_title = "My Game Test"
# Create game window.
arcade.open_window(screen_width, screen_height, screen_title)
# Set window background color.
# Initialize and set an image for a Sprite.
mySprite = arcade.Sprite("sprites/mybitmap.png")
# Set up two variables for coordinates.
x = 200
y = 200
# Set Sprite position.
# Draw the Sprite to the screen.
# Keep the window up until the player closes it.
Analysis of the above code:
import arcade: The arcade library adds many game-related functions. This is probably the most important library to the functioning of our game.
screen_width = 1200: Setting up a variable to store the screen width. We are choosing a width of 1200 pixels here.
screen_height = 900: Setting up a variable to store the screen height. We are choosing a height of 900 pixels here.
arcade.open_window: The open_window function takes three parameters; width, height, and title. Width and height require integers. Title requires a string (text).
arcade.set_background_color: The set_background_color function takes one parameter; color. Notice these can be expressed using arcade constants or as RGBA, where the “A” means alpha (opacity).
arcade.Sprite: This line creates a Sprite, names it “mySprite”, and gives it a graphic “sprites/mybitmap.png”.
x = 200: Setting up a variable to store the distance in pixels from the left side of the screen.
y = 200: Setting up a variable to store the distance in pixels from the bottom of the screen. So zero would be the very bottom and 900 would be the very top.
mySprite.set_position: This moves the Sprite to be at the x and y coordinates we had set to 200 by 200, respectively.
mySprite.draw: Makes the Sprite visible on the screen.
arcade.run: Runs the program.
Now that we see how easy it is to create a Sprite, let’s move on to placing Sprites in a list.
What is an Arcade Sprite List?
Arcade capitalizes on Python’s list object to give us Sprite lists. These allow us to easily operate on groups of Sprites. In our game we use this feature for snowballs (bullets), walruses (enemies), and ice blocks (obstructions). For bullets, this allows the player to “fire” multiple bullets at a time. For enemies, we can track as many enemies (within reason) as we want. And for ice blocks, we can put hundreds on the screen if we want. I invite you to experiment with changing the default (constant) variables for all these objects to see how it affects game play and performance. From our perspective, Python seems to be quite efficient with not only displaying all these objects at once, moving them, and even detecting collisions between one object and groups. In a future part of this series we will definitely be analyzing how to do all of that.
Let’s look at some code showing Sprites being created and then added to a list of Sprites. We’ll use a for loop to accomplish the part where we want to iterate through more than one. In order to get multiple Sprites for our Sprite List, we’ll use the Postgres table we created in part 1. Since we went over that in a fair amount of detail in part 1, we’ll gloss over the database part here:
# Create a Sprite List for ice blocks
list_ice_blocks = arcade.SpriteList()
The above code initializes a Sprite List that acts just like a typical Python list, except that it has quite a few properties and methods inherited from Python’s Arcade library, such as center_x, center_y, and many others.
Now we’ll query Postgres for all the ice blocks in tbl_screens_objects.
# SQL to get Sprite screen x/y coordinates from the database.
s = ""
s += "SELECT"
s += " i_x"
s += ", i_y"
s += " FROM tbl_screens_objects"
s += " WHERE ("
s += " id_screen = 1"
s += " AND t_object_type = 'ice block'"
s += ")"
Now that we pulled a set of records into db_cursor, we can move on to iterate through each row returned, where a row represents one ice block, and draw the blocks to the screen.
# Iterate through the Postgres rows returned
# and place each block using the x and y coordinates
# provided in each row returned.
for each row in db_cursor:
# Get column 0 and column 1 from the current row
x = row
y = row
# Create the current ice block as a sprite
ice_block = arcade.Sprite("./resources/images/block-ice.png", SCALE)
# Move the current ice block to be at the x/y coordinates we pulled from the database.
ice_block.center_x = x
ice_block.center_y = y
# Here is where we add a Sprite to our Sprite List
If the above code made sense, let’s get slightly more complex by combining a typical Python list to store image file names with a Sprite List of enemies. The purpose of the following code is merely to alter your angle of perspective on how Sprite Lists work slightly to increase your understanding.
# Create a Sprite List for the enemies
list_enemies = arcade.SpriteList()
# Set up a Python List to store four different colored images of walruses.
image_list = ("./resources/images/walrus-red.png",
# Cycle through 6 enemies:
for i in range(6):
# Pick a random colored image from the Python image list.
image_no = random.randint(0,3) # generates 0, 1, 2, or 3
# for non-random, like if you have four enemies and want
# each to be one of the above colors, use image_no = i here.
enemy_sprite = EnemySprite(image_list[image_no], SCALE)
# Set the screen position of the enemy sprite.
enemy_sprite.center_y = random.randint(LIMIT_BOTTOM, LIMIT_TOP+1)
enemy_sprite.center_x = random.randint(LIMIT_LEFT, LIMIT_RIGHT+1)
# Set movement direction of this enemy sprite.
enemy_sprite.change_x = int(random.random() * 2 + (DIFFICULTY/10) - 1)
enemy_sprite.change_y = int(random.random() * 2 + (DIFFICULTY/10) - 1)
# Add this Sprite to our Sprite list
This was part 2 of a multi-part tutorial lesson on building an arcade-style game. In this part we learned about Sprites and Sprite Lists, including how to associate a Sprite with an image, set the coordinates for a Sprite, and finally, how to group Sprites into Sprite Lists so that we can later have more control over groups of Sprites. Coming up, part 3 where we learn to read the keyboard, giving the user control over his player.
Pilot the ObjectRocket Platform Free!
Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.Get Started