#!/usr/bin/env python """ particles "bubbles" screen saver written by Felix "Albert" Liard """ from graphics import * from random import * from time import * class Particle: def __init__(self, window, maxX): self.px = int(randint(0,maxX)) # random position on X axis self.py = 0 # always start at Y = 0 (bottom) # if near side edges, sometimes move a little laterally.. if randint(0,2) == 0 and (maxX*.90 < self.px or self.px < maxX*.10): self.dx = randint(-1,1) else: self.dx = 0 # special animation effect: # sometimes, leave some "stuck" to the bottom of screen or rise slow if randint(0,1) == 0: self.dy = randint(0,3) if self.dy == 0: self.born = time() # but don't leave stuck forever... # note time of creation to speed up later else: self.dy = randint(2,4) # pick rise speed at random self.size = randint(10,30) if randint(0,20) == 0: # sometimes, create a LARGE and FAST bubble self.size = 40 self.dy = randint(5,6) circle = Circle(Point(self.px,self.py),self.size) circle.setOutline('blue') circle.setFill('black') circle.draw(window) self.circle = circle # correlate physical object to logical object def destroy(self,particles_list): del particles_list[self.circle] # remove from dictionary self.circle.undraw() # remove from screen del self.circle # don't forget to remove physical objects del self def initialize_window(sizex,sizey): w = GraphWin('Bubbles! Bubbles! Bubbles!',sizex,sizey) w.setCoords(0,0,sizex,sizey) w.setBackground('black') seed() # random numbers return w def main(): particles_list = {} total_particles = 150 maxX = 1024 maxY = 575 #maxX = 1920 #maxY = 1020 window = initialize_window(maxX,maxY) sleep(1.5) # start with 1 bubble... main loop keeps generating new bubbles... particle = Particle(window,maxX) particles_list[particle.circle] = particle while True: remaining = len(particles_list) if remaining <= 10: # less than n particles, animation too fast sleep(.011) # so add a delay elif remaining <= 100: sleep(.01) for c,p in particles_list.items(): # EDGE detect, if not at edge keep moving if 0 < p.px+p.dx < maxX and 0 < p.py+p.dy < maxY: p.px += p.dx p.py += p.dy # if at edge (x) then alter course to "bounce" if p.px+p.dx >= maxX or p.px+p.dx <= 0: p.dx = -(p.dx) p.px += p.dx c.move(p.dx,p.dy) #...finally, move particle to next position # if at top (y) then destroy if p.py+p.dy >= maxY: p.destroy(particles_list) # keep generating new bubbles... if len(particles_list) < total_particles: particle = Particle(window,maxX) particles_list[particle.circle] = particle # if stuck at bottom, let it float after 20 secs if p.dy == 0: if time() > p.born + 20: p.dy = randint(2,4) if __name__ == '__main__': main()