Grid Using Sprites v1#

Screenshot of a program that shows an array backed grid.

You may also want to look at:

array_backed_grid_sprites_1.py#
  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()