Array-Backed Grid Buffered#
You may also want to look at:
Array-Backed Grid - very slow but simple, uses drawing commands
Array-Backed Grid Buffered - (This program) slow and uses buffered shapes
Grid Using Sprites v1 - 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
3
4Show how to use a two-dimensional list/array to back the display of a
5grid on-screen. We can click each cell in the window to toggle the color
6or each individual cell.
7
8This is not the most efficient way to maintain an updated grid
9simply because we have to rebuild the shape list from scratch
10every time it changes, but it's fast enough for smaller grids
11that don't update frequently.
12
13If Python and Arcade are installed, this example can be run from the command line with:
14python -m arcade.examples.array_backed_grid_buffered
15"""
16from __future__ import annotations
17
18import arcade
19
20# Set how many rows and columns we will have
21ROW_COUNT = 15
22COLUMN_COUNT = 15
23
24# This sets the WIDTH and HEIGHT of each grid location
25WIDTH = 30
26HEIGHT = 30
27
28# This sets the margin between each cell
29# and on the edges of the screen.
30MARGIN = 5
31
32# Do the math to figure out our screen dimensions
33SCREEN_WIDTH = (WIDTH + MARGIN) * COLUMN_COUNT + MARGIN
34SCREEN_HEIGHT = (HEIGHT + MARGIN) * ROW_COUNT + MARGIN
35SCREEN_TITLE = "Array Backed Grid Buffered Example"
36
37
38class MyGame(arcade.Window):
39 """
40 Main application class.
41 """
42
43 def __init__(self, width, height, title):
44 """
45 Set up the application.
46 """
47 super().__init__(width, height, title)
48 self.shape_list = None
49
50 # Create a 2 dimensional array. A two dimensional
51 # array is simply a list of lists.
52 # This array can be altered later to contain 0 or 1
53 # to show a white or green cell.
54 #
55 # A 4 x 4 grid would look like this
56 #
57 # grid = [
58 # [0, 0, 0, 0],
59 # [0, 0, 0, 0],
60 # [0, 0, 0, 0],
61 # [0, 0, 0, 0],
62 # ]
63 # We can quickly build a grid with python list comprehension
64 # self.grid = [[0] * COLUMN_COUNT for _ in range(ROW_COUNT)]
65 # Making the grid with loops:
66 self.grid = []
67 for row in range(ROW_COUNT):
68 # Add an empty array that will hold each cell
69 # in this row
70 self.grid.append([])
71 for column in range(COLUMN_COUNT):
72 self.grid[row].append(0) # Append a cell
73
74 # Set the window's background color
75 self.background_color = arcade.color.BLACK
76 # Create shapes from the grid
77 self.recreate_grid()
78
79 def recreate_grid(self):
80 """
81 Create the shapes for our current grid.
82
83 We look at the values in each cell.
84 If the cell contains 0 we crate a white shape.
85 If the cell contains 1 we crate a green shape.
86 """
87 self.shape_list = arcade.shape_list.ShapeElementList()
88 for row in range(ROW_COUNT):
89 for column in range(COLUMN_COUNT):
90 if self.grid[row][column] == 0:
91 color = arcade.color.WHITE
92 else:
93 color = arcade.color.GREEN
94
95 x = (MARGIN + WIDTH) * column + MARGIN + WIDTH // 2
96 y = (MARGIN + HEIGHT) * row + MARGIN + HEIGHT // 2
97
98 current_rect = arcade.shape_list.create_rectangle_filled(x, y, WIDTH, HEIGHT, color)
99 self.shape_list.append(current_rect)
100
101 def on_draw(self):
102 """
103 Render the screen.
104 """
105 # We should always start by clearing the window pixels
106 self.clear()
107
108 # Draw the shapes representing our current grid
109 self.shape_list.draw()
110
111 def on_mouse_press(self, x, y, button, modifiers):
112 """
113 Called when the user presses a mouse button.
114 """
115
116 # Convert the clicked mouse position into grid coordinates
117 column = int(x // (WIDTH + MARGIN))
118 row = int(y // (HEIGHT + MARGIN))
119
120 print(f"Click coordinates: ({x}, {y}). Grid coordinates: ({row}, {column})")
121
122 # Make sure we are on-grid. It is possible to click in the upper right
123 # corner in the margin and go to a grid location that doesn't exist
124 if row >= ROW_COUNT or column >= COLUMN_COUNT:
125 # Simply return from this method since nothing needs updating
126 return
127
128 # Flip the location between 1 and 0.
129 if self.grid[row][column] == 0:
130 self.grid[row][column] = 1
131 else:
132 self.grid[row][column] = 0
133
134 # Rebuild the shapes
135 self.recreate_grid()
136
137
138def main():
139 MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
140 arcade.run()
141
142
143if __name__ == "__main__":
144 main()