Advertisement
cookertron

Boids - Separation

Sep 10th, 2019
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.90 KB | None | 0 0
  1. import math, random, sys, time
  2. import pygame
  3. from pygame.locals import *
  4. from pygame import gfxdraw
  5.  
  6. # exit the program
  7. def quit():
  8.     for event in pygame.event.get():
  9.         if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
  10.             return True
  11.     return False
  12.  
  13. # define display surface           
  14. W, H = 1280, 720
  15. HW, HH = W / 2, H / 2
  16.  
  17. # initialise display
  18. pygame.init()
  19. FONT = pygame.font.SysFont(None, 72)
  20. DS = pygame.display.set_mode((W, H))
  21. pygame.display.set_caption("Tetris Clone")
  22. FPS = 120
  23. SPF = 1.00 / FPS
  24.  
  25. # define some colors
  26. FUCHSIA = (255,   0, 255)
  27. PURPLE  = (128,   0, 128)
  28. TEAL    = (  0, 128, 128)
  29. LIME    = (  0, 255,   0)
  30. GREEN   = (  0, 128,   0)
  31. OLIVE   = (128, 128,   0)
  32. YELLOW  = (255, 255,   0)
  33. ORANGE  = (255, 165,   0)
  34. RED     = (255,   0,   0)
  35. MAROON  = (128,   0,   0)
  36. SILVER  = (192, 192, 192)
  37. GRAY    = (128, 128, 128)
  38. BLUE    = (  0,   0, 255)
  39. NAVY    = (  0,   0, 128)
  40. AQUA    = (  0, 255, 255)
  41. WHITE   = (255, 255, 255)
  42. BLACK   = (  0,   0,   0)
  43.  
  44. COLORS = [BLACK, WHITE, RED, GREEN, BLUE, PURPLE, YELLOW, ORANGE, GRAY, SILVER, AQUA, FUCHSIA, LIME, MAROON, NAVY, OLIVE, TEAL]
  45.  
  46. # the areas of the display that need updating
  47. AREAS = [(0, 0, W, H)]
  48.  
  49. # start FPS monitoring
  50. FPSTime = time.time()
  51.  
  52.  
  53. # PI = 3.1415926
  54. # PI * 2 = 6.2831852
  55. BIRD_SHAPE = [0, 150, 210]
  56. BIRD_SIZE = 10
  57. BIRD_SIGHT_RADIUS = 100
  58. BIRD_BLIND_SPOT_SIZE = 50 # is actually double
  59.  
  60. VECTOR_TABLE = [[math.cos(math.radians(degrees)), math.sin(math.radians(degrees))] for degrees in range(360)]
  61.  
  62. MAX_AVOIDANCE_SPEED = 3
  63. AVOIDANCE_THRESHOLD = 2.0 * MAX_AVOIDANCE_SPEED / (BIRD_SIGHT_RADIUS * (BIRD_SIGHT_RADIUS - 1))
  64. AVOIDANCE_SPEED_TABLE = []
  65. a = 0
  66. for index in range(BIRD_SIGHT_RADIUS):
  67.     AVOIDANCE_SPEED_TABLE.append(a)
  68.     a += AVOIDANCE_THRESHOLD * index
  69. AVOIDANCE_SPEED_TABLE.reverse()
  70.  
  71. class bird:
  72.     def __init__(s):
  73.         global W, H
  74.         s.x, s.y = random.randint(20, W - 40), random.randint(20, H - 40)
  75.         s.angle = float(random.randint(0, 360))
  76.         s.seen = False
  77.         s.focus = False
  78.        
  79.     def draw(s):
  80.         global DS
  81.         global WHITE, RED
  82.         global BIRD_SHAPE, BIRD_SIZE
  83.        
  84.         polygon = []
  85.         for point_degrees in BIRD_SHAPE:
  86.             angle = math.radians(s.angle + point_degrees)
  87.             px = int(s.x + math.cos(angle) * BIRD_SIZE)
  88.             py = int(s.y + math.sin(angle) * BIRD_SIZE)
  89.             polygon.append([px, py])
  90.         if s.focus:
  91.             pygame.gfxdraw.filled_polygon(DS, polygon, RED)
  92.         else:
  93.             pygame.gfxdraw.filled_polygon(DS, polygon, WHITE)
  94.            
  95.     def move(s):
  96.         global W, H
  97.         global VECTOR_TABLE
  98.        
  99.         angle = int(s.angle)
  100.         s.x += VECTOR_TABLE[angle][0]
  101.         if s.x > W: s.x = 0
  102.         if s.x < 0: s.x = W
  103.         s.y += VECTOR_TABLE[angle][1]
  104.         if s.y > H: s.y = 0
  105.         if s.y < 0: s.y = H
  106.        
  107. class birds:
  108.     def __init__(s):
  109.         s.aviary = list()
  110.    
  111.     def add(s, n):
  112.         global bird
  113.        
  114.         for i in range(n):
  115.             s.aviary.append(bird())
  116.  
  117.     def avoid(s):
  118.         global BIRD_SIGHT_RADIUS, BIRD_BLIND_SPOT_SIZE
  119.        
  120.         for b in s.aviary:
  121.             bbsal = (b.angle + 180 - BIRD_BLIND_SPOT_SIZE) % 360
  122.             bbsah = (b.angle + 180 + BIRD_BLIND_SPOT_SIZE) % 360
  123.             for tb in s.aviary:
  124.                 dist = math.hypot(b.x - tb.x, b.y - tb.y)
  125.                 if dist > BIRD_SIGHT_RADIUS: continue
  126.                
  127.                 if b == tb: continue
  128.                
  129.                 angle = math.degrees(math.atan2(b.y - tb.y, b.x - tb.x)) % 360
  130.                
  131.                 if bbsal > bbsah:
  132.                     if angle > bbsal or angle < bbsah:
  133.                         continue
  134.                 elif angle < bbsah and angle > bbsal:
  135.                     continue
  136.                
  137.                
  138.                 if b.angle > angle:
  139.                     b.angle -= AVOIDANCE_SPEED_TABLE[int(dist)]
  140.                 else:
  141.                     b.angle += AVOIDANCE_SPEED_TABLE[int(dist)]
  142.                 b.angle %= 360 
  143.                 #print polarity
  144.                
  145.                
  146.                
  147.     def do(s):
  148.         for b in s.aviary:
  149.             b.draw()
  150.             b.move()
  151.         s.avoid()
  152.            
  153. b = birds()
  154. b.add(40)
  155. b.aviary[20].focus = True
  156.  
  157. # main loop
  158. while not quit():
  159.     frameTime = time.time() - FPSTime
  160.     if frameTime < SPF: continue
  161.     FPSTime += frameTime
  162.    
  163.     b.do()
  164.    
  165.     pygame.display.update(AREAS)
  166.     DS.fill(BLACK)
  167. pygame.quit()
  168. sys.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement