Grid Using Sprites v1#

You may also want to look at:
Array-Backed Grid - very slow but simple, uses drawing commands
Array-Backed Grid Buffered - slow and uses buffered shapes
Grid Using Sprites v1 - (This program) super-fast and uses sprites. Resyncs to number grid in one function call
Grid Using Sprites v2 - super-fast and uses sprites. Keeps a second 2D grid of sprites to match 2D grid of numbers
array_backed_grid_sprites_1.py#
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | """
Array Backed Grid Shown By Sprites
Show how to use a two-dimensional list/array to back the display of a
grid on-screen.
This version syncs the grid to the sprite list in one go using resync_grid_with_sprites.
This is faster than rebuilding a shape list every time the grid changes,
but we are still inspecting every single cell of the grid when it updates.
There are faster ways, but this works for smaller grid sizes.
If Python and Arcade are installed, this example can be run from the command line with:
python -m arcade.examples.array_backed_grid_sprites_1
"""
import arcade
# Set how many rows and columns we will have
ROW_COUNT = 15
COLUMN_COUNT = 15
# This sets the WIDTH and HEIGHT of each grid location
WIDTH = 30
HEIGHT = 30
# This sets the margin between each cell
# and on the edges of the screen.
MARGIN = 5
# Do the math to figure out our screen dimensions
SCREEN_WIDTH = (WIDTH + MARGIN) * COLUMN_COUNT + MARGIN
SCREEN_HEIGHT = (HEIGHT + MARGIN) * ROW_COUNT + MARGIN
SCREEN_TITLE = "Array Backed Grid Example"
class MyGame(arcade.Window):
"""
Main application class.
"""
def __init__(self, width, height, title):
"""
Set up the application.
"""
super().__init__(width, height, title)
# Create a 2 dimensional array. A two dimensional
# array is simply a list of lists.
# This array can be altered later to contain 0 or 1
# to show a white or green cell.
#
# A 4 x 4 grid would look like this
#
# grid = [
# [0, 0, 0, 0],
# [0, 0, 0, 0],
# [0, 0, 0, 0],
# [0, 0, 0, 0],
# ]
# We can quickly build a grid with python list comprehension
# self.grid = [[0] * COLUMN_COUNT for _ in range(ROW_COUNT)]
# Making the grid with loops:
self.grid = []
for row in range(ROW_COUNT):
# Add an empty array that will hold each cell
# in this row
self.grid.append([])
for column in range(COLUMN_COUNT):
self.grid[row].append(0) # Append a cell
# Set the window's background color
self.background_color = arcade.color.BLACK
# Create a spritelist for batch drawing all the grid sprites
self.grid_sprite_list = arcade.SpriteList()
# Create a list of solid-color sprites to represent each grid location
for row in range(ROW_COUNT):
for column in range(COLUMN_COUNT):
x = column * (WIDTH + MARGIN) + (WIDTH / 2 + MARGIN)
y = row * (HEIGHT + MARGIN) + (HEIGHT / 2 + MARGIN)
sprite = arcade.SpriteSolidColor(WIDTH, HEIGHT, arcade.color.WHITE)
sprite.center_x = x
sprite.center_y = y
self.grid_sprite_list.append(sprite)
def resync_grid_with_sprites(self):
"""
Update the color of all the sprites to match
the color/stats in the grid.
We look at the values in each cell.
If the cell contains 0 we assign a white color.
If the cell contains 1 we assign a green color.
"""
for row in range(ROW_COUNT):
for column in range(COLUMN_COUNT):
# We need to convert our two dimensional grid to our
# one-dimensional sprite list. For example a 10x10 grid might have
# row 2, column 8 mapped to location 28. (Zero-basing throws things
# off, but you get the idea.)
# ALTERNATIVELY you could set self.grid_sprite_list[pos].texture
# to different textures to change the image instead of the color.
pos = row * COLUMN_COUNT + column
if self.grid[row][column] == 0:
self.grid_sprite_list[pos].color = arcade.color.WHITE
else:
self.grid_sprite_list[pos].color = arcade.color.GREEN
def on_draw(self):
"""
Render the screen.
"""
# We should always start by clearing the window pixels
self.clear()
# Batch draw all the sprites
self.grid_sprite_list.draw()
def on_mouse_press(self, x, y, button, modifiers):
"""
Called when the user presses a mouse button.
"""
# Convert the clicked mouse position into grid coordinates
column = int(x // (WIDTH + MARGIN))
row = int(y // (HEIGHT + MARGIN))
print(f"Click coordinates: ({x}, {y}). Grid coordinates: ({row}, {column})")
# Make sure we are on-grid. It is possible to click in the upper right
# corner in the margin and go to a grid location that doesn't exist
if row >= ROW_COUNT or column >= COLUMN_COUNT:
# Simply return from this method since nothing needs updating
return
# Flip the location between 1 and 0.
if self.grid[row][column] == 0:
self.grid[row][column] = 1
else:
self.grid[row][column] = 0
# Update the sprite colors to match the new grid
self.resync_grid_with_sprites()
def main():
MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.run()
if __name__ == "__main__":
main()
|