From dab3bff2e6996b980212e76798775b8d37c2c0b3 Mon Sep 17 00:00:00 2001 From: s481879 Date: Mon, 9 Dec 2024 16:50:38 +0100 Subject: [PATCH] Add main.py --- main.py | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 main.py diff --git a/main.py b/main.py new file mode 100644 index 0000000..4d6de42 --- /dev/null +++ b/main.py @@ -0,0 +1,123 @@ +import pygame +import random +import math + +WIDTH, HEIGHT = 800, 600 + +NUM_GROUPS = 3 +BOIDS_PER_GROUP = 20 +MAX_SPEED = 4 +NEIGHBOR_RADIUS = 60 +AVOID_RADIUS = 100 + +ALIGNMENT_WEIGHT = 1.0 +COHESION_WEIGHT = 1.0 +SEPARATION_WEIGHT = 3.0 + +GROUP_COLOR = [(200, 50, 50), (50, 200, 50), (50, 50, 200)] + +class Boid: + def __init__(self, x, y, group_id): + self.position = pygame.Vector2(x, y) + self.boid_vector = pygame.Vector2(0.5, 0.5).normalize() + self.group_id = group_id + + def update(self, boids): + alignment = self.align(boids) * ALIGNMENT_WEIGHT # dopasowanie + cohesion = self.cohesion(boids) * COHESION_WEIGHT # kohesja + separation = self.separation(boids) * SEPARATION_WEIGHT # separacja + + steering = alignment + cohesion + separation + + self.boid_vector += steering + if self.boid_vector.length() > MAX_SPEED: + self.boid_vector.scale_to_length(MAX_SPEED) + + self.position += self.boid_vector + + if self.position.x > WIDTH: + self.position.x = WIDTH + self.boid_vector.x *= -1 + if self.position.x < 0: + self.position.x = 0 + self.boid_vector.x *= -1 + if self.position.y > HEIGHT: + self.position.y = HEIGHT + self.boid_vector.y *= -1 + if self.position.y < 0: + self.position.y = 0 + self.boid_vector.y *= -1 + + def align(self, boids): + avg_boid_vector = pygame.Vector2(0, 0) + count = 0 + for boid in boids: + if boid == self or boid.group_id != self.group_id: + continue + if self.position.distance_to(boid.position) < NEIGHBOR_RADIUS: + avg_boid_vector += boid.boid_vector + count += 1 + if count > 0: + avg_boid_vector = avg_boid_vector/count + avg_boid_vector = avg_boid_vector.normalize() * MAX_SPEED + return avg_boid_vector - self.boid_vector + + def cohesion(self, boids): + center_of_group = pygame.Vector2(0, 0) + count = 0 + for boid in boids: + if boid == self or boid.group_id != self.group_id: + continue + if self.position.distance_to(boid.position) < NEIGHBOR_RADIUS: + center_of_group += boid.position + count += 1 + if count > 0: + center_of_group = center_of_group/count + return (center_of_group - self.position).normalize() + return pygame.Vector2(0, 0) + + def separation(self, boids): + avoid_vector = pygame.Vector2(0, 0) + for boid in boids: + if boid == self or boid.group_id != self.group_id: + continue + distance = self.position.distance_to(boid.position) + if distance < AVOID_RADIUS: + avoid_vector += (self.position - boid.position).normalize() / distance + return avoid_vector + def draw(self, screen): + angle = math.atan2(self.boid_vector.y, self.boid_vector.x) + points = [ + (self.position.x + math.cos(angle) * 10, self.position.y + math.sin(angle) * 10), + (self.position.x + math.cos(angle + 2.5) * 5, self.position.y + math.sin(angle + 2.5) * 5), + (self.position.x + math.cos(angle - 2.5) * 5, self.position.y + math.sin(angle - 2.5) * 5), + ] + pygame.draw.polygon(screen, GROUP_COLOR[self.group_id], points) + +pygame.init() +screen = pygame.display.set_mode((WIDTH, HEIGHT)) +clock = pygame.time.Clock() + +boids = [] +for group_id in range(NUM_GROUPS): + for _ in range(BOIDS_PER_GROUP): + x = random.randint(0, WIDTH) + y = random.randint(0, HEIGHT) + boids.append(Boid(x, y, group_id)) + +running = True +while running: + screen.fill((30, 30, 30)) + + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + for boid in boids: + boid.update(boids) + boid.draw(screen) + + pygame.display.flip() + clock.tick(60) + +pygame.quit()