Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Want to join a pygame community? fb.com/groups/pygame
- # all skill levels welcome
- import math, random, sys
- import pygame
- from pygame.locals import *
- MAX_RADIUS = 50
- # render a table of values (hypot, cos, sin)
- data = []
- dataSize = int(math.hypot(MAX_RADIUS * 2, MAX_RADIUS * 2)) + 1
- for y in range(0, dataSize):
- data.append([])
- yIndex = len(data) - 1
- for x in range(0, dataSize):
- radians = math.atan2(y, x)
- data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
- for x in range(-dataSize, 0):
- radians = math.atan2(y, x)
- data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
- for y in range(-dataSize, 0):
- data.append([])
- yIndex = len(data) - 1
- for x in range(0, dataSize):
- radians = math.atan2(y, x)
- data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
- for x in range(-dataSize, 0):
- radians = math.atan2(y, x)
- data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
- # exit the program
- def events():
- for event in pygame.event.get():
- if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
- pygame.quit()
- sys.exit()
- # define display surface
- W, H = 1280, 720
- HW, HH = W / 2, H / 2
- AREA = W * H
- # initialise display
- pygame.init()
- CLOCK = pygame.time.Clock()
- DS = pygame.display.set_mode((W, H))
- pygame.display.set_caption("Circle Pusher")
- FPS = 120
- # define some colors
- BLACK = (0, 0, 0, 255)
- WHITE = (255, 255, 255, 255)
- class circle:
- def __init__(self, xy, radius, id):
- self.xy = xy
- self.radius = radius
- self.halfRadius = radius
- self.id = id
- self.color = (random.randint(128, 255), random.randint(128, 255), random.randint(128, 255), 255)
- def hasOverlapped(self, xy, radius):
- global data
- minDistance = 0.0 + radius + self.radius
- minDistanceSquared = minDistance * minDistance
- x = int(xy[0] - self.xy[0])
- y = int(xy[1] - self.xy[1])
- distance = x * x + y * y
- if distance >= minDistanceSquared: return False
- overlap = 1 + minDistance - data[y][x][0]
- return (data[y][x][1] * overlap, data[y][x][2] * overlap, overlap)
- def setXY(self, xy):
- self.xy = xy
- def draw(self):
- d = pygame.display.get_surface()
- pygame.draw.circle(d, self.color, (int(self.xy[0]), int(self.xy[1])), self.halfRadius, 0)
- class circles:
- def __init__(self):
- self.container = list([])
- self.overlap = list([])
- def add(self):
- global W, H, MAX_RADIUS
- while True:
- radius = random.randint(15, MAX_RADIUS)
- xy = [random.randint(radius, W - radius), random.randint(radius, H - radius)]
- noOverlap = True
- for c in self.container:
- if c.hasOverlapped(xy, radius):
- noOverlap = False
- break
- if noOverlap: break
- self.container.append(circle(xy, radius, len(self.container)))
- def collision(self):
- self.overlap.append(self.container[0])
- while self.overlap:
- source = self.overlap[0]
- self.overlap.pop(0)
- for index in range(1, len(self.container)):
- target = self.container[index]
- if target.id == source.id: continue
- result = source.hasOverlapped(target.xy, target.radius)
- if result:
- target.xy[0] += result[0]
- target.xy[1] += result[1]
- self.overlap.append(target)
- def drawAll(self):
- for source in self.container:
- source.draw()
- def do(self):
- self.collision()
- self.drawAll()
- circs = circles()
- for i in range(0, 200): circs.add()
- # main loop
- while True:
- events()
- mx, my = pygame.mouse.get_pos()
- circs.container[0].setXY([mx, my])
- circs.do()
- pygame.display.update()
- #CLOCK.tick(FPS)
- DS.fill(BLACK)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement