| 115 | ################################################################################ |
| 116 | |
| 117 | class BoidGUI(Canvas): |
| 118 | |
| 119 | # Drawing Options |
| 120 | BAL_NOT_VEC = True # Draw balls (True) or vectors (False). |
| 121 | RANDOM_BACK = False # Replace background with flashing colors? |
| 122 | RANDOM_BALL = False # Replace balls with flashing colors? |
| 123 | DRAW_TARGET = True # Show line from groups to their targets? |
| 124 | # Wall Settings |
| 125 | WALL_BOUNCE = False # Bouncy wall if true; force wall if false. |
| 126 | WALL_MARGIN = 50 # Pixels from edge of screen for boundary. |
| 127 | WALL_FORCE = 100 # Force applied to balls outside boundary. |
| 128 | # Random Parameters |
| 129 | MAX_FPS = 100 # Maximum frame per second for display. |
| 130 | GROUPS = 2 # Number of groups to have displayed on the GUI. |
| 131 | # Target Settings |
| 132 | TARGET_FORCE = 500 # Force exerted by the targets on the boid groups. |
| 133 | TRIG_DIST = 100 # Distance to target where target gets changed. |
| 134 | MINI_DIST = 200 # Target must be this far away when recreated. |
| 135 | # Boid Settings |
| 136 | MAX_SPEED = 400 # Maximum speed for boids (pixels per second). |
| 137 | MAX_SIZE = 15 # Largest radius a boid is allowed to have. |
| 138 | MIN_SIZE = 10 # Smallest radius a boid may be built with. |
| 139 | # Color Variables |
| 140 | PALETTE_MODE = True # Palette mode if true; random mode if false. |
| 141 | COLORS = '#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#FF00FF' |
| 142 | PALETTE = [] |
| 143 | for x in range(16): |
| 144 | for y in range(16): |
| 145 | for z in range(16): |
| 146 | color = '#{:X}{:X}{:X}'.format(x, y, z) |
| 147 | PALETTE.append(color) |
| 148 | # Check the settings up above for errors. |
| 149 | assert MINI_DIST > TRIG_DIST, 'Targets must be set beyond trigger point.' |
| 150 | assert MAX_SIZE > MIN_SIZE, 'A minimum may not be larger than maximum.' |
| 151 | assert len(COLORS) > GROUPS, 'There must be more colors than groups.' |
| 152 | |
| 153 | def __init__(self, master, width, height, background, boids): |
| 154 | # Initialize the Canvas object. |
| 155 | cursor = 'none' if SCR_SAVER else '' |
| 156 | super().__init__(master, width=width, height=height, cursor=cursor, |
| 157 | background=background, highlightthickness=0) |
| 158 | self.width = width |
| 159 | self.height = height |
| 160 | self.background = background |
| 161 | # Create colors for the balls. |
| 162 | self.create_ball_palette(boids) |
| 163 | # Build the boid control system. |
| 164 | self.build_boids(boids) |
| 165 | # Build loop for frame updating. |
| 166 | self.last_time = clock() |
| 167 | self.time_diff = 1 / self.MAX_FPS |
| 168 | self.after(1000 // self.MAX_FPS, self.update_screen) |
| 169 | |
| 170 | def create_ball_palette(self, size): |
| 171 | # The last color is not used. |
| 172 | size += 1 |
| 173 | # Turn the colors into (R, G, B) tuples. |
| 174 | colors = list(map(parse_color, self.COLORS)) |