Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame
- from pygame import Rect
- from pygame import Vector2
- from random import randint, uniform
- # particle
- class particle:
- def __init__(s, xy, vel): # xy = tuple(x, y)
- # position of the particle
- s.xy = Vector2(xy)
- # particle velocity
- 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
- # particle radius
- s.radius = randint(4, 8) # random integer between 5 & 15
- # draw particle and update position/size
- def update(s):
- global PDS, WHITE # PDS = primary display surface
- # draw particle
- pygame.draw.circle(PDS, (128, 128, 128), s.xy, s.radius)
- # draw glow
- s.glow()
- # add velocity to particle
- s.xy += s.vel
- # add gravity to velocity. negative velocity will slowly become positive
- s.vel.y += GRAVITY
- # decrease radius to give a fizzling out effect
- s.radius -= 0.1
- def glow(s):
- global PDS
- # get rectangular size of the particle. radius * 2
- r = Vector2(s.radius) * 2 # r = (radius * 2, radius * 2)
- # create a surface twice the size of the particle
- gs = pygame.Surface(r * 2)
- # draw a circle with a radius twice the size of the particle in the center of the new surface
- pygame.draw.circle(gs, (60, 20, 60), r, r.x)
- # blit the new larger particle on the primary display with the center of the smaller particle
- # use BLEND_RGB_ADD to increase luminosity if particles overlap
- PDS.blit(gs, s.xy - r, special_flags=pygame.BLEND_RGB_ADD)
- class ball:
- def __init__(s, xy, v):
- s.xy = xy
- s.v = v
- def update(s):
- global OBSTICLES, BALL_RADIUS, BALL_RADIUS_V, BALL_RADIUS2_V
- r = Rect(s.xy - BALL_RADIUS_V, BALL_RADIUS2_V)
- nr = Rect(s.xy + s.v - (10, 10), (20, 20))
- for o in OBSTICLES:
- if not o.colliderect(nr): continue
- if nr.right >= o.left and r.right <= o.left:
- r.right = o.left
- s.v.x = -s.v.x
- burst(r.midright, 1, 0)
- if nr.left <= o.right and r.left >= o.right:
- r.left = o.right
- s.v.x = -s.v.x
- burst(r.midleft, 1, 1)
- if nr.bottom >= o.top and r.bottom <= o.top:
- r.bottom = o.top
- s.v.y = -s.v.y
- burst(r.midbottom, 0, 0)
- if nr.top <= o.bottom and r.top >= o.bottom:
- r.top = o.bottom
- s.v.y = -s.v.y
- burst(r.midbottom, 0, 1)
- s.xy = Vector2(r.center)
- pygame.draw.circle(PDS, WHITE, s.xy, BALL_RADIUS)
- s.xy += s.v
- def burst(xy, verticies, ricochet_direction):
- global PARTICLES
- for i in range(20):
- if verticies == 0: # horizontal particle burst
- v = Vector2(uniform(-4, -2) if i // 10 else uniform(2, 4), uniform(1, 2) if ricochet_direction else uniform(-2, -1))
- else:
- v = Vector2(uniform(1, 2) if ricochet_direction else uniform(-2, -1), uniform(-4, -2) if i // 10 else uniform(2, 4))
- PARTICLES += [particle(xy, v)]
- # initialise pygame and create primary display surface PDS
- pygame.init()
- PDR = Rect(0, 0, 1280, 720)
- PDS = pygame.display.set_mode(PDR.size)
- # define some colors
- BLACK = (0, 0, 0)
- WHITE = (255, 255, 255)
- # strength of gravity
- GRAVITY = 0.1
- # particle container
- PARTICLES = []
- # obsticles
- OBSTICLES = [
- Rect(0, 0, PDR.w, 20),
- Rect(0, 20, 20, PDR.h),
- Rect(20, PDR.h - 20, PDR.w - 20, 20),
- Rect(PDR.w - 20, 20, 20, PDR.h - 40),
- Rect(PDR.w / 3 - 10, 140, 20, PDR.h - 280),
- Rect(-10 + PDR.w - PDR.w / 3, 140, 20, PDR.h - 280),
- Rect(140, PDR.centery - 10, PDR.w / 3 - 270, 20),
- Rect(PDR.w - 300, PDR.centery - 10, PDR.w / 3 - 270, 20)
- ]
- BALL_RADIUS = 10
- BALL_RADIUS_V = Vector2(BALL_RADIUS)
- BALL_RADIUS2_V = BALL_RADIUS_V * 2
- BALLS = [ball(Vector2(PDR.center), Vector2(5).rotate(d)) for d in range(0, 360, 20)]
- exitDemo = False
- pause = False # press p to pause
- while not exitDemo:
- # handle the events
- events = pygame.event.get()
- for event in events:
- if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
- exitDemo = True
- if event.type == pygame.KEYDOWN and event.key == pygame.K_p:
- pause = 1 - pause
- if pause: continue
- # clear the PDS to black
- PDS.fill(BLACK)
- for o in OBSTICLES:
- pygame.draw.rect(PDS, (60, 20, 60), o, 2)
- for b in BALLS:
- b.update()
- # create a container to hold particles that need deleting
- killParticles = []
- for p in PARTICLES:
- p.update() # draw and update postion/size of the particle
- # if the particle is outside of the PDS or the radius is less than zero ie no longer visible
- # then add it the killparticles pile
- if p.xy.y >= PDR.bottom or p.radius <= 0:
- killParticles += [p]
- # delete particles from particle container
- for p in killParticles:
- PARTICLES.remove(p)
- # update the PDS
- pygame.display.update()
- pygame.time.Clock().tick(120) # limit FPS to 120
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement