Advertisement
cookertron

Pull and release ball 2

Mar 11th, 2022 (edited)
922
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.96 KB | None | 0 0
  1. from random import randint, uniform
  2. import time, sys
  3. import pygame
  4. from pygame import Rect as R
  5. from pygame import Vector2 as V
  6. from pygame.locals import *
  7.  
  8. class particle:
  9.     def __init__(s, xy, vel): # xy = tuple(x, y)
  10.         # position of the particle
  11.         s.xy = V(xy)
  12.  
  13.         # particle velocity
  14.         s.vel = vel #Vector2(uniform(-1, 1), uniform(-4.5, -5)) # x vel is betweem -1 & 1 and y vel is between -4.5 and -5
  15.  
  16.         # particle radius
  17.         s.radius = randint(20, 30) # random integer between 5 & 15
  18.  
  19.     # draw particle and update position/size
  20.     def update(s):
  21.         global dt
  22.         global GRAVITY
  23.         global PDS, WHITE # PDS = primary display surface
  24.  
  25.         # draw particle
  26.         pygame.draw.circle(PDS, (128, 128, 128), s.xy, s.radius)
  27.  
  28.         # draw glow
  29.         s.glow()
  30.  
  31.         # add velocity to particle
  32.         s.xy += s.vel * dt
  33.  
  34.         # add gravity to velocity. negative velocity will slowly become positive
  35.         s.vel.y += GRAVITY * dt
  36.  
  37.         # decrease radius to give a fizzling out effect
  38.         s.radius -= 0.1 * dt
  39.  
  40.     def glow(s):
  41.         global PDS
  42.         # get rectangular size of the particle. radius * 2
  43.         r = V(s.radius) * 2 # r = (radius * 2, radius * 2)
  44.  
  45.         # create a surface twice the size of the particle
  46.         gs = pygame.Surface(r * 2)
  47.  
  48.         # draw a circle with a radius twice the size of the particle in the center of the new surface
  49.         pygame.draw.circle(gs, (60, 20, 60), r, r.x)
  50.  
  51.         # blit the new larger particle on the primary display with the center of the smaller particle
  52.         # use BLEND_RGB_ADD to increase luminosity if particles overlap
  53.         PDS.blit(gs, s.xy - r, special_flags=pygame.BLEND_RGB_ADD)
  54.  
  55. def burst(xy, verticies, ricochet_direction):
  56.     global parts
  57.  
  58.     for i in range(20):
  59.         if verticies == 0: # horizontal particle burst
  60.             v = V(uniform(-4, -2) if i // 10 else uniform(2, 4), uniform(1, 2) if ricochet_direction else uniform(-5, -4))
  61.         else:
  62.             v = V(uniform(1, 2) if ricochet_direction else uniform(-2, -1), uniform(-4, -2) if i // 10 else uniform(5, 4))
  63.         parts += [particle(xy, v)]
  64.  
  65. WHITE = (255, 255, 255)
  66. RED = (255, 0, 0)
  67.  
  68. pygame.init()
  69. PDS = pygame.display.set_mode()
  70. PDR = PDS.get_rect()
  71. FPS = 120
  72.  
  73. GRAVITY = 0.1
  74.  
  75. parts = []
  76. ball = V(PDR.center)
  77. rad = 80
  78. v = V()
  79. f = V()
  80.  
  81. pressed = False
  82. pressed_timer = None
  83.  
  84. dts = time.time()
  85. exit_demo = False
  86. while not exit_demo:
  87.     for e in pygame.event.get():
  88.         if e.type == KEYDOWN and e.key == K_ESCAPE:
  89.             exit_demo = True
  90.  
  91.     now = time.time()
  92.     dt = (now - dts) * FPS
  93.     dts = now
  94.    
  95.     mp = V(pygame.mouse.get_pos())
  96.     dist = mp.distance_to(ball)
  97.    
  98.     mb = pygame.mouse.get_pressed()
  99.     if mb[0] and not pressed:
  100.         if dist <= rad:
  101.             pressed = True
  102.             pressed_timer = time.time()
  103.     if pressed:
  104.         if not mb[0]:
  105.             if dist > rad:
  106.                 deg = V().angle_to(mp - ball)
  107.                 a = V(1, 0)
  108.                 b = a.rotate(deg + 180) * (dist - rad)
  109.                 v = b / 10
  110.             pressed = False
  111.         if now - pressed_timer > 4:
  112.             exit_demo = True
  113.  
  114.     ball += v * dt
  115.     if v.x != 0 or v.y != 0:
  116.         a = v.normalize()
  117.         v -= (a / 10) * dt
  118.     if ball.x + rad > PDR.w: # RIGHT
  119.         ball.x = PDR.w - rad
  120.         v.x = -v.x
  121.         burst(ball + (rad, 0), 1, 0)
  122.     if ball.x - rad < 0: # LEFT
  123.         ball.x = rad
  124.         v.x = -v.x
  125.         burst(ball - (rad, 0), 1, 1)
  126.     if ball.y + rad > PDR.h: # BOTTOM
  127.         ball.y = PDR.h - rad
  128.         v.y = -v.y
  129.         burst(ball + (0, rad), 0, 0)
  130.     if ball.y - rad < 0: # TOP
  131.         ball.y = rad
  132.         v.y = -v.y
  133.         burst(ball - (0, rad), 0, 1)
  134.    
  135.     PDS.fill(0)
  136.     # create a container to hold particles that need deleting
  137.    
  138.     kill_parts = []
  139.     for p in parts:
  140.         p.update() # draw and update postion/size of the particle
  141.        
  142.         # if the particle is outside of the PDS or the radius is less than zero ie no longer visible
  143.         # then add it the killparticles pile
  144.         if p.xy.y >= PDR.bottom or p.radius <= 0:
  145.             kill_parts += [p]
  146.    
  147.     for p in kill_parts:
  148.         parts.remove(p)
  149.  
  150.     if pressed and dist > rad:
  151.         pygame.draw.line(PDS, RED, ball, mp)
  152.     pygame.draw.circle(PDS, WHITE, ball, rad)
  153.    
  154.     pygame.display.update()
  155. pygame.quit()
  156. sys.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement