康威的生活游戏#
这个版本的Conway的生活游戏通过控制单元格的Alpha值来控制单元格的可见性,并将绘图逻辑交给图形卡,从而加快了速度。
基于网格的游戏可能需要一段时间才能使用经典的基于栅格的图形来渲染程序。每个单元格都必须在每一帧中重新绘制。如果单元格非常复杂,则会增加渲染时间。
在本程序中,我们首先创建网格中的所有单元格。(这会导致程序在启动时暂停一段时间。)
创建精灵后,我们根据其Alpha值打开和关闭单元格。我们只需将Alpha值列表发送到图形卡,即可更新整个网格。这显著缩短了绘制时间。
conway_alpha.py#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | """ Conway's Game of Life This code shows how to set up sprites in a grid, and then use their 'alpha' value to quickly turn them on and off. After installing the "arcade" package version 2.4.4+, this program can be run by typing: python -m arcade.examples.conway_alpha """ import arcade import random # Set how many rows and columns we will have ROW_COUNT = 70 COLUMN_COUNT = 128 # This sets the WIDTH and HEIGHT of each grid location CELL_WIDTH = 15 CELL_HEIGHT = 15 # This sets the margin between each cell # and on the edges of the screen. CELL_MARGIN = 0 # Do the math to figure out our screen dimensions SCREEN_WIDTH = (CELL_WIDTH + CELL_MARGIN) * COLUMN_COUNT + CELL_MARGIN SCREEN_HEIGHT = (CELL_HEIGHT + CELL_MARGIN) * ROW_COUNT + CELL_MARGIN SCREEN_TITLE = "Conway's Game of Life" # Colors and alpha values ALIVE_COLOR = arcade.color.BISTRE BACKGROUND_COLOR = arcade.color.ANTIQUE_WHITE ALPHA_ON = 255 ALPHA_OFF = 0 def create_grids(): """ Create a 2D and 1D grid of sprites. We use the 1D SpriteList for drawing, and the 2D list for accessing via grid. Both lists point to the same set of sprites. """ # One dimensional list of all sprites in the two-dimensional sprite list grid_sprites_one_dim = arcade.SpriteList() # This will be a two-dimensional grid of sprites to mirror the two # dimensional grid of numbers. This points to the SAME sprites that are # in grid_sprite_list, just in a 2d manner. grid_sprites_two_dim = [] # Create a list of sprites to represent each grid location for row in range(ROW_COUNT): grid_sprites_two_dim.append([]) for column in range(COLUMN_COUNT): # Make the sprite as a soft circle sprite = arcade.SpriteCircle(CELL_WIDTH // 2, ALIVE_COLOR, soft=True) # Position the sprite x = column * (CELL_WIDTH + CELL_MARGIN) + (CELL_WIDTH / 2 + CELL_MARGIN) y = row * (CELL_HEIGHT + CELL_MARGIN) + (CELL_HEIGHT / 2 + CELL_MARGIN) sprite.center_x = x sprite.center_y = y # Add the sprite to both lists grid_sprites_one_dim.append(sprite) grid_sprites_two_dim[row].append(sprite) return grid_sprites_one_dim, grid_sprites_two_dim def randomize_grid(grid: arcade.SpriteList): """ Randomize the grid to alive/dead """ for cell in grid: pick = random.randrange(2) if pick: cell.alpha = ALPHA_ON else: cell.alpha = ALPHA_OFF class MyGame(arcade.Window): """ Main application class. """ def __init__(self, width: int, height: int, title: str): """ Set up the application. """ super().__init__(width, height, title) self.background_color = BACKGROUND_COLOR # We need two layers. One holds the current state of our grid, the other # holds the next frame's state. We flip back and forth between the two. grid_sprites_one_dim1, grid_sprites_two_dim1 = create_grids() grid_sprites_one_dim2, grid_sprites_two_dim2 = create_grids() self.layers_grid_sprites_one_dim = [grid_sprites_one_dim1, grid_sprites_one_dim2] self.layers_grid_sprites_two_dim = [grid_sprites_two_dim1, grid_sprites_two_dim2] self.cur_layer = 0 randomize_grid(self.layers_grid_sprites_one_dim[0]) def on_draw(self): """ Render the screen. """ # Clear all pixels in the window self.clear() self.layers_grid_sprites_one_dim[0].draw() def on_update(self, delta_time: float): """ Update the grid """ # Flip layers if self.cur_layer == 0: layer1 = self.layers_grid_sprites_two_dim[0] layer2 = self.layers_grid_sprites_two_dim[1] self.cur_layer = 1 else: layer1 = self.layers_grid_sprites_two_dim[1] layer2 = self.layers_grid_sprites_two_dim[0] self.cur_layer = 0 # Count the neighbors that are alive for row in range(ROW_COUNT): for column in range(COLUMN_COUNT): live_neighbors = 0 # -1 -1 if row > 0 and column > 0 \ and layer1[row - 1][column - 1].alpha == ALPHA_ON: live_neighbors += 1 # -1 0 if row > 0 and layer1[row - 1][column].alpha == ALPHA_ON: live_neighbors += 1 # -1 +1 if row > 0 and column < COLUMN_COUNT - 1\ and layer1[row - 1][column + 1].alpha == ALPHA_ON: live_neighbors += 1 # 0 +1 if column < COLUMN_COUNT - 1 \ and layer1[row][column + 1].alpha == ALPHA_ON: live_neighbors += 1 # +1 +1 if row < ROW_COUNT - 1 \ and column < COLUMN_COUNT - 1 \ and layer1[row + 1][column + 1].alpha == ALPHA_ON: live_neighbors += 1 # +1 0 if row < ROW_COUNT - 1 and layer1[row + 1][column].alpha == ALPHA_ON: live_neighbors += 1 # +1 -1 if row < ROW_COUNT - 1 and column > 0 \ and layer1[row + 1][column - 1].alpha == ALPHA_ON: live_neighbors += 1 # 0 -1 if column > 0 and layer1[row][column - 1].alpha == ALPHA_ON: live_neighbors += 1 """ Implement Conway's game of life rules Any live cell with two or three live neighbours survives. Any dead cell with three live neighbours becomes a live cell. All other live cells die in the next generation. Similarly, all other dead cells stay dead. """ if layer1[row][column].alpha == ALPHA_ON and (live_neighbors == 2 or live_neighbors == 3): if layer2[row][column].alpha == ALPHA_OFF: layer2[row][column].alpha = ALPHA_ON elif layer1[row][column].alpha == ALPHA_OFF and live_neighbors == 3: if layer2[row][column].alpha == ALPHA_OFF: layer2[row][column].alpha = ALPHA_ON else: if layer2[row][column].alpha == ALPHA_ON: layer2[row][column].alpha = ALPHA_OFF def main(): """ Main function - starting point to the program """ window = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE) window.center_window() arcade.run() if __name__ == "__main__": main() |