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