### # not_a_swarm_yet.py # # author: Kristina Striegnitz # # version: 2/3/2010 # # On the way to a swarm. This program creates a whole bunch of # creatures that move around and bounce off the edges. ### import random, math from boids_display import run_display # These are global constants. That is global variables, with a value # that never changes while the program runs. WIDTH = 1200 HEIGHT = 800 def run_swarm(n): boids = [] for count in range(0,n): b_x_pos = random.randint(0,WIDTH) b_y_pos = random.randint(0,HEIGHT) b_x_vel = random.randint(-400,400) b_y_vel = random.randint(-400,400) boid = [b_x_pos, b_y_pos, b_x_vel, b_y_vel, random_color()] boids = boids + [boid] # Call the function run_display which we imported from the # file/module boids_display.py. run_display takes a list of boids, # the name of a function which describes how each boids position # and speed should be updated as time passes, and the width and # the height of the display window. run_display(boids, update_boids, WIDTH, HEIGHT) # This function takes two parameters: a list of boids and a time in # miliseconds. The time parameter indicates how much time has passed # since the last time update was called. The function specifies how # each boid from the list of boids given as a parameter gets updated, # that is how each boid's position and velocity changes given the time # that has passed since the last update. # The function update_boids gets called every few milliseconds by # run_display. def update_boids(boids, time): for index in range(len(boids)): b = boids[index] v1 = cohesion(index, boids) b[2] = b[2] + v1[0] b[3] = b[3] + v1[1] # Limit velocity to 500 pixels per second horizontally and vertically b[2] = speed_limit(b[2], 500) b[3] = speed_limit(b[3], 500) # Update the boid's position based on its velocity and the # time that has passed since the last update. b[0] += float(b[2])/1000 * time b[1] += float(b[3])/1000 * time # Make the boid bounce off the walls. if b[0] < 0: b[0] = 0 b[2] = -b[2] elif b[0] > WIDTH: b[0] = WIDTH b[2] = -b[2] if b[1] < 0: b[1] = 0 b[3] = -b[3] elif b[1] > HEIGHT: b[1] = HEIGHT b[3] = -b[3] # This function picks a random color from a given list of colors. def random_color(): colors = [(255,140,0), (139,0,0), (139,0,139), (0,100,0), (255,69,0)] return random.choice(colors) def speed_limit(vel, limit): if vel > 500: return 500 elif vel < -500: return -500 else: return vel # The function takes two parameters: a list of boids (the group) and a # number (the index of the boid that we are currently dealing # with). The function returns a list of two numbers. The first number # in that list is the amount that should be added to the horizontal # velocity of the boid and the second number is the amount that should # be added to the vertical velocity of the boid. def cohesion(index, boids): b = boids[index] # Find the perceived center, i.e. the center of all *other* boids. perceived_center = [0, 0] for other_index in range(len(boids)): if other_index != index: other_b = boids[other_index] perceived_center[0] += other_b[0] perceived_center[1] += other_b[1] perceived_center[0] = float(perceived_center[0]) / (len(boids) - 1) perceived_center[1] = float(perceived_center[1]) / (len(boids) - 1) # Calculate the amounts that should be added to the boid's # horizontal and vertical velocity for the boid to slowly move # toward the perceived center. v_change_x = (perceived_center[0] - b[0]) / 100 v_change_y = (perceived_center[1] - b[1]) / 100 return [v_change_x, v_change_y] ### START EVERYTHING ### run_swarm(30)