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