Advertisement
cookertron

Circle Pusher (Distance Collision) [Pygame]

Nov 1st, 2018
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.70 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. # exit the program
  9. def events():
  10.     for event in pygame.event.get():
  11.         if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
  12.             pygame.quit()
  13.             sys.exit()
  14.  
  15. # define display surface           
  16. W, H = 1280, 720
  17. HW, HH = W / 2, H / 2
  18. AREA = W * H
  19.  
  20. # initialise display
  21. pygame.init()
  22. CLOCK = pygame.time.Clock()
  23. DS = pygame.display.set_mode((W, H))
  24. pygame.display.set_caption("Circle Pusher")
  25. FPS = 120
  26.  
  27. # define some colors
  28. BLACK = (0, 0, 0, 255)
  29. WHITE = (255, 255, 255, 255)
  30.  
  31.  
  32. class circle:
  33.     def __init__(self, xy, radius, id):
  34.         self.xy = xy
  35.         self.radius = radius
  36.         self.id = id
  37.         self.color = (random.randint(128, 255), random.randint(128, 255), random.randint(128, 255), 255)
  38.        
  39.     def hasOverlapped(self, xy, radius):
  40.         minDistance = 0.0 + radius + self.radius
  41.         distance = math.hypot(xy[0] - self.xy[0], xy[1] - self.xy[1])
  42.         if distance >= minDistance: return False
  43.        
  44.         radians = math.atan2(xy[1] - self.xy[1], xy[0] - self.xy[0])
  45.         overlap = 1 + (minDistance - distance)
  46.         return (math.cos(radians) * overlap, math.sin(radians) * overlap, overlap)
  47.    
  48.     def setXY(self, xy):
  49.         self.xy = xy
  50.        
  51.     def draw(self):
  52.         d = pygame.display.get_surface()
  53.         pygame.draw.circle(d, self.color, (int(self.xy[0]), int(self.xy[1])), self.radius, 0)
  54.    
  55. class circles:
  56.     def __init__(self):
  57.         self.container = list([])
  58.         self.overlap = list([])
  59.        
  60.     def add(self):
  61.         global W, H
  62.         while True:
  63.             radius = random.randint(15, 50)
  64.             xy = [random.randint(radius, W - radius), random.randint(radius, H - radius)]
  65.             noOverlap = True
  66.             for c in self.container:
  67.                 if c.hasOverlapped(xy, radius):
  68.                     noOverlap = False
  69.                     break
  70.             if noOverlap: break
  71.         self.container.append(circle(xy, radius, len(self.container)))
  72.    
  73.     def collision(self):
  74.         self.overlap.append(self.container[0])
  75.         while self.overlap:
  76.             source = self.overlap[0]
  77.             self.overlap.pop(0)
  78.  
  79.             for index in range(1, len(self.container)):
  80.                 target = self.container[index]
  81.                 if target.id == source.id: continue
  82.                
  83.                 result = source.hasOverlapped(target.xy, target.radius)
  84.                 if result:
  85.                     target.xy[0] += result[0]
  86.                     target.xy[1] += result[1]
  87.                     self.overlap.append(target)
  88.  
  89.     def drawAll(self):
  90.         for source in self.container:
  91.             source.draw()
  92.            
  93.     def do(self):
  94.         self.collision()
  95.         self.drawAll()
  96.        
  97. circs = circles()          
  98. for i in range(0, 200): circs.add()
  99.  
  100. # main loop
  101. while True:
  102.     events()
  103.    
  104.     mx, my = pygame.mouse.get_pos()
  105.     circs.container[0].setXY([mx, my])
  106.     circs.do()
  107.    
  108.     pygame.display.update()
  109.     #CLOCK.tick(FPS)
  110.     DS.fill(BLACK)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement