Array-Backed Grid Buffered

Screenshot of a program that shows an array backed grid.

You may also want to look at:

array_backed_grid_buffered.py
  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"""
 16import arcade
 17
 18# Set how many rows and columns we will have
 19ROW_COUNT = 15
 20COLUMN_COUNT = 15
 21
 22# This sets the WIDTH and HEIGHT of each grid location
 23WIDTH = 30
 24HEIGHT = 30
 25
 26# This sets the margin between each cell
 27# and on the edges of the screen.
 28MARGIN = 5
 29
 30# Do the math to figure out our screen dimensions
 31WINDOW_WIDTH = (WIDTH + MARGIN) * COLUMN_COUNT + MARGIN
 32WINDOW_HEIGHT = (HEIGHT + MARGIN) * ROW_COUNT + MARGIN
 33WINDOW_TITLE = "Array Backed Grid Buffered Example"
 34
 35
 36class GameView(arcade.View):
 37    """
 38    Main application class.
 39    """
 40
 41    def __init__(self):
 42        """
 43        Set up the application.
 44        """
 45        super().__init__()
 46        self.shape_list = None
 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 shapes from the grid
 75        self.recreate_grid()
 76
 77    def recreate_grid(self):
 78        """
 79        Create the shapes for our current grid.
 80
 81        We look at the values in each cell.
 82        If the cell contains 0 we crate a white shape.
 83        If the cell contains 1 we crate a green shape.
 84        """
 85        self.shape_list = arcade.shape_list.ShapeElementList()
 86        for row in range(ROW_COUNT):
 87            for column in range(COLUMN_COUNT):
 88                if self.grid[row][column] == 0:
 89                    color = arcade.color.WHITE
 90                else:
 91                    color = arcade.color.GREEN
 92
 93                x = (MARGIN + WIDTH) * column + MARGIN + WIDTH // 2
 94                y = (MARGIN + HEIGHT) * row + MARGIN + HEIGHT // 2
 95
 96                current_rect = arcade.shape_list.create_rectangle_filled(
 97                    x, y, WIDTH, HEIGHT, color,
 98                )
 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    """ Main function """
140    # Create a window class. This is what actually shows up on screen
141    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
142
143    # Create the GameView
144    game = GameView()
145
146    # Show GameView on screen
147    window.show_view(game)
148
149    # Start the arcade game loop
150    arcade.run()
151
152
153if __name__ == "__main__":
154    main()