|
烟花代码运行效果:Python动态烟花代码importpygamefromrandomimportrandintfromrandomimportuniformfromrandomimportchoiceimportmathvector=pygame.math.Vector2#重力变量gravity=vector(0,0.3)#控制窗口的大小DISPLAY_WIDTH=DISPLAY_HEIGHT=800#颜色选项trail_colours=[(45,45,45),(60,60,60),(75,75,75),(125,125,125),(150,150,150)]dynamic_offset=1static_offset=3classFirework:def__init__(self):#随机颜色self.colour=(randint(0,255),randint(0,255),randint(0,255))self.colours=((randint(0,255),randint(0,255),randint(0,255)),(randint(0,255),randint(0,255),randint(0,255)),(randint(0,255),randint(0,255),randint(0,255)))self.firework=Particle(randint(0,DISPLAY_WIDTH),DISPLAY_HEIGHT,True,self.colour)self.exploded=Falseself.particles=[]self.min_max_particles=vector(100,225)defupdate(self,win):#每帧调用ifnotself.exploded:self.firework.apply_force(gravity)self.firework.move()fortfinself.firework.trails:tf.show(win)self.show(win)ifself.firework.vel.y>=0:self.exploded=Trueself.explode()else:forparticleinself.particles:particle.apply_force(vector(gravity.x+uniform(-1,1)/20,gravity.y/2+(randint(1,8)/100)))particle.move()fortinparticle.trails:t.show(win)particle.show(win)defexplode(self):amount=randint(self.min_max_particles.x,self.min_max_particles.y)foriinrange(amount):self.particles.append(Particle(self.firework.pos.x,self.firework.pos.y,False,self.colours))defshow(self,win):pygame.draw.circle(win,self.colour,(int(self.firework.pos.x),int(self.firework.pos.y)),self.firework.size)defremove(self):ifself.exploded:forpinself.particles:ifp.removeisTrue:self.particles.remove(p)iflen(self.particles)==0:returnTrueelse:returnFalseclassParticle:def__init__(self,x,y,firework,colour):self.firework=fireworkself.pos=vector(x,y)self.origin=vector(x,y)self.radius=20self.remove=Falseself.explosion_radius=randint(5,18)self.life=0self.acc=vector(0,0)self.trails=[]self.prev_posx=[-10]*10self.prev_posy=[-10]*10ifself.firework:self.vel=vector(0,-randint(17,20))self.size=5self.colour=colourforiinrange(5):self.trails.append(Trail(i,self.size,True))else:self.vel=vector(uniform(-1,1),uniform(-1,1))self.vel.x*=randint(7,self.explosion_radius+2)self.vel.y*=randint(7,self.explosion_radius+2)#向量self.size=randint(2,4)self.colour=choice(colour)#5个tails总计foriinrange(5):self.trails.append(Trail(i,self.size,False))defapply_force(self,force):self.acc+=forcedefmove(self):ifnotself.firework:self.vel.x*=0.8self.vel.y*=0.8self.vel+=self.accself.pos+=self.velself.acc*=0ifself.life==0andnotself.firework:#检查粒子的爆炸范围distance=math.sqrt((self.pos.x-self.origin.x)**2+(self.pos.y-self.origin.y)**2)ifdistance>self.explosion_radius:self.remove=Trueself.decay()self.trail_update()self.life+=1defshow(self,win):pygame.draw.circle(win,(self.colour[0],self.colour[1],self.colour[2],0),(int(self.pos.x),int(self.pos.y)),self.size)defdecay(self):if50>self.life>10:ran=randint(0,30)ifran==0:self.remove=Trueelifself.life>50:ran=randint(0,5)ifran==0:self.remove=Truedeftrail_update(self):self.prev_posx.pop()self.prev_posx.insert(0,int(self.pos.x))self.prev_posy.pop()self.prev_posy.insert(0,int(self.pos.y))forn,tinenumerate(self.trails):ift.dynamic:t.get_pos(self.prev_posx[n+dynamic_offset],self.prev_posy[n+dynamic_offset])else:t.get_pos(self.prev_posx[n+static_offset],self.prev_posy[n+static_offset])classTrail:def__init__(self,n,size,dynamic):self.pos_in_line=nself.pos=vector(-10,-10)self.dynamic=dynamicifself.dynamic:self.colour=trail_colours[n]self.size=int(size-n/2)else:self.colour=(255,255,200)self.size=size-2ifself.size
|
|