import random
import math
particles = []
fireworks = []
static_windows = []
click_count = 0
mega_firework = None
class Particle:
def \__init_\_(self, x, y, color, velocity_multiplier=1, size_range=(1, 4)):
self.x = x
self.y = y
angle = random.uniform(0, TWO_PI)
speed = random.uniform(1, 6) \* velocity_multiplier
self.vx = cos(angle) \* speed
self.vy = sin(angle) \* speed
self.color = color
self.life = 255
self.max_life = 255
self.size = random.uniform(size_range\[0\], size_range\[1\])
self.trail = \[\]
def update(self):
# 保存轨迹
self.trail.append((self.x, self.y))
if len(self.trail) > 5:
self.trail.pop(0)
self.x += self.vx
self.y += self.vy
self.vy += 0.15 # 重力
self.vx \*= 0.97 # 空气阻力
self.life -= 2 # 淡出速度
def draw(self):
if self.life > 0:
pushStyle()
# 绘制轨迹
for i, (tx, ty) in enumerate(self.trail):
trail_alpha = (i / len(self.trail)) \* (self.life / 255) \* 100
trail_size = self.size \* (i / len(self.trail)) \* 0.5
fill(red(self.color), green(self.color), blue(self.color), trail_alpha)
noStroke()
ellipse(tx, ty, trail_size, trail_size)
# 绘制主粒子
fill(red(self.color), green(self.color), blue(self.color), self.life)
noStroke()
ellipse(self.x, self.y, self.size, self.size)
# 添加光晕效果
glow_size = self.size \* 2
glow_alpha = self.life \* 0.3
fill(red(self.color), green(self.color), blue(self.color), glow_alpha)
ellipse(self.x, self.y, glow_size, glow_size)
popStyle()
class Firework:
def \__init_\_(self, x, y, is_mega=False):
self.x = x
self.y = y
self.start_y = height
self.y_pos = self.start_y
self.exploded = False
self.is_mega = is_mega
if is_mega:
self.color = color(255, 255, 255) # 白色,稍后会用多种颜色
self.particle_count = 200
self.explosion_size = 3
else:
self.color = color(random.randint(150, 255), random.randint(150, 255), random.randint(150, 255))
self.particle_count = 60
self.explosion_size = 1
def update(self):
if not self.exploded:
speed = 12 if self.is_mega else 8
self.y_pos -= speed
if self.y_pos <= self.y:
self.explode()
self.exploded = True
def explode(self):
if self.is_mega:
# 超大烟花:多层彩色爆炸
colors = \[
color(255, 0, 0), # 红
color(255, 165, 0), # 橙
color(255, 255, 0), # 黄
color(0, 255, 0), # 绿
color(0, 0, 255), # 蓝
color(128, 0, 128), # 紫
color(255, 192, 203) # 粉
\]
for i, col in enumerate(colors):
for j in range(30):
angle = random.uniform(0, TWO_PI)
radius = random.uniform(50, 150)
px = self.x + cos(angle) \* radius
py = self.y + sin(angle) \* radius
particles.append(Particle(px, py, col, 2, (3, 8)))
else:
# 普通烟花
for i in range(self.particle_count):
angle = random.uniform(0, TWO_PI)
speed = random.uniform(1, 7)
px = self.x + cos(angle) \* speed \* 2
py = self.y + sin(angle) \* speed \* 2
particles.append(Particle(px, py, self.color, 1, (2, 6)))
def draw(self):
if not self.exploded:
pushStyle()
# 火箭轨迹
stroke(self.color)
strokeWeight(3)
line(self.x, self.y_pos + 15, self.x, self.y_pos)
# 火箭头部
fill(self.color)
noStroke()
ellipse(self.x, self.y_pos, 6, 6)
# 火箭光晕
fill(red(self.color), green(self.color), blue(self.color), 100)
ellipse(self.x, self.y_pos, 12, 12)
popStyle()
def setup():
size(800, 600)
background(20, 25, 40)
create_static_windows()
def create_static_windows():
# 建筑物窗户位置
window_positions = \[
(120, height - 180), (140, height - 160), (160, height - 140),
(270, height - 130), (290, height - 110),
(420, height - 160), (440, height - 140), (460, height - 120),
(560, height - 100),
(700, height - 140), (720, height - 120), (740, height - 100)
\]
for x, y in window_positions:
# 随机一些窗户亮着
if random.random() > 0.3:
static_windows.append((x, y, color(255, 255, 150))) # 暖黄色灯光
else:
static_windows.append((x, y, color(50, 50, 30))) # 暗色
def draw():
# 绘制夜晚背景
draw_background()
# 绘制静态窗户
draw_static_windows()
# 更新和绘制烟花
for firework in fireworks\[:\]:
firework.update()
firework.draw()
if firework.exploded and firework.y_pos <= firework.y:
fireworks.remove(firework)
# 更新和绘制超大烟花
if mega_firework:
mega_firework.update()
mega_firework.draw()
if mega_firework.exploded and mega_firework.y_pos <= mega_firework.y:
global mega_firework
mega_firework = None
# 更新和绘制粒子
for particle in particles\[:\]:
particle.update()
particle.draw()
if particle.life <= 0:
particles.remove(particle)
# 绘制文字
draw_text()
def draw_background():
# 深蓝天色渐变
for i in range(height):
inter = map(i, 0, height, 0, 1)
c = lerpColor(color(20, 25, 40), color(10, 15, 30), inter)
stroke(c)
line(0, i, width, i)
# 绘制星星
fill(255, 255, 200, 150)
noStroke()
for i in range(80):
x = (i \* 137.5 + frameCount \* 0.1) % width
y = (i \* 89) % (height // 2)
size = sin(frameCount \* 0.05 + i) \* 1.5 + 2
ellipse(x, y, size, size)
# 绘制地面剪影
fill(0, 20, 10)
beginShape()
vertex(0, height)
vertex(0, height - 100)
for x in range(0, width, 50):
y = height - 100 + sin(x \* 0.01) \* 20
vertex(x, y)
vertex(width, height - 100)
vertex(width, height)
endShape(CLOSE)
# 绘制建筑物剪影
fill(0, 15, 8)
rect(100, height - 200, 80, 200)
rect(250, height - 150, 60, 150)
rect(400, height - 180, 70, 180)
rect(550, height - 120, 50, 120)
rect(680, height - 160, 90, 160)
def draw_static_windows():
for x, y, window_color in static_windows:
pushStyle()
fill(window_color)
noStroke()
rect(x, y, 12, 12)
# 窗户光晕效果
if red(window_color) > 200: # 如果是亮着的窗户
fill(red(window_color), green(window_color), blue(window_color), 50)
rect(x-2, y-2, 16, 16)
popStyle()
def draw_text():
pushStyle()
textAlign(CENTER, CENTER)
textSize(48)
fill(255, 215, 0) # 金色
text("Happy New Year", width/2, 80)
textSize(24)
fill(255, 182, 193) # 粉色
text("2026", width/2, 120)
textSize(16)
fill(200, 200, 255, 200)
text("Click to launch fireworks! (Click 26 times for special surprise)", width/2, height - 30)
# 显示点击计数
textSize(14)
fill(255, 255, 255, 150)
text("Clicks: " + str(click_count) + "/26", width/2, height - 10)
popStyle()
def mousePressed():
global click_count, mega_firework
if mouseButton == LEFT:
click_count += 1
if click_count == 26:
# 彩蛋:超大烟花
mega_firework = Firework(width/2, height/3, is_mega=True)
click_count = 0 # 重置计数
else:
# 普通烟花
fireworks.append(Firework(mouseX, mouseY))
1月8日 17:27