Advertisement
Windspar

Pygame Linking Nodes

May 7th, 2024
591
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.82 KB | None | 0 0
  1. import random
  2. import pygame
  3. from pygame.sprite import Group, Sprite
  4.  
  5. class Entity(Sprite):
  6.     def __init__(self, image, position, anchor):
  7.         super().__init__()
  8.         self.image = image
  9.         self.rect = image.get_rect(**{anchor: position})
  10.         self.center = pygame.Vector2(self.rect.center)
  11.         self.vector = pygame.Vector2()
  12.         self._random()
  13.  
  14.     def _random(self):
  15.         self.vector.from_polar((1, random.randint(0, 360)))
  16.         self.velocity = random.randrange(60, 180)
  17.  
  18.     def update(self, delta, area):
  19.         self.center += self.vector * delta * self.velocity
  20.         self.rect.center = self.center
  21.         clamp = self.rect.clamp(area)
  22.  
  23.         # Boundry Collision
  24.         if clamp != self.rect:
  25.             if clamp.x != self.rect.x:
  26.                 self.vector.x = -self.vector.x
  27.  
  28.             if clamp.y != self.rect.y:
  29.                 self.vector.y = -self.vector.y
  30.  
  31.             self.rect = clamp
  32.             self.center = pygame.Vector2(self.rect.center)
  33.  
  34. class Scene:
  35.     def __init__(self, display):
  36.         self.display = display
  37.  
  38.     def on_draw(self, surface):
  39.         pass
  40.  
  41.     def on_event(self, event):
  42.         pass
  43.  
  44.     def on_update(self, delta):
  45.         pass
  46.  
  47. class Display:
  48.     def __init__(self, caption, width, height, flags=0, fps=60):
  49.         pygame.display.set_caption(caption)
  50.         self.display = pygame.display.set_mode((width, height), flags)
  51.         self.rect = self.display.get_rect()
  52.         self.clock = pygame.time.Clock()
  53.         self.running = True
  54.         self.delta = 0
  55.         self.fps = fps
  56.  
  57.         self.scene = Scene(self)
  58.  
  59.     def loop(self):
  60.         while self.running:
  61.             for event in pygame.event.get():
  62.                 self.scene.on_event(event)
  63.  
  64.             self.scene.on_update(self.delta)
  65.             self.scene.on_draw(self.display)
  66.             pygame.display.flip()
  67.             # Using delta time for smooth movement.
  68.             self.delta = self.clock.tick(self.fps) / 1000
  69.  
  70. class ImageHandler:
  71.     def __init__(self):
  72.         self.radius = 10
  73.         self.nodes = self.create_nodes()
  74.  
  75.     def create_nodes(self):
  76.         colors = self.get_colors()
  77.         nodes = []
  78.         transparent = 0, 0, 0, 0
  79.         size = self.radius * 2, self.radius * 2
  80.         surface = pygame.Surface(size, pygame.SRCALPHA)
  81.         surface.fill(transparent)
  82.         for color in colors:
  83.             pygame.draw.circle(surface, color, (self.radius, self.radius), self.radius)
  84.             nodes.append(surface.copy())
  85.  
  86.         return nodes
  87.  
  88.     def get_colors(self):
  89.         dark = 80
  90.         colors = []
  91.         for color in pygame.color.THECOLORS:
  92.             pcolor = pygame.Color(color)
  93.             if pcolor.a > dark and pcolor.g > dark and pcolor.b > dark:
  94.                 if not color.startswith('grey') and not color.startswith('gray'):
  95.                     colors.append(color)
  96.  
  97.         random.shuffle(colors)
  98.         return colors
  99.  
  100. class Main(Scene):
  101.     def __init__(self, display):
  102.         super().__init__(display)
  103.         self.image = ImageHandler()
  104.         self.nodes = Group()
  105.  
  106.         self.setup(20)
  107.  
  108.     def setup(self, count):
  109.         count = min(count, len(self.image.nodes))
  110.         self.nodes.empty()
  111.         rad = self.image.radius * 2
  112.         for i in range(count):
  113.             position = (random.randint(rad, self.display.rect.w - rad),
  114.                         random.randint(rad, self.display.rect.h - rad))
  115.  
  116.             self.nodes.add(Entity(self.image.nodes[i], position, 'center'))
  117.  
  118.     def draw_lines(self, surface):
  119.         rnd = random.randrange
  120.         for i, inode in enumerate(self.nodes):
  121.             nearest = None
  122.             min_dist = float('inf')
  123.             for j, jnode in enumerate(self.nodes):
  124.                 if i != j:
  125.                     dist = inode.center.distance_to(jnode.center)
  126.                     if dist < min_dist:
  127.                         min_dist = dist
  128.                         nearest = jnode
  129.  
  130.             line_color = pygame.Color(rnd(0, 255), rnd(0, 255), rnd(0, 255), 255)
  131.             if min_dist <= 255:
  132.                 line_color.a = int(255 - min_dist)
  133.  
  134.             if min_dist <= 1000:
  135.                 pygame.draw.line(surface, line_color, inode.rect.center, nearest.rect.center)
  136.  
  137.     def on_draw(self, surface):
  138.         surface.fill('black')
  139.         # Draw all lines first
  140.         self.draw_lines(surface)
  141.         # Draw all circles
  142.         self.nodes.draw(surface)
  143.  
  144.     def on_event(self, event):
  145.         if event.type == pygame.QUIT:
  146.             self.display.running = False
  147.  
  148.     def on_update(self, delta):
  149.         self.nodes.update(delta, self.display.rect)
  150.  
  151. def main():
  152.     pygame.init()
  153.     display = Display("Example", 800, 600)
  154.     main = Main(display)
  155.     display.scene = main
  156.     display.loop()
  157.     pygame.quit()
  158.  
  159. main()
  160.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement