Welcome

首页 / Python / 用Python编写一个烟花烯放效果的应用程序

提示词: 

用Python编写一个烟花烯放效果的应用程序

具体要求如下:

 1、程序运行后在屏幕中间弹出一个800*600的窗口。 

2、在窗口是的任何一个位置点击后,从鼠标点击的X坐标处的窗口底部发射一个烟花。 

3、烟花在上生过程中需要带上小火星,来模拟实现真实的烟花燃放效果。 

4、当烟花到达鼠标点击的Y坐标时,烟花炸开,出现五颜六色的烟火效果。 

5、烟火效果自由下落,下落过程中渐渐淡去。 以上是我的具体要求,要求程序能够直接执行不报错。

代码实现:
import os

import pygame
import random
import math
from pygame.locals import *

# 初始化Pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("烟花模拟")
clock = pygame.time.Clock()

# 颜色定义
COLORS = [
    (255, 0, 0),  # 红
    (0, 255, 0),  # 绿
    (0, 0, 255),  # 蓝
    (255, 255, 0),  # 黄
    (255, 0, 255),  # 紫
    (0, 255, 255)  # 青
]


# 粒子类
class Particle:
    def __init__(self, x, y, is_rocket=False):
        self.is_rocket = is_rocket
        self.x, self.y = x, y
        self.vx = random.uniform(-3, 3) if not is_rocket else 0
        self.vy = random.uniform(-18, -12) if is_rocket else random.uniform(-3, 3)
        self.radius = random.randint(1, 3) if not is_rocket else 2
        self.life = 255
        self.color = random.choice(COLORS) if not is_rocket else (255, 255, 200)
        self.gravity = 0.5 if not is_rocket else 0

    def move(self):
        if not self.is_rocket:
            self.vx *= 0.95
            self.vy *= 0.95
            self.vy += self.gravity

        self.x += self.vx
        self.y += self.vy
        self.life -= 4 if not self.is_rocket else 0

    def draw(self):
        if self.life > 0:
            alpha_surface = pygame.Surface((self.radius * 2, self.radius * 2), pygame.SRCALPHA)
            alpha = self.life if not self.is_rocket else 255
            pygame.draw.circle(alpha_surface, (*self.color, alpha),
                               (self.radius, self.radius), self.radius)
            screen.blit(alpha_surface, (self.x - self.radius, self.y - self.radius))


# 烟花管理器
class Firework:
    def __init__(self, start_x, target_y):
        self.rocket = Particle(start_x, HEIGHT, is_rocket=True)
        self.particles = []
        self.exploded = False
        self.target_y = target_y

    def update(self):
        if not self.exploded:
            # 更新火箭位置
            self.rocket.move()

            # 添加尾迹粒子
            if random.random() < 0.4:
                self.particles.append(Particle(self.rocket.x, self.rocket.y))

            # 检查爆炸条件
            if self.rocket.y <= self.target_y:
                self.explode()

        # 更新所有粒子
        for p in self.particles[:]:
            p.move()
            if p.life <= 0:
                self.particles.remove(p)

    def explode(self):
        self.exploded = True
        # 生成爆炸粒子
        for _ in range(100):
            angle = random.uniform(0, 2 * math.pi)
            speed = random.uniform(3, 8)
            p = Particle(self.rocket.x, self.rocket.y)
            p.vx = math.cos(angle) * speed
            p.vy = math.sin(angle) * speed
            p.radius = random.randint(2, 4)
            self.particles.append(p)

    def draw(self):
        if not self.exploded:
            self.rocket.draw()
        for p in self.particles:
            p.draw()


# 主程序
fireworks = []
running = True

# 设置窗口居中
os.environ['SDL_VIDEO_CENTERED'] = '1'

while running:
    screen.fill((0, 0, 0))  # 黑色背景

    for event in pygame.event.get():
        if event.type == QUIT:
            running = False
        elif event.type == MOUSEBUTTONDOWN:
            # 创建新的烟花
            mouse_x, mouse_y = pygame.mouse.get_pos()
            fireworks.append(Firework(mouse_x, mouse_y))

    # 更新和绘制所有烟花
    for fw in fireworks[:]:
        fw.update()
        fw.draw()
        if fw.exploded and len(fw.particles) == 0:
            fireworks.remove(fw)

    pygame.display.flip()
    clock.tick(60)

pygame.quit()