1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| import math import random import pygame
WIDTH, HEIGHT = 800, 700 BACKGROUND = (20, 20, 30) GRAVITY = pygame.Vector2(0, 0.12)
class Spark: def __init__(self, position, velocity, color, life=90): self.position = pygame.Vector2(position) self.velocity = pygame.Vector2(velocity) self.color = color self.life = life self.trail = []
def update(self): self.trail.insert(0, self.position.copy()) del self.trail[8:] self.velocity += GRAVITY self.velocity *= 0.985 self.position += self.velocity self.life -= 1
def draw(self, surface): for index, point in enumerate(self.trail): radius = max(1, 3 - index // 3) pygame.draw.circle(surface, self.color, point, radius) pygame.draw.circle(surface, self.color, self.position, 3)
@property def finished(self): return self.life <= 0
class Firework: def __init__(self): self.position = pygame.Vector2(random.randint(80, WIDTH - 80), HEIGHT) self.velocity = pygame.Vector2(random.uniform(-0.8, 0.8), random.uniform(-13, -10)) self.color = tuple(random.randint(80, 255) for _ in range(3)) self.exploded = False self.sparks = []
def explode(self): self.exploded = True for _ in range(random.randint(90, 150)): angle = random.uniform(0, math.tau) speed = random.uniform(2, 8) velocity = pygame.Vector2(math.cos(angle), math.sin(angle)) * speed self.sparks.append(Spark(self.position, velocity, self.color))
def update(self): if not self.exploded: self.velocity += GRAVITY self.position += self.velocity if self.velocity.y >= 0: self.explode() else: for spark in self.sparks: spark.update() self.sparks = [spark for spark in self.sparks if not spark.finished]
def draw(self, surface): if not self.exploded: pygame.draw.circle(surface, self.color, self.position, 4) for spark in self.sparks: spark.draw(surface)
@property def finished(self): return self.exploded and not self.sparks
def main(): pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption('Pygame Fireworks') clock = pygame.time.Clock() fireworks = [Firework(), Firework()] running = True
while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: fireworks.append(Firework())
if random.randint(0, 20) == 0: fireworks.append(Firework())
screen.fill(BACKGROUND) for firework in fireworks: firework.update() firework.draw(screen) fireworks = [item for item in fireworks if not item.finished]
pygame.display.flip() clock.tick(60)
pygame.quit()
if __name__ == '__main__': main()
|