Python Pygame如何制作雪夜烟花景
导读:本文共6821.5字符,通常情况下阅读需要23分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 运行截图运行效果:什么?你说你看不清烟花?那我换一种颜色,请点开看。实现过程准备工作使用语言和框架:python、pygame。安装pygame:pipinstall-ihttps://pypi.tuna.tsinghua.edu.cn/simple/--trusted-hostpypi.tuna.tsinghua.edu.cnpygame你需要知道的基础知识首... ...
目录
(为您整理了一些要点),点击可以直达。运行截图
运行效果:
什么?你说你看不清烟花?那我换一种颜色,请点开看。
实现过程
准备工作
使用语言和框架:python、pygame。
安装pygame:
pipinstall-ihttps://pypi.tuna.tsinghua.edu.cn/simple/--trusted-hostpypi.tuna.tsinghua.edu.cnpygame
你需要知道的基础知识
首先,pygame渲染是同步的,所以同屏渲染的点过多之后,就会造成卡顿的情况。
其次,pygame的代码逻辑是,周期性渲染一系列的屏,从而产生连续的动画。
你需要掌握的框架基础知识:
初始化过程
importpygamepygame.init()pygame.mixer.init()pygame.font.init()
获取字体
myfont=pygame.font.SysFont('simHei',30)textsurface=myfont.render(a[i],False,random_color(150,255))screen.blit(textsurface,(80,30))
画圈
pygame.draw.circle(screen,(snow_list[i][4],snow_list[i][5],snow_list[i][6]),snow_list[i][:2],snow_list[i][3]-3)
加载背景音乐
screen=pygame.display.set_mode(bg_size)pygame.display.set_caption("新年快乐")bg=pygame.image.load(bg_img)pygame.mixer.music.load('D:\\CloudMusic\\小时姑娘-霞光-《精灵世纪》片尾曲.mp3')
核心代码
基础架子
首先,需要实现一个基础的事件循环的架子,如下:
defmain():globalshow_nglobalfk_listbg_size=(WIN_W,WIN_H)screen=pygame.display.set_mode(bg_size)pygame.display.set_caption("新年快乐")pygame.mixer.music.load('D:\\CloudMusic\\小时姑娘-霞光-《精灵世纪》片尾曲.mp3')font_values=['新年快乐']grand_has=set()clock=pygame.time.Clock()whileTrue:ifnotpygame.mixer.music.get_busy():pygame.mixer.music.play()foreventinpygame.event.get():ifevent.type==pygame.QUIT:exit()screen.fill((0,0,0))......pygame.display.update()time_passed=clock.tick(50)if__name__=='__main__':main()
下雪的过程
现在,需要实现下雪的过程,首先,考虑定义定义一堆初始化的下雪点
definit_xue(bg_size):snow_list=[]foriinrange(200):x_site=random.randrange(0,bg_size[0])#雪花圆心位置y_site=random.randrange(0,bg_size[1])#雪花圆心位置X_shift=random.randint(-1,1)#x轴偏移量radius=random.randint(4,6)#半径和y周下降量xxxxx=random_color(150,255)snow_list.append([x_site,y_site,X_shift,radius,255,255,255])returnsnow_list
然后实现渲染雪的过程
defdraw_xue(snow_list:[],screen,bg_size:[],grand_has:set,grand_list:[]):#雪花列表循环#todo空中的雪foriinrange(len(snow_list)):#绘制雪花,颜色、位置、大小pygame.draw.circle(screen,(snow_list[i][4],snow_list[i][5],snow_list[i][6]),snow_list[i][:2],snow_list[i][3]-3)#移动雪花位置(下一次循环起效)snow_list[i][0]+=snow_list[i][2]snow_list[i][1]+=snow_list[i][3]#如果雪花落出屏幕,重设位置ifsnow_list[i][1]>bg_size[1]:#tmp=[]snow_list[i][1]=random.randrange(-50,-10)snow_list[i][0]=random.randrange(0,bg_size[0])x=snow_list[i][0]y=bg_size[1]while(grand_has.__contains__(x*10000+y)):y=y-snow_list[i][3]grand_has.add(x*10000+y)grand_list.append([x,y,snow_list[i][2],snow_list[i][3],snow_list[i][4],snow_list[i][5],snow_list[i][6]])
集成到上面的架子中,效果如下:
不过目前的下雪没有质感,可以考虑在底部堆一些雪,只需要在雪落到地上做特判即可。
雪落到地上堆起来的过程
在前面的下雪过程的代码中,我们维护了一个Grand_list的数组,目的就是维护堆雪的效果
min_height=100000#todo地上的积雪foriinrange(len(grand_list)):ifgrand_list[i][0]<375:min_height=min(min_height,grand_list[i][1])
然后进入维护程序:
draw_xue(snow_list,screen,bg_size,grand_has,grand_list)
最后再将雪画出来
foriinrange(len(grand_list)):pygame.draw.circle(screen,(grand_list[i][4],grand_list[i][5],grand_list[i][6]),grand_list[i][:2],grand_list[i][3]-3)
效果图如上。
实现烟花的过程
首先定义出烟花类:
classFireworks():is_show=Falsex,y=0,0vy=0p_list=[]color=[0,0,0]v=0def__init__(self,x,y,vy,n=300,color=[0,255,0],v=10):self.x=xself.y=yself.vy=vyself.color=colorself.v=vforiinrange(n):self.p_list.append([random.random()*2*math.pi,0,v*math.pow(random.random(),1/3)])defrun(self):globalshow_nforpinself.p_list:p[1]=p[1]+(random.random()*0.6+0.7)*p[2]p[2]=p[2]*0.97ifp[2]<1.2:self.color[0]*=0.9999self.color[1]*=0.9999self.color[2]*=0.9999ifmax(self.color)<10orself.y>WIN_H+p[1]:show_n-=1self.is_show=Falsebreakself.vy+=10*t1self.y+=self.vy*t1
然后,我们需要画出烟花释放前上升的过程点,这部分与下雪的初始化差不多。
definit_yanhua(bg_size):yanhua_list=[]foriinrange(5):x_site=random.randrange(0,WIN_W)#雪花圆心位置y_site=WIN_H#雪花圆心位置X_shift=0#x轴偏移量radius=random.randint(6,10)#半径和y周上升降量xxxxx=random_color(150,255)red=xxxxx[0]green=xxxxx[1]blue=xxxxx[2]yanhua_list.append([x_site,y_site,X_shift,radius,red,green,blue])returnyanhua_list
然后是画上升过程
defdraw_yanhua(yanhua_list:[],screen,bg_size:[]):globalfk_listforiinrange(len(yanhua_list)):#绘制雪花,颜色、位置、大小pygame.draw.circle(screen,(yanhua_list[i][4],yanhua_list[i][5],yanhua_list[i][6]),yanhua_list[i][:2],yanhua_list[i][3]-3)yanhua_list[i][0]+=yanhua_list[i][2]yanhua_list[i][1]-=yanhua_list[i][3]ifyanhua_list[i][1]<=0:#tmp=[]yanhua_list[i][1]=WIN_Hyanhua_list[i][0]=random.randrange(0,bg_size[0])ifyanhua_list[i][1]<=random.randint(200,400):#todo放烟花fk=Fireworks(yanhua_list[i][0],yanhua_list[i][1],-20,n=300,color=red_random(1,150),v=10)fk_list.append(fk)yanhua_list[i][1]=WIN_Hyanhua_list[i][0]=random.randrange(0,bg_size[0])
效果图如下:
圈出来的就是上升过程的烟花。
最后就是绽放部分,其实在上升过程的代码中有维护,如果超过某个随机高度,就会生成一个烟花,只是没有渲染,现在我们把渲染加上。
forfkinfk_list:fk.run()forpinfk.p_list:x,y=fk.x+p[1]*math.cos(p[0]),fk.y+p[1]*math.sin(p[0])ifrandom.random()<0.055:screen.set_at((int(x),int(y)),(255,255,255))else:screen.set_at((int(x),int(y)),(int(fk.color[0]),int(fk.color[1]),int(fk.color[2])))tmp=[]forfkinfk_list:forpinfk.p_list:x,y=fk.x+p[1]*math.cos(p[0]),fk.y+p[1]*math.sin(p[0])ify<WIN_H-1000:tmp.append(fk)breakfk_list=tmp
最终的运行效果就如最顶上的效果一样。
完整代码
将上述过程进行组合,结果如下,感兴趣的朋友可以按自己的需求进行优化。
importpygameimportrandomimportmathpygame.init()pygame.mixer.init()pygame.font.init()WIN_W=2200WIN_H=1300t1=0.18#时间流速show_n=0show_frequency=0.0015#烟花绽放频率,数值越大频率越高color_list=[[255,0,0]]yanhua_map={}fk_list=[]classFireworks():is_show=Falsex,y=0,0vy=0p_list=[]color=[0,0,0]v=0def__init__(self,x,y,vy,n=300,color=[0,255,0],v=10):self.x=xself.y=yself.vy=vyself.color=colorself.v=vforiinrange(n):self.p_list.append([random.random()*2*math.pi,0,v*math.pow(random.random(),1/3)])defrun(self):globalshow_nforpinself.p_list:p[1]=p[1]+(random.random()*0.6+0.7)*p[2]p[2]=p[2]*0.97ifp[2]<1.2:self.color[0]*=0.9999self.color[1]*=0.9999self.color[2]*=0.9999ifmax(self.color)<10orself.y>WIN_H+p[1]:show_n-=1self.is_show=Falsebreakself.vy+=10*t1self.y+=self.vy*t1defrandom_color(l,r):return[random.randint(l,r),random.randint(l,r),random.randint(l,r)]defred_random(l,r):return[255,random.randint(l,r),random.randint(l,r)]definit_yanhua(bg_size):yanhua_list=[]foriinrange(5):x_site=random.randrange(0,WIN_W)#雪花圆心位置y_site=WIN_H#雪花圆心位置X_shift=0#x轴偏移量radius=random.randint(6,10)#半径和y周上升降量xxxxx=random_color(150,255)red=xxxxx[0]green=xxxxx[1]blue=xxxxx[2]yanhua_list.append([x_site,y_site,X_shift,radius,red,green,blue])returnyanhua_listdefinit_xue(bg_size):snow_list=[]foriinrange(200):x_site=random.randrange(0,bg_size[0])#雪花圆心位置y_site=random.randrange(0,bg_size[1])#雪花圆心位置X_shift=random.randint(-1,1)#x轴偏移量radius=random.randint(4,6)#半径和y周下降量xxxxx=random_color(150,255)#red=xxxxx[0]#green=xxxxx[1]#blue=xxxxx[2]snow_list.append([x_site,y_site,X_shift,radius,255,255,255])returnsnow_listdefdraw_xue(snow_list:[],screen,bg_size:[],grand_has:set,grand_list:[]):#雪花列表循环#todo空中的雪foriinrange(len(snow_list)):#绘制雪花,颜色、位置、大小pygame.draw.circle(screen,(snow_list[i][4],snow_list[i][5],snow_list[i][6]),snow_list[i][:2],snow_list[i][3]-3)#移动雪花位置(下一次循环起效)snow_list[i][0]+=snow_list[i][2]snow_list[i][1]+=snow_list[i][3]#如果雪花落出屏幕,重设位置ifsnow_list[i][1]>bg_size[1]:#tmp=[]snow_list[i][1]=random.randrange(-50,-10)snow_list[i][0]=random.randrange(0,bg_size[0])x=snow_list[i][0]y=bg_size[1]while(grand_has.__contains__(x*10000+y)):y=y-snow_list[i][3]grand_has.add(x*10000+y)grand_list.append([x,y,snow_list[i][2],snow_list[i][3],snow_list[i][4],snow_list[i][5],snow_list[i][6]])defdraw_yanhua(yanhua_list:[],screen,bg_size:[]):globalfk_listforiinrange(len(yanhua_list)):#绘制雪花,颜色、位置、大小pygame.draw.circle(screen,(yanhua_list[i][4],yanhua_list[i][5],yanhua_list[i][6]),yanhua_list[i][:2],yanhua_list[i][3]-3)#移动雪花位置(下一次循环起效)yanhua_list[i][0]+=yanhua_list[i][2]yanhua_list[i][1]-=yanhua_list[i][3]#如果雪花落出屏幕,重设位置ifyanhua_list[i][1]<=0:#tmp=[]yanhua_list[i][1]=WIN_Hyanhua_list[i][0]=random.randrange(0,bg_size[0])ifyanhua_list[i][1]<=random.randint(200,400):#todo放烟花fk=Fireworks(yanhua_list[i][0],yanhua_list[i][1],-20,n=300,color=red_random(1,150),v=10)fk_list.append(fk)yanhua_list[i][1]=WIN_Hyanhua_list[i][0]=random.randrange(0,bg_size[0])defshow_shi(a:list,n,screen):i=2*n-1j=2*nifi>=len(a):i=len(a)-2j=len(a)-1ifi>=0:myfont=pygame.font.SysFont('simHei',30)textsurface=myfont.render(a[i],False,random_color(150,255))screen.blit(textsurface,(WIN_W/2,30))ifj>=0:myfont=pygame.font.SysFont('simHei',100)textsurface=myfont.render(a[j],False,red_random(1,1))screen.blit(textsurface,(WIN_W/2-200,50))defmain():globalshow_nglobalfk_listbg_size=(WIN_W,WIN_H)screen=pygame.display.set_mode(bg_size)#bg_img="./1.png"pygame.display.set_caption("新年快乐")#bg=pygame.image.load(bg_img)pygame.mixer.music.load('D:\\CloudMusic\\小时姑娘-霞光-《精灵世纪》片尾曲.mp3')grand_list=[]font_values=['新年快乐']grand_has=set()clock=pygame.time.Clock()yanhua_list=init_yanhua(bg_size)snow_list=init_xue(bg_size)#游戏主循环whileTrue:ifnotpygame.mixer.music.get_busy():pygame.mixer.music.play()foreventinpygame.event.get():ifevent.type==pygame.QUIT:exit()screen.fill((0,0,0))draw_yanhua(yanhua_list,screen,bg_size)iflen(fk_list)!=0:print(len(fk_list))##放烟花show_shi(font_values,0,screen)forfkinfk_list:fk.run()forpinfk.p_list:x,y=fk.x+p[1]*math.cos(p[0]),fk.y+p[1]*math.sin(p[0])ifrandom.random()<0.055:screen.set_at((int(x),int(y)),(255,255,255))else:screen.set_at((int(x),int(y)),(int(fk.color[0]),int(fk.color[1]),int(fk.color[2])))tmp=[]forfkinfk_list:forpinfk.p_list:x,y=fk.x+p[1]*math.cos(p[0]),fk.y+p[1]*math.sin(p[0])ify<WIN_H-1000:tmp.append(fk)breakfk_list=tmpmin_height=100000#todo地上的积雪foriinrange(len(grand_list)):ifgrand_list[i][0]<375:min_height=min(min_height,grand_list[i][1])draw_xue(snow_list,screen,bg_size,grand_has,grand_list)foriinrange(len(grand_list)):pygame.draw.circle(screen,(grand_list[i][4],grand_list[i][5],grand_list[i][6]),grand_list[i][:2],grand_list[i][3]-3)pygame.display.update()time_passed=clock.tick(50)if__name__=='__main__':main()
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
Python Pygame如何制作雪夜烟花景的详细内容,希望对您有所帮助,信息来源于网络。