import random

import math

particles = []

fireworks = []

buildings = []

click_count = 0

mega_firework = None

mega_particles = []

show_message = False

message_timer = 0

class Particle:

def \__init_\_(self, x, y, color, size_multiplier=1, velocity_multiplier=1):

    self.x = x

    self.y = y

    self.vx = random.uniform(-4, 4) \* velocity_multiplier

    self.vy = random.uniform(-4, 4) \* velocity_multiplier

    self.color = color

    self.life = 255

    self.max_life = 255

    self.size = random.uniform(3, 8) \* size_multiplier

    

def update(self):

    self.x += self.vx

    self.y += self.vy

    self.vy += 0.15  # 重力

    self.vx \*= 0.97  # 空气阻力

    self.life -= 2.5  # 3-4秒内淡出

    

def draw(self):

    if self.life > 0:

        pushStyle()

        # 添加发光效果

        for i in range(3):

            glow_size = self.size + i \* 2

            glow_alpha = self.life \* (0.3 - i \* 0.1)

            fill(red(self.color), green(self.color), blue(self.color), glow_alpha)

            noStroke()

            ellipse(self.x, self.y, glow_size, glow_size)

        

        # 核心粒子

        fill(255, 255, 255, self.life)  # 白色核心

        ellipse(self.x, self.y, self.size \* 0.5, self.size \* 0.5)

        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)  # 白色,后面会添加多种颜色

    else:

        # 每个烟花随机颜色

        hue = random.random()

        if hue < 0.2:

            self.color = color(255, 100, 100)  # 红色

        elif hue < 0.4:

            self.color = color(100, 255, 100)  # 绿色

        elif hue < 0.6:

            self.color = color(100, 100, 255)  # 蓝色

        elif hue < 0.8:

            self.color = color(255, 255, 100)  # 黄色

        else:

            self.color = color(255, 100, 255)  # 紫色

            

def update(self):

    if not self.exploded:

        speed = 6 if self.is_mega else 8

        self.y_pos -= speed

        if self.y_pos <= self.y:

            self.explode()

            self.exploded = True

            

def explode(self):

    particle_count = 200 if self.is_mega else 50

    for i in range(particle_count):

        angle = random.uniform(0, TWO_PI)

        speed = random.uniform(2, 8)

        px = self.x + cos(angle) \* speed

        py = self.y + sin(angle) \* speed

        

        if self.is_mega:

            # 超大烟花使用多种颜色

            colors = \[

                color(255, 0, 0), color(0, 255, 0), color(0, 0, 255),

                color(255, 255, 0), color(255, 0, 255), color(0, 255, 255),

                color(255, 165, 0), color(255, 255, 255)

            \]

            particle_color = random.choice(colors)

            size_multiplier = 1.5

            velocity_multiplier = 1.3

        else:

            particle_color = self.color

            size_multiplier = 1

            velocity_multiplier = 1

            

        particles.append(Particle(px, py, particle_color, size_multiplier, velocity_multiplier))

        

def draw(self):

    if not self.exploded:

        pushStyle()

        # 火箭尾部发光效果

        for i in range(3):

            glow_size = 6 - i

            glow_alpha = 200 - i \* 50

            fill(red(self.color), green(self.color), blue(self.color), glow_alpha)

            noStroke()

            ellipse(self.x, self.y_pos + i \* 3, glow_size, glow_size)

        popStyle()

class Building:

def \__init_\_(self, x, width, height):

    self.x = x

    self.width = width

    self.height = height

    self.windows = \[\]

    self.generate_windows()

    

def generate_windows(self):

    # 生成窗户,随机一些亮着

    window_rows = self.height // 40

    window_cols = self.width // 30

    

    for row in range(window_rows - 1):  # 留一层不要窗户

        for col in range(window_cols - 1):  # 留边距

            if random.random() > 0.3:  # 70%的概率有窗户

                is_lit = random.random() > 0.4  # 60%的概率亮着

                window_x = self.x + col \* 30 + 15

                window_y = height - self.height + row \* 40 + 20

                self.windows.append({

                    'x': window_x,

                    'y': window_y,

                    'lit': is_lit

                })



def draw(self):

    # 建筑剪影

    fill(0, 15, 8)

    rect(self.x, height - self.height, self.width, self.height)

    

    # 窗户

    for window in self.windows:

        if window\['lit'\]:

            fill(255, 255, 150, 200)  # 亮黄色灯光

        else:

            fill(20, 25, 35)  # 暗色,与背景相近

        noStroke()

        rect(window\['x'\], window\['y'\], 15, 20)

def setup():

size(800, 600)

background(20, 25, 40)



# 初始化建筑

buildings_data = \[

    (100, 80, 200),

    (250, 60, 150),

    (400, 70, 180),

    (550, 50, 120),

    (680, 90, 160)

\]



for x, w, h in buildings_data:

    buildings.append(Building(x, w, h))

def draw():

global mega_firework, show_message, message_timer



# 绘制夜晚背景

draw_background()



# 绘制建筑

for building in buildings:

    building.draw()



# 更新和绘制烟花

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:

        mega_firework = None

        show_message = True

        message_timer = 300  # 5秒 (60fps \* 5)



# 更新和绘制粒子

for particle in particles\[:\]:

    particle.update()

    particle.draw()

    if particle.life <= 0:

        particles.remove(particle)



# 更新和绘制超大粒子

for particle in mega_particles\[:\]:

    particle.update()

    particle.draw()

    if particle.life <= 0:

        mega_particles.remove(particle)



# 显示消息

if show_message:

    draw_message()

    message_timer -= 1

    if message_timer <= 0:

        show_message = False



# 绘制文字

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(50):

    x = (i \* 137.5 + frameCount \* 0.1) % width

    y = (i \* 89) % (height // 2)

    size = sin(frameCount \* 0.05 + i) \* 2 + 3

    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)

def draw_message():

pushStyle()

textAlign(CENTER, CENTER)

textSize(64)



# 彩虹渐变文字

colors = \[

    color(255, 0, 0), color(255, 165, 0), color(255, 255, 0),

    color(0, 255, 0), color(0, 0, 255), color(75, 0, 130), color(238, 130, 238)

\]



text_width = textWidth("Happy New Year!")

char_width = text_width / len("Happy New Year!")



for i, char in enumerate("Happy New Year!"):

    color_index = int((i / len("Happy New Year!")) \* len(colors))

    fill(colors\[color_index % len(colors)\])

    x = width/2 - text_width/2 + i \* char_width

    text(char, x, height/2)



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 left mouse button to launch fireworks", width/2, height - 30)



# 显示点击计数

textSize(14)

text("Clicks: " + str(click_count), 60, height - 30)

popStyle()

def mousePressed():

global click_count, mega_firework



if mouseButton == LEFT:

    click_count += 1

    

    # 每26次点击触发彩蛋

    if click_count % 26 == 0:

        mega_firework = Firework(width/2, height/2, is_mega=True)

    else:

        fireworks.append(Firework(mouseX, mouseY))
1月15日 17:25