Advertisement
cookertron

Pushing Circles [Python Pygame]

Nov 4th, 2018
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.63 KB | None | 0 0
  1. # Want to join a pygame community? fb.com/groups/pygame
  2. # all skill levels welcome
  3.  
  4. import math, random, sys
  5. import pygame
  6. from pygame.locals import *
  7.  
  8. MAX_RADIUS = 50
  9.  
  10. # render a table of values (hypot, cos, sin)
  11. data = []
  12. dataSize = int(math.hypot(MAX_RADIUS * 2, MAX_RADIUS * 2)) + 1
  13. for y in range(0, dataSize):
  14.     data.append([])
  15.     yIndex = len(data) - 1
  16.     for x in range(0, dataSize):
  17.         radians = math.atan2(y, x)
  18.         data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
  19.     for x in range(-dataSize, 0):
  20.         radians = math.atan2(y, x)
  21.         data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
  22. for y in range(-dataSize, 0):
  23.     data.append([])
  24.     yIndex = len(data) - 1
  25.     for x in range(0, dataSize):
  26.         radians = math.atan2(y, x)
  27.         data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
  28.     for x in range(-dataSize, 0):
  29.         radians = math.atan2(y, x)
  30.         data[yIndex].append([math.hypot(x, y), math.cos(radians), math.sin(radians)])
  31.  
  32. # exit the program
  33. def events():
  34.     for event in pygame.event.get():
  35.         if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
  36.             pygame.quit()
  37.             sys.exit()
  38.  
  39. # define display surface           
  40. W, H = 1280, 720
  41. HW, HH = W / 2, H / 2
  42. AREA = W * H
  43.  
  44. # initialise display
  45. pygame.init()
  46. CLOCK = pygame.time.Clock()
  47. DS = pygame.display.set_mode((W, H))
  48. pygame.display.set_caption("Circle Pusher")
  49. FPS = 120
  50.  
  51. # define some colors
  52. BLACK = (0, 0, 0, 255)
  53. WHITE = (255, 255, 255, 255)
  54.  
  55. class circle:
  56.     def __init__(self, xy, radius, id):
  57.         self.xy = xy
  58.         self.radius = radius
  59.         self.halfRadius = radius
  60.         self.id = id
  61.         self.color = (random.randint(128, 255), random.randint(128, 255), random.randint(128, 255), 255)
  62.        
  63.     def hasOverlapped(self, xy, radius):
  64.         global data
  65.        
  66.         minDistance = 0.0 + radius + self.radius
  67.         minDistanceSquared = minDistance * minDistance
  68.        
  69.         x = int(xy[0] - self.xy[0])
  70.         y = int(xy[1] - self.xy[1])
  71.         distance = x * x + y * y
  72.  
  73.         if distance >= minDistanceSquared: return False
  74.    
  75.         overlap = 1 + minDistance - data[y][x][0]      
  76.         return (data[y][x][1] * overlap, data[y][x][2] * overlap, overlap)
  77.    
  78.     def setXY(self, xy):
  79.         self.xy = xy
  80.        
  81.     def draw(self):
  82.         d = pygame.display.get_surface()
  83.         pygame.draw.circle(d, self.color, (int(self.xy[0]), int(self.xy[1])), self.halfRadius, 0)
  84.    
  85. class circles:
  86.     def __init__(self):
  87.         self.container = list([])
  88.         self.overlap = list([])
  89.        
  90.     def add(self):
  91.         global W, H, MAX_RADIUS
  92.         while True:
  93.             radius = random.randint(15, MAX_RADIUS)
  94.             xy = [random.randint(radius, W - radius), random.randint(radius, H - radius)]
  95.             noOverlap = True
  96.             for c in self.container:
  97.                 if c.hasOverlapped(xy, radius):
  98.                     noOverlap = False
  99.                     break
  100.             if noOverlap: break
  101.         self.container.append(circle(xy, radius, len(self.container)))
  102.    
  103.     def collision(self):
  104.         self.overlap.append(self.container[0])
  105.         while self.overlap:
  106.             source = self.overlap[0]
  107.             self.overlap.pop(0)
  108.  
  109.             for index in range(1, len(self.container)):
  110.                 target = self.container[index]
  111.                 if target.id == source.id: continue
  112.                
  113.                 result = source.hasOverlapped(target.xy, target.radius)
  114.                 if result:
  115.                     target.xy[0] += result[0]
  116.                     target.xy[1] += result[1]
  117.                     self.overlap.append(target)
  118.  
  119.     def drawAll(self):
  120.         for source in self.container:
  121.             source.draw()
  122.            
  123.     def do(self):
  124.         self.collision()
  125.         self.drawAll()
  126.        
  127. circs = circles()          
  128. for i in range(0, 200): circs.add()
  129.  
  130. # main loop
  131. while True:
  132.     events()
  133.    
  134.     mx, my = pygame.mouse.get_pos()
  135.     circs.container[0].setXY([mx, my])
  136.     circs.do()
  137.    
  138.     pygame.display.update()
  139.     #CLOCK.tick(FPS)
  140.     DS.fill(BLACK)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement