Python小程序:模拟烟花

python爱好者,业余时间写个模拟烟花小程序。

import pygame,random,math,time,sys

#========================================================
# 设置屏幕大小、背景色
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
BG_COLOR = (0,0,0)

# 设置烟花参数
FIREWORKS_COUNT = 8 #屏幕上同时出现的烟花个数
PARTICLES_COUNT = 50 #每个烟花爆炸的微粒个数
VELOCITY_MIN,VELOCITY_MAX = 5,8
GRAVITY = 0.05 #模拟重力减速度
SIZE_MIN, SIZE_MAX= 1,2 #烟花半径范围
P_size_min,P_size_max = 1,2 #烟花微粒的最大半径
LIGHT_SIZE_MIN,LIGHT_SIZE_MAX = 10,20 #烟花爆炸瞬间光斑半径
PARTICLE_MOVE_LIMITE = 100 #爆炸粒子移动的最远距离(超过距离则删除)

#背景图片定义
background_filename = 'night.jpg'
FRAME = 60 #设置画面刷新率

#========================================================
class Firework:
    """定义烟花类"""
    def __init__(self, x, y):
        self.x = x
        self.y = y
        #随机烟花的半径、颜色、水平分速度、竖直分速度
        self.size = random.randint(SIZE_MIN,SIZE_MAX)
        self.color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        self.velocity_y = random.uniform(VELOCITY_MIN,VELOCITY_MAX)        
        self.gravity = GRAVITY
        #初始化本烟花的微粒和爆炸状态
        self.particles = []       
        self.exploded = False
        #随机产生一个爆炸高度,范围是距离顶部50至三分之一屏高
        self.Rand_height = random.randint(50,int(SCREEN_HEIGHT/2))
        
    def explode(self,screen):
        """爆炸函数,产生微粒"""
        self.exploded = True
        #在爆炸处生成一个转瞬即逝的直径为LIGHT_SIZE的闪光
        pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), random.randint(LIGHT_SIZE_MIN,LIGHT_SIZE_MAX))
        for _ in range(PARTICLES_COUNT):
            angle = random.uniform(0, 2 * math.pi)  # 随机角度
            speed = random.uniform(5, 7)  # 随机速度
            particle_x = self.x + speed * math.cos(angle)  # 计算粒子的x坐标
            particle_y = self.y + speed * math.sin(angle)  # 计算粒子的y坐标
            particle = Particle(particle_x, particle_y, screen)  # 生成粒子
            self.particles.append(particle)  # 将粒子添加到烟花的粒子列表中

    def draw(self, screen):
        """绘制烟花或者微粒"""
        if not self.exploded:
            #若未爆炸,则在当前坐标画圆
            self.rect = pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.size)
        else:
            #若已爆炸,则画爆炸微粒 
            for particle in self.particles:
                particle.draw(screen)
                particle.update() #此句不用也可以,微粒的速度会慢一点

    def update(self,screen):
        """更新烟花位置,或者更新微粒"""
        Label = False # 定义一个标签,反映烟花爆炸后,微粒移动距离是否超过100单位
        if not self.exploded:            
            # 烟花如果未爆炸,则竖直上升,上升的速度越来越慢
            self.y -= self.velocity_y  #velocity_y为上升速度
            self.velocity_y -= GRAVITY            
            self.rect.y = self.y
            # 如果上升高度达到随机的爆炸高度,则爆炸
            if self.rect.y <= self.Rand_height or \
               self.velocity_y <= 0: # 或者烟花到达最高点(上升速度降为0)时,烟花爆炸
                self.explode(screen)
            elif self.rect.y > SCREEN_HEIGHT: # 如果烟花到达屏幕下沿,则标记Label(删除该烟花)。
                Label = True    
        else:
            # 烟花若已爆炸,逐个扫描微粒的移动距离
            for particle in self.particles:
                particle.update()
                if particle.move_distance() >= PARTICLE_MOVE_LIMITE: #若移动距离超过限值,则移除该微粒
                    self.particles.remove(particle)            
                    Label = True  #若微粒移动超过100,返回此标签(为了删除此烟花)
                    break
        return Label


#=============================================================
class Particle:
    """定义粒子类"""
    def __init__(self, x, y,screen):
        self.x = x
        self.y = y
        self.x0, self.y0 = x, y #记录初始坐标        
        self.color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        self.size = random.randint(P_size_min,P_size_max)
        self.velocity_y = random.uniform(-1, -0.6) * random.random() # 粒子的竖直速度在-0.6到-1之间随机变化
        self.velocity_x = random.uniform(-1, 1) * random.random()  # 粒子的水平速度在-1到1之间随机变化
        self.rect = pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.size)

    def update(self):
        """更新粒子rect位置"""
        speed_rate = 1.2 # 定义一个速度系数,微调微粒速度
        self.x += self.velocity_x * speed_rate
        self.y += self.velocity_y * speed_rate
        self.velocity_y += GRAVITY * 0.2 # 微粒的重力加速度要设置得小一点
        #更新微粒的rect对象的值,否则显示微粒不动
        self.rect.x = self.x
        self.rect.y = self.y

    def move_distance(self):
        """计算移动的距离"""
        return int(math.sqrt((self.x-self.x0)**2+(self.y-self.y0)**2))

    def draw(self, screen):
        """绘制粒子"""
        pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.size)


#==============================================================
def generate_fireworks(fireworks):
    """装载烟花"""
    #如果画面烟花数量小于设置上限就补充
    if len(fireworks) <= FIREWORKS_COUNT:
        #firework = Firework((random.randint(20, SCREEN_WIDTH-20)),(random.randint(int(SCREEN_HEIGHT/2), int(SCREEN_HEIGHT))))
        firework = Firework((random.randint(20, SCREEN_WIDTH-20)),(random.randint(SCREEN_HEIGHT-150, SCREEN_HEIGHT-100)))
        fireworks.append(firework)
    return fireworks                      


#==============================================================
def update_screen(fireworks,screen):
    """刷新屏幕"""
  
    try:
        background = pygame.image.load(background_filename).convert()
    except FileNotFoundError:
        #print("Sorry, the file " + background_filename + " does not exist.")
        #input()
        screen.fill(BG_COLOR) #若没有背景图片,则使用纯黑色背景!
    else:
        screen.blit(background, (0, 0))
    #遍历烟花,满足条件即删除
    for firework in fireworks:
        firework.draw(screen)
        Label = firework.update(screen)
        # 若烟花的微粒移动距离超过指定数值,则删除该烟花(包括其所有微粒)
        if Label == True :
            fireworks.remove(firework)          

    #让最近绘制的屏幕可见
    pygame.display.flip()     


#===============================================================
def rungame():
    """主函数"""
    #初始化
    pygame.init()
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    screen.fill(BG_COLOR)
    pygame.display.set_caption("Fireworks")
    clock = pygame.time.Clock()
    fireworks = []

    #开始循环
    while True :
        #设置帧率(如帧率过高,则一闪而过)
        clock.tick(FRAME)
        #点击窗口X按钮,退出程序
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        #生成烟花
        generate_fireworks(fireworks)

        #刷新屏幕
        update_screen(fireworks,screen)


#==============================================================
"""运行主函数"""
if __name__ == '__main__':
    rungame()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当然可以!下面是一个用Python编写的简单烟花小程序的示例: ```python import pygame import random # 初始化pygame pygame.init() # 设置窗口大小和标题 screen_width = 800 screen_height = 600 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("烟花小程序") # 定义烟花类 class Firework: def __init__(self, x, y): self.x = x self.y = y self.color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) self.radius = 3 self.speed = random.randint(1, 5) self.exploded = False def move(self): if not self.exploded: self.y -= self.speed def explode(self): self.exploded = True for _ in range(100): sparks.append(Spark(self.x, self.y, self.color)) def draw(self): pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.radius) # 定义火花类 class Spark: def __init__(self, x, y, color): self.x = x self.y = y self.color = color self.radius = 2 self.angle = random.uniform(0, 2 * math.pi) self.speed = random.uniform(1, 5) def move(self): self.x += math.cos(self.angle) * self.speed self.y += math.sin(self.angle) * self.speed def draw(self): pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.radius) # 创建烟花和火花列表 fireworks = [] sparks = [] # 游戏主循环 running = True while running: # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 生成新的烟花 if random.random() < 0.01: fireworks.append(Firework(random.randint(0, screen_width), screen_height)) # 更新烟花和火花的位置 for firework in fireworks: firework.move() if firework.y < 200 and not firework.exploded: firework.explode() for spark in sparks: spark.move() # 绘制烟花和火花 screen.fill((0, 0, 0)) for firework in fireworks: firework.draw() for spark in sparks: spark.draw() # 移除已经消失的火花 sparks = [spark for spark in sparks if spark.radius > 0] # 更新屏幕显示 pygame.display.flip() # 退出游戏 pygame.quit() ``` 这个程序使用了Pygame库来创建窗口和处理图形绘制。它通过不断生成新的烟花对象,并在一定高度上爆炸成火花对象来模拟烟花效果。每个烟花和火花对象都有自己的位置、颜色、半径和速度等属性,通过不断更新和绘制它们来实现动画效果。 希望这个示例能帮助到你!如果你有任何相关问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值