import random import pygame import PyParticles class UniverseScreen: def __init__ (self, width, height): self.width = width self.height = height (self.dx, self.dy) = (0, 0) (self.mx, self.my) = (0, 0) self.magnification = 1.0 def scroll(self, dx=0, dy=0): self.dx += dx * width / (self.magnification*10) self.dy += dy * height / (self.magnification*10) def zoom(self, zoom): self.magnification *= zoom self.mx = (1-self.magnification) * self.width/2 self.my = (1-self.magnification) * self.height/2 def reset(self): (self.dx, self.dy) = (0, 0) (self.mx, self.my) = (0, 0) self.magnification = 1.0 def calculateRadius(mass): return 0.5 * mass ** (0.5) (width, height) = (400, 400) screen = pygame.display.set_mode((width, height)) pygame.display.set_caption('Star formation') universe = PyParticles.Environment((width, height)) universe.colour = (0,0,0) universe.addFunctions(['move', 'attract', 'combine']) universe_screen = UniverseScreen(width, height) for p in range(100): particle_mass = random.randint(1,4) particle_size = calculateRadius(particle_mass) universe.addParticles(mass=particle_mass, size=particle_size, speed=0, colour=(255,255,255)) key_to_function = { pygame.K_LEFT: (lambda x: x.scroll(dx = 1)), pygame.K_RIGHT: (lambda x: x.scroll(dx = -1)), pygame.K_DOWN: (lambda x: x.scroll(dy = -1)), pygame.K_UP: (lambda x: x.scroll(dy = 1)), pygame.K_EQUALS: (lambda x: x.zoom(2)), pygame.K_MINUS: (lambda x: x.zoom(0.5)), pygame.K_r: (lambda x: x.reset())} clock = pygame.time.Clock() paused = False running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key in key_to_function: key_to_function[event.key](universe_screen) elif event.key == pygame.K_SPACE: paused = (True, False)[paused] if not paused: universe.update() screen.fill(universe.colour) particles_to_remove = [] for p in universe.particles: if 'collide_with' in p.__dict__: particles_to_remove.append(p.collide_with) p.size = calculateRadius(p.mass) del p.__dict__['collide_with'] x = int(universe_screen.mx + (universe_screen.dx + p.x) * universe_screen.magnification) y = int(universe_screen.my + (universe_screen.dy + p.y) * universe_screen.magnification) size = int(p.size * universe_screen.magnification) if size < 2: pygame.draw.rect(screen, p.colour, (x, y, 2, 2)) else: pygame.draw.circle(screen, p.colour, (x, y), size, 0) for p in particles_to_remove: if p in universe.particles: universe.particles.remove(p) pygame.display.flip() clock.tick(80)