Array-Backed Grid#

Screenshot of a program that shows an array backed grid.

If you work with grids much, you’ll find this to be slow. You may want to look at:

array_backed_grid.py#
  1"""
  2Array Backed Grid
  3
  4Show how to use a two-dimensional list/array to back the display of a
  5grid on-screen.
  6
  7Note: Regular drawing commands are slow. Particularly when drawing a lot of
  8items, like the rectangles in this example.
  9
 10For faster drawing, create the shapes and then draw them as a batch.
 11See array_backed_grid_buffered.py
 12
 13If Python and Arcade are installed, this example can be run from the command line with:
 14python -m arcade.examples.array_backed_grid
 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 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
 48        super().__init__(width, height, title)
 49
 50        # Create a 2 dimensional array. A two-dimensional
 51        # array is simply a list of lists.
 52        self.grid = []
 53        for row in range(ROW_COUNT):
 54            # Add an empty array that will hold each cell
 55            # in this row
 56            self.grid.append([])
 57            for column in range(COLUMN_COUNT):
 58                self.grid[row].append(0)  # Append a cell
 59
 60        self.background_color = arcade.color.BLACK
 61
 62    def on_draw(self):
 63        """
 64        Render the screen.
 65        """
 66
 67        # This command has to happen before we start drawing
 68        self.clear()
 69
 70        # Draw the grid
 71        for row in range(ROW_COUNT):
 72            for column in range(COLUMN_COUNT):
 73                # Figure out what color to draw the box
 74                if self.grid[row][column] == 1:
 75                    color = arcade.color.GREEN
 76                else:
 77                    color = arcade.color.WHITE
 78
 79                # Do the math to figure out where the box is
 80                x = (MARGIN + WIDTH) * column + MARGIN + WIDTH // 2
 81                y = (MARGIN + HEIGHT) * row + MARGIN + HEIGHT // 2
 82
 83                # Draw the box
 84                arcade.draw_rectangle_filled(x, y, WIDTH, HEIGHT, color)
 85
 86    def on_mouse_press(self, x, y, button, modifiers):
 87        """
 88        Called when the user presses a mouse button.
 89        """
 90
 91        # Change the x/y screen coordinates to grid coordinates
 92        column = int(x // (WIDTH + MARGIN))
 93        row = int(y // (HEIGHT + MARGIN))
 94
 95        print(f"Click coordinates: ({x}, {y}). Grid coordinates: ({row}, {column})")
 96
 97        # Make sure we are on-grid. It is possible to click in the upper right
 98        # corner in the margin and go to a grid location that doesn't exist
 99        if row < ROW_COUNT and column < COLUMN_COUNT:
100
101            # Flip the location between 1 and 0.
102            if self.grid[row][column] == 0:
103                self.grid[row][column] = 1
104            else:
105                self.grid[row][column] = 0
106
107
108def main():
109
110    MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
111    arcade.run()
112
113
114if __name__ == "__main__":
115    main()