Animated Bubbles
Quite a while ago, I played around with the game of Oligarchy in Processing and had the animation working to a certain extent. At the time I was a bit rushed and didn't have the bandwidth to properly look at animating the bubbles in the visualization so that they would cluster together and move apart as they grew or shrank in size or disappeared altogether.
This piece of code does that animation and will be shoe-horned into the original at some point.
Code
Bubble
A simple bubble class with a position, a radius and a velocity where the position and velocity are PVector types to make calculations a little neater
class Bubble:
def __init__(self, position, radius):
self.position = position
self.radius = radius
self.velocity = PVector(0, 0)
def update(self):
self.position.add(self.velocity)
self.velocity *= 0.95 # Damping to slow down the movement
pass
def display(self):
fill(100, 150, 200) # random colour
ellipse(self.position.x, self.position.y, self.radius * 2, self.radius * 2)
Animation
The movement of bubbles is handled in the code that tries to keep each bubble from overlapping it's neighbours but also tries to pull them together into a smaller huddle.
def check_collisions():
global bubbles
for i in range(len(bubbles)):
for j in range(i + 1, len(bubbles)):
b1 = bubbles[i]
b2 = bubbles[j]
direction = b2.position - b1.position
distance = direction.mag()
minimum_distance = b1.radius + b2.radius
if distance < minimum_distance:
overlap = minimum_distance - distance
direction.normalize()
move = direction * (overlap / 2)
b1.velocity -= move * 0.1
b2.velocity += move * 0.1
def pull_towards_center():
global bubbles
center = PVector(width / 2, height / 2)
for b in bubbles:
direction = center - b.position
direction.normalize()
force = (
direction * 0.05
) # Adjust this value to control the strength of the pull
b.velocity += force
Main
The main loop and event handlers for processing including a mechanism to add and remove bubbles for testing purposes.
bubbles = []
# Add some initial content
def setup():
global bubbles
size(800, 800)
bubbles.append(Bubble(PVector(100, 100), 50))
bubbles.append(Bubble(PVector(200, 200), 75))
bubbles.append(Bubble(PVector(300, 300), 60))
def draw():
background(255, 255, 255)
for b in bubbles:
b.update()
b.display()
check_collisions()
pull_towards_center()
# Add a new bubble at the mouse position with random size
def mousePressed():
global bubbles
bubbles.append(Bubble(PVector(mouseX, mouseY), random(30, 60)))
# Remove the last bubble when a key is pressed
def keyPressed():
global bubbles
if bubbles:
bubbles.pop()