├── FUNDING.yml ├── README.md ├── __pycache__ ├── boid.cpython-39.pyc ├── constants.cpython-39.pyc ├── matrix.cpython-39.pyc ├── tools.cpython-39.pyc ├── ui.cpython-39.pyc └── uiParameters.cpython-39.pyc ├── boid.py ├── constants.py ├── main.py ├── matrix.py ├── tools.py ├── ui.py └── uiParameters.py /FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: auctux 2 | ko_fi: auctux 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # simple-Flocking-simulation-python-pygame 2 | #### youtube channel: [Auctux](https://www.youtube.com/channel/UCjPk9YDheKst1FlAf_KSpyA) 3 | --- 4 | #### Libraries 5 | > pygame : pip install pygame 6 | 7 | > colorsys : pip install colorsys 8 | 9 | --- 10 | #### Controls 11 | - `U` to toggle the UI panel 12 | - `R` to reset 13 | - `Esc` to exit 14 | --- 15 | ![Screenshot (101)](https://user-images.githubusercontent.com/48150537/118202015-8aa2d580-b476-11eb-992d-9a67b72de395.png) 16 | ![Screenshot (85)](https://user-images.githubusercontent.com/48150537/118163915-26fdb580-b440-11eb-8ef8-a4e292eb32e8.png) 17 | ![Screenshot (84)](https://user-images.githubusercontent.com/48150537/118154985-58bd4f00-b435-11eb-897c-0e0e58466291.png) 18 | Enjoy the 🍝 code 19 | -------------------------------------------------------------------------------- /__pycache__/boid.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/simple-Flocking-simulation-python-pygame/b7e3c64f4badcb7a54840d7141238ce8525f836e/__pycache__/boid.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/constants.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/simple-Flocking-simulation-python-pygame/b7e3c64f4badcb7a54840d7141238ce8525f836e/__pycache__/constants.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/matrix.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/simple-Flocking-simulation-python-pygame/b7e3c64f4badcb7a54840d7141238ce8525f836e/__pycache__/matrix.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/tools.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/simple-Flocking-simulation-python-pygame/b7e3c64f4badcb7a54840d7141238ce8525f836e/__pycache__/tools.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/ui.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/simple-Flocking-simulation-python-pygame/b7e3c64f4badcb7a54840d7141238ce8525f836e/__pycache__/ui.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/uiParameters.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/simple-Flocking-simulation-python-pygame/b7e3c64f4badcb7a54840d7141238ce8525f836e/__pycache__/uiParameters.cpython-39.pyc -------------------------------------------------------------------------------- /boid.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from tools import * 3 | from random import uniform 4 | import colorsys 5 | from matrix import * 6 | from math import pi,sin,cos 7 | # def hsvToRGB(h, s, v): 8 | # return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h,s,v)) 9 | 10 | 11 | class Boid: 12 | def __init__(self, x, y): 13 | self.position = Vector(x, y) 14 | vec_x = uniform(-1, 1) 15 | vec_y = uniform(-1, 1) 16 | self.velocity = Vector(vec_x, vec_y) 17 | self.velocity.normalize() 18 | #set a random magnitude 19 | self.velocity = self.velocity * uniform(1.5, 4) 20 | self.acceleration = Vector() 21 | self.color = (255, 255,255) 22 | self.temp = self.color 23 | self.secondaryColor = (70, 70, 70) 24 | self.max_speed = 5 25 | self.max_length = 1 26 | self.size = 2 27 | self.stroke = 5 28 | self.angle = 0 29 | self.hue = 0 30 | self.toggles = {"separation":True, "alignment":True, "cohesion":True} 31 | self.values = {"separation":0.1, "alignment":0.1, "cohesion":0.1} 32 | self.radius = 40 33 | def limits(self, width , height): 34 | if self.position.x > width: 35 | self.position.x = 0 36 | elif self.position.x < 0: 37 | self.position.x = width 38 | 39 | if self.position.y > height: 40 | self.position.y = 0 41 | elif self.position.y < 0: 42 | self.position.y = height 43 | 44 | def behaviour(self, flock): 45 | self.acceleration.reset() 46 | 47 | if self.toggles["separation"] == True: 48 | avoid = self.separation(flock) 49 | avoid = avoid * self.values["separation"] 50 | self.acceleration.add(avoid) 51 | 52 | if self.toggles["cohesion"]== True: 53 | coh = self.cohesion(flock) 54 | coh = coh * self.values["cohesion"] 55 | self.acceleration.add(coh) 56 | 57 | if self.toggles["alignment"] == True: 58 | align = self.alignment(flock) 59 | align = align * self.values["alignment"] 60 | self.acceleration.add(align) 61 | 62 | 63 | def separation(self, flockMates): 64 | total = 0 65 | steering = Vector() 66 | 67 | for mate in flockMates: 68 | dist = getDistance(self.position, mate.position) 69 | if mate is not self and dist < self.radius: 70 | temp = SubVectors(self.position,mate.position) 71 | temp = temp/(dist ** 2) 72 | steering.add(temp) 73 | total += 1 74 | 75 | if total > 0: 76 | steering = steering / total 77 | # steering = steering - self.position 78 | steering.normalize() 79 | steering = steering * self.max_speed 80 | steering = steering - self.velocity 81 | steering.limit(self.max_length) 82 | 83 | return steering 84 | def alignment(self, flockMates): 85 | total = 0 86 | steering = Vector() 87 | # hue = uniform(0, 0.5) 88 | for mate in flockMates: 89 | dist = getDistance(self.position, mate.position) 90 | if mate is not self and dist < self.radius: 91 | vel = mate.velocity.Normalize() 92 | steering.add(vel) 93 | mate.color = hsv_to_rgb( self.hue ,1, 1) 94 | 95 | total += 1 96 | 97 | 98 | if total > 0: 99 | steering = steering / total 100 | steering.normalize() 101 | steering = steering * self.max_speed 102 | steering = steering - self.velocity.Normalize() 103 | steering.limit(self.max_length) 104 | return steering 105 | 106 | def cohesion(self, flockMates): 107 | total = 0 108 | steering = Vector() 109 | 110 | for mate in flockMates: 111 | dist = getDistance(self.position, mate.position) 112 | if mate is not self and dist < self.radius: 113 | steering.add(mate.position) 114 | total += 1 115 | 116 | if total > 0: 117 | steering = steering / total 118 | steering = steering - self.position 119 | steering.normalize() 120 | steering = steering * self.max_speed 121 | steering = steering - self.velocity 122 | steering.limit(self.max_length) 123 | 124 | return steering 125 | 126 | def update(self): 127 | 128 | self.position = self.position + self.velocity 129 | self.velocity = self.velocity + self.acceleration 130 | self.velocity.limit(self.max_speed) 131 | self.angle = self.velocity.heading() + pi/2 132 | 133 | def Draw(self, screen, distance, scale): 134 | ps = [] 135 | points = [None for _ in range(3)] 136 | 137 | points[0] = [[0],[-self.size],[0]] 138 | points[1] = [[self.size//2],[self.size//2],[0]] 139 | points[2] = [[-self.size//2],[self.size//2],[0]] 140 | 141 | for point in points: 142 | rotated = matrix_multiplication(rotationZ(self.angle) , point) 143 | z = 1/(distance - rotated[2][0]) 144 | 145 | projection_matrix = [[z, 0, 0], [0, z, 0]] 146 | projected_2d = matrix_multiplication(projection_matrix, rotated) 147 | 148 | x = int(projected_2d[0][0] * scale) + self.position.x 149 | y = int(projected_2d[1][0] * scale) + self.position.y 150 | ps.append((x, y)) 151 | 152 | pygame.draw.polygon(screen, self.secondaryColor, ps) 153 | pygame.draw.polygon(screen, self.color, ps, self.stroke) 154 | -------------------------------------------------------------------------------- /constants.py: -------------------------------------------------------------------------------- 1 | Width, Height = 1920, 1080 2 | white, black = (217, 217, 217), (12, 12, 12) 3 | size=(Width, Height) 4 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from boid import Boid 3 | from tools import Vector 4 | import math 5 | import random 6 | from matrix import * 7 | from constants import * 8 | from uiParameters import * 9 | 10 | pygame.init() 11 | window = pygame.display.set_mode(size, pygame.FULLSCREEN) 12 | clock = pygame.time.Clock() 13 | fps = 60 14 | 15 | scale = 40 16 | Distance = 5 17 | speed = 0.0005 18 | 19 | flock = [] 20 | #number of boids 21 | n = 50 22 | #radius of perception of each boid 23 | 24 | for i in range(n): 25 | flock.append(Boid(random.randint(20, Width-20), random.randint(20, Height-20))) 26 | 27 | textI = "10" 28 | reset = False 29 | SpaceButtonPressed = False 30 | backSpace = False 31 | keyPressed = False 32 | showUI = False 33 | clicked = False 34 | run = True 35 | while run: 36 | clock.tick(fps) 37 | window.fill((10, 10, 15)) 38 | 39 | n = numberInput.value 40 | scale = sliderScale.value 41 | 42 | for event in pygame.event.get(): 43 | if event.type == pygame.QUIT: 44 | run = False 45 | if event.type == pygame.MOUSEBUTTONUP: 46 | clicked = True 47 | if event.type == pygame.KEYDOWN: 48 | if event.key == pygame.K_ESCAPE: 49 | run = False 50 | if event.key == pygame.K_r: 51 | reset = True 52 | if event.key == pygame.K_SPACE: 53 | SpaceButtonPressed = True 54 | 55 | textI = pygame.key.name(event.key) 56 | keyPressed = True 57 | 58 | if event.type == pygame.KEYUP: 59 | if event.key == pygame.K_BACKSPACE: 60 | backSpace = True 61 | if event.key == pygame.K_u: 62 | showUI = not showUI 63 | 64 | if reset == True or resetButton.state == True: 65 | flock = [] 66 | for i in range(n): 67 | flock.append(Boid(random.randint(20, Width-20), random.randint(20, Height-20))) 68 | reset = False 69 | 70 | 71 | for boid in flock: 72 | boid.toggles = {"separation": toggleSeparation.state, "alignment": toggleAlignment.state,"cohesion": toggleCohesion.state} 73 | boid.values = {"separation": separationInput.value/100, "alignment": alignmentInput.value/100,"cohesion": cohesionInput.value/100} 74 | boid.radius = scale 75 | boid.limits(Width, Height) 76 | boid.behaviour(flock) 77 | boid.update() 78 | boid.hue += speed 79 | boid.Draw(window, Distance, scale) 80 | 81 | 82 | 83 | if showUI == True: 84 | panel.Render(window) 85 | resetButton.Render(window) 86 | Behaviours.Render(window) 87 | Separation.Render(window) 88 | Alignment.Render(window) 89 | Cohesion.Render(window) 90 | SeparationValue.Render(window) 91 | AlignmentValue.Render(window) 92 | CohesionValue.Render(window) 93 | NumberOfBoids.Render(window) 94 | ScaleText.Render(window) 95 | toggleSeparation.Render(window, clicked) 96 | toggleAlignment.Render(window, clicked) 97 | toggleCohesion.Render(window, clicked) 98 | separationInput.Render(window, textI, backSpace, keyPressed) 99 | alignmentInput.Render(window, textI, backSpace, keyPressed) 100 | cohesionInput.Render(window, textI, backSpace, keyPressed) 101 | numberInput.Render(window, textI, backSpace, keyPressed) 102 | 103 | sliderScale.Render(window) 104 | else: 105 | UItoggle.Render(window) 106 | backSpace = False 107 | keyPressed = False 108 | pygame.display.flip() 109 | clicked = False 110 | pygame.quit() 111 | -------------------------------------------------------------------------------- /matrix.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | def matrix_multiplication(a, b): 4 | columns_a = len(a[0]) 5 | rows_a = len(a) 6 | columns_b = len(b[0]) 7 | rows_b = len(b) 8 | 9 | result_matrix = [[j for j in range(columns_b)] for i in range(rows_a)] 10 | if columns_a == rows_b: 11 | for x in range(rows_a): 12 | for y in range(columns_b): 13 | sum = 0 14 | for k in range(columns_a): 15 | sum += a[x][k] * b[k][y] 16 | result_matrix[x][y] = sum 17 | return result_matrix 18 | 19 | else: 20 | print("columns of the first matrix must be equal to the rows of the second matrix") 21 | return None 22 | 23 | 24 | def rotationX(angle): 25 | return [[1, 0, 0], 26 | [0, math.cos(angle), -math.sin(angle)], 27 | [0, math.sin(angle), math.cos(angle)]] 28 | def rotationY(angle): 29 | return [[math.cos(angle), 0, -math.sin(angle)], 30 | [0, 1, 0], 31 | [math.sin(angle), 0, math.cos(angle)]] 32 | 33 | def rotationZ(angle): 34 | return [[math.cos(angle), -math.sin(angle), 0], 35 | [math.sin(angle), math.cos(angle), 0], 36 | [0, 0 ,1]] 37 | -------------------------------------------------------------------------------- /tools.py: -------------------------------------------------------------------------------- 1 | from math import sqrt, atan2 2 | import colorsys 3 | NEIGHBORHOOD_RADIUS = 40 4 | 5 | class Vector: 6 | def __init__(self, x=0, y=0): 7 | self.x = x 8 | self.y = y 9 | 10 | def __mul__(self, a): 11 | self.x = self.x * a 12 | self.y = self.y * a 13 | return self 14 | 15 | def __add__(self, a): 16 | self.x = self.x + a.x 17 | self.y = self.y + a.y 18 | return self 19 | 20 | def __sub__(self, a): 21 | self.x = self.x - a.x 22 | self.y = self.y - a.y 23 | return self 24 | 25 | def __truediv__(self, a): 26 | self.x = self.x / a 27 | self.y = self.y / a 28 | return self 29 | 30 | def add(self, a): 31 | self.x = self.x + a.x 32 | self.y = self.y + a.y 33 | 34 | def parseToInt(self): 35 | return (int(self.x), int(self.y)) 36 | 37 | def magnitude(self): 38 | return sqrt(self.x * self.x + self.y * self.y) 39 | 40 | def normalize(self): 41 | mag = self.magnitude() 42 | if not (mag == 0 ): 43 | self = self/mag 44 | def Normalize(self): 45 | mag = self.magnitude() 46 | if mag != 0: 47 | return Vector(self.x/mag, self.y/mag) 48 | else: 49 | return Vector(1, 1) 50 | 51 | def heading(self): 52 | angle = atan2(self.y, self.x) 53 | # in radians 54 | return angle 55 | 56 | def limit(self, max_length): 57 | squared_mag = self.magnitude() * self.magnitude() 58 | if squared_mag > (max_length * max_length): 59 | self.x = self.x/sqrt(squared_mag) 60 | self.y = self.y/sqrt(squared_mag) 61 | self.x = self.x * max_length 62 | self.y = self.y * max_length 63 | def reset(self, x=0, y=0): 64 | self.x = x 65 | self.y = y 66 | 67 | def __repr__(self): 68 | return f'vector-> x:{self.x}, y:{self.y}' 69 | 70 | 71 | def getDistance(v1, v2): 72 | return sqrt((v2.x - v1.x)*(v2.x - v1.x) + (v2.y -v1.y)*(v2.y - v1.y)) 73 | 74 | def AddVectors(v1, v2): 75 | return Vector(v1.x + v2.x, v1.y + v2.y) 76 | 77 | def translate(value, min1, max1, min2, max2): 78 | return min2 + (max2 - min2)* ((value-min1)/(max1-min1)) 79 | 80 | def hsv_to_rgb(h, s, v): 81 | return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h, s, v)) 82 | 83 | 84 | def SubVectors(v1, v2): 85 | return Vector(v1.x - v2.x, v1.y - v2.y) 86 | -------------------------------------------------------------------------------- /ui.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from constants import * 3 | from tools import * 4 | class Button: 5 | def __init__(self, text, position = (Width-230, 600) , w = 100, h= 50, border=10, color = (0, 0, 0), borderColor = (64, 123, 158)): 6 | self.text = text 7 | self.position = position 8 | self.w = w 9 | self.h = h 10 | self.border = border 11 | self.temp = color 12 | self.color = color 13 | self.borderColor = borderColor 14 | self.font = 'freesansbold.ttf' 15 | self.fontSize = 25 16 | self.textColor = (255, 255, 255) 17 | self.state = False 18 | self.action = None 19 | 20 | def HandleMouse(self, HoverColor = (100, 100, 100)): 21 | m = pygame.mouse.get_pos() 22 | self.state = False 23 | if m[0] >= self.position[0] and m[0] <= self.position[0] + self.w: 24 | if m[1] >= self.position[1] and m[1] <= self.position[1] + self.h: 25 | self.color = HoverColor 26 | if pygame.mouse.get_pressed()[0]: 27 | self.color = (200, 200, 200) 28 | if self.action == None: 29 | self.state = True 30 | else: 31 | self.color = self.temp 32 | else: 33 | self.color = self.temp 34 | 35 | 36 | def Render(self, screen): 37 | self.HandleMouse() 38 | font = pygame.font.Font(self.font, self.fontSize) 39 | text = font.render(self.text, True, self.textColor) 40 | textRect = text.get_rect() 41 | textRect.center = (self.position[0]+self.w//2, self.position[1]+self.h//2) 42 | if self.border > 0: 43 | pygame.draw.rect(screen, self.borderColor, pygame.Rect(self.position[0] - self.border//2, self.position[1] - self.border//2, self.w + self.border, self.h + self.border)) 44 | pygame.draw.rect(screen, self.color, pygame.Rect(self.position[0], self.position[1], self.w, self.h)) 45 | 46 | screen.blit(text, textRect) 47 | 48 | class Panel: 49 | def __init__(self, position = (Width-350, 100), w= 345, h= 500, color=(8, 3, 12), alpha=128): 50 | self.position = position 51 | self.w = w 52 | self.h = h 53 | self.color = color 54 | self.alpha = alpha 55 | 56 | def Render(self, screen): 57 | s = pygame.Surface((self.w, self.h)) 58 | s.set_alpha(self.alpha) 59 | s.fill(self.color) 60 | screen.blit(s, (self.position[0], self.position[1])) 61 | # pygame.draw.rect(screen, self.color, pygame.Rect(self.position[0], self.position[1], self.w, self.h)) 62 | 63 | class ToggleButton: 64 | def __init__(self, position= ((Width-200, 400)), w = 30, h=30, state=False, color=(40, 40, 10), activeColor=(240, 140, 60)): 65 | self.position = position 66 | self.w = w 67 | self.h = h 68 | self.clicked = False 69 | self.state = state 70 | self.temp = (activeColor, color) 71 | self.activeColor = activeColor 72 | self.color = color 73 | 74 | def HandleMouse(self, HoverColor = (150, 120, 40)): 75 | m = pygame.mouse.get_pos() 76 | 77 | if m[0] >= self.position[0] and m[0] <= self.position[0] + self.w: 78 | if m[1] >= self.position[1] and m[1] <= self.position[1] + self.h: 79 | self.color = HoverColor 80 | self.activeColor = HoverColor 81 | if self.clicked: 82 | self.state = not self.state 83 | self.color = (255, 255, 255) 84 | else: 85 | self.color = self.temp[1] 86 | self.activeColor =self.temp[0] 87 | else: 88 | self.color = self.temp[1] 89 | self.activeColor =self.temp[0] 90 | 91 | def Render(self, screen, clicked): 92 | self.HandleMouse() 93 | self.clicked = clicked 94 | if self.state == True: 95 | pygame.draw.rect(screen, self.activeColor, pygame.Rect(self.position[0], self.position[1], self.w, self.h)) 96 | else: 97 | pygame.draw.rect(screen, self.color, pygame.Rect(self.position[0], self.position[1], self.w, self.h)) 98 | return self.state 99 | class TextUI: 100 | def __init__(self,text, position, fontColor): 101 | self.position = position 102 | self.text = text 103 | self.font = 'freesansbold.ttf' 104 | self.fontSize = 18 105 | self.fontColor = fontColor 106 | def Render(self, screen): 107 | font = pygame.font.Font(self.font, self.fontSize) 108 | text = font.render(self.text, True, self.fontColor) 109 | textRect = text.get_rect() 110 | textRect.center = (self.position[0], self.position[1]) 111 | screen.blit(text, textRect) 112 | 113 | class DigitInput: 114 | def __init__(self,startingValue, position = (Width-320, 100), w= 300, h= 600, color=(8, 3, 12)): 115 | self.position = position 116 | self.text = str(startingValue) 117 | self.fontColor = (255, 255, 255) 118 | self.fontSize = 18 119 | self.font = 'freesansbold.ttf' 120 | self.w = w 121 | self.h = h 122 | self.color = color 123 | self.value = int(self.text) 124 | self.hoverEnter = False 125 | 126 | def Check(self, backspace,val): 127 | 128 | if self.hoverEnter == True: 129 | if backspace == True: 130 | 131 | if len(str(self.value)) <= 0 or len(str(self.value))-1 <= 0: 132 | self.value = 0 133 | else: 134 | self.value = int(str(self.value)[:-1]) 135 | 136 | else: 137 | if self.text.isdigit(): 138 | self.value = int(str(self.value) + str(self.text)) 139 | else: 140 | for el in self.text: 141 | if el.isdigit() != True: 142 | self.text = self.text.replace(el, "") 143 | backspace == False 144 | self.text = "" 145 | 146 | 147 | 148 | 149 | def updateText(self, val, pressed): 150 | m = pygame.mouse.get_pos() 151 | if m[0] >= self.position[0] and m[0] <= self.position[0] + self.w: 152 | if m[1] >= self.position[1] and m[1] <= self.position[1] + self.h: 153 | self.hoverEnter = True 154 | if pressed == True: 155 | self.text += val 156 | else: 157 | self.hoverEnter = False 158 | val = "" 159 | else: 160 | self.hoverEnter = False 161 | val = "" 162 | 163 | 164 | def Render(self, screen, val, backspace, pressed): 165 | self.updateText(val, pressed) 166 | self.Check(backspace, val) 167 | font = pygame.font.Font(self.font, self.fontSize) 168 | text = font.render(str(self.value), True, self.fontColor) 169 | textRect = text.get_rect() 170 | textRect.center = (self.position[0]+self.w//2, self.position[1]+self.h//2) 171 | pygame.draw.rect(screen, self.color, pygame.Rect(self.position[0], self.position[1], self.w, self.h)) 172 | screen.blit(text, textRect) 173 | 174 | class Slider: 175 | def __init__(self,x, y, val, min1, max1, length, h, max=500): 176 | self.value = val 177 | self.x = x 178 | self.y = y 179 | self.h = h 180 | self.min1 = min1 181 | self.max1 = max1 182 | self.length = length 183 | self.lineColor = (20, 10, 20) 184 | self.rectradius = 10 185 | self.temp_radius = self.rectradius 186 | self.rectColor = (255, 255, 255) 187 | self.v = 0.4 188 | self.temp = self.lineColor 189 | self.max = max 190 | 191 | def Calculate(self, val): 192 | self.v = translate(val, 0, self.length, 0, 1) 193 | self.value = self.v * self.max 194 | 195 | def HandleMouse(self): 196 | mx, my = pygame.mouse.get_pos() 197 | 198 | if mx >= self.x and mx <= self.x + self.length: 199 | if my >= self.y and my <= self.y + self.h: 200 | self.rectradius = 15 201 | if pygame.mouse.get_pressed()[0]: 202 | self.Calculate(mx - self.x) 203 | else: 204 | self.lineColor = self.temp 205 | self.rectradius = self.temp_radius 206 | else: 207 | self.lineColor = self.temp 208 | self.rectradius = self.temp_radius 209 | 210 | def Render(self,screen): 211 | self.HandleMouse() 212 | pygame.draw.rect(screen, self.lineColor, pygame.Rect(self.x, self.y, self.length, self.h)) 213 | x = int((self.v * self.length) + self.x) 214 | pygame.draw.rect(screen, self.rectColor, pygame.Rect(self.x, self.y, int( self.v * self.length), self.h)) 215 | pygame.draw.circle(screen, (130, 213, 151), (x, self.y + (self.rectradius/2)), self.rectradius) 216 | return self.value 217 | -------------------------------------------------------------------------------- /uiParameters.py: -------------------------------------------------------------------------------- 1 | from ui import * 2 | 3 | panel = Panel() 4 | panel.color = (0, 0, 0) 5 | resetButton = Button("Reset") 6 | 7 | Behaviours = TextUI("BEHAVIOURS", (Width-180, 120), (255, 255, 255)) 8 | UItoggle = TextUI("Press 'U' to show parameter panel", (Width-180, 120), (55, 120, 255)) 9 | 10 | 11 | Separation = TextUI("Separation: ", (Width-245, 180), (255, 255, 255)) 12 | Alignment = TextUI("Alignment: ", (Width-245, 220), (255, 255, 255)) 13 | Cohesion = TextUI("Cohesion: ", (Width-245, 260), (255, 255, 255)) 14 | 15 | SeparationValue = TextUI("separationValue: ", (Width-245, 315), (255, 255, 255)) 16 | AlignmentValue = TextUI("alignmentValue: ", (Width-245, 365), (255, 255, 255)) 17 | CohesionValue = TextUI("cohesionValue: ", (Width-245, 415), (255, 255, 255)) 18 | NumberOfBoids = TextUI("Number of Boids: ", (Width-245, 465), (255, 255, 255)) 19 | ScaleText = TextUI("Boid-Scale (radius): ", (Width-200, 520), (255, 255, 255)) 20 | 21 | toggleSeparation = ToggleButton((Width-160, 170), 20, 20, True) 22 | toggleAlignment = ToggleButton((Width-160, 210), 20, 20, True) 23 | toggleCohesion= ToggleButton((Width-160, 250), 20, 20, True) 24 | 25 | separationInput = DigitInput(10, (Width-160, 300), 80, 30) 26 | alignmentInput = DigitInput(10, (Width-160, 350), 80, 30) 27 | cohesionInput = DigitInput(10, (Width-160, 400), 80, 30) 28 | numberInput = DigitInput(100, (Width-160, 450), 80, 30) 29 | 30 | sliderScale = Slider(Width-280, 550, 40, 0, 100, 180, 10, 80) 31 | 32 | #toggleDiagonal2 = ToggleButton((Width-160, 290), 20, 20, False) 33 | #showPoint = ToggleButton((Width-160, 340), 20, 20, True) 34 | --------------------------------------------------------------------------------