源代码如下(遇上篇烟花代码几乎一样,参数值稍微不一样):

  1. # -*- coding: utf-8 -*-
  2. # Nola
  3.  
  4. import tkinter as tk
  5. from PIL import Image, ImageTk
  6. from time import time, sleep
  7. from random import choice, uniform,randint
  8. from math import sin, cos, radians
  9.  
  10. # # 初始化tkinter 创建根部件 必须在创建其他部件之前创建 且只有一个
  11. # root = tk.Tk()
  12. # # Label部件
  13. # w = tk.Label(root, text="Hello Tkinter!")
  14. # # pack告诉tkinter调整窗口大小适应所用的小部件
  15. # w.pack()
  16. # root.mainloop()
  17. # 模拟重力
  18. GRAVITY = 0.05
  19. colors = ['red', 'blue', 'pink', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue']
  20.  
  21. class Part(object):
  22. """
  23. particles 类
  24. 粒子在空中随机生成,变成一个圈,下坠,消失
  25. """
  26. def __init__(self, cv, idx, total, explosion_speed, x=0., y=0., vx=0., vy=0., size=2., color='red', lifespan=2, **kwargs):
  27. """
  28. :param cv: 画布
  29. :param idx: 粒子的id
  30. :param total: 总数
  31. :param explosion_speed: 粒子初始速度
  32. :param x: 粒子的横坐标
  33. :param y: 粒子的纵坐标
  34. :param vx: 粒子在x轴上的变化速度
  35. :param vy: 粒子在y轴上的变化速度
  36. :param size: 大小
  37. :param color: 颜色
  38. :param lifespan: 最高存在时长
  39. :param kwargs:
  40. """
  41. self.id = idx
  42. self.x = x
  43. self.y = y
  44. self.initial_speed = explosion_speed
  45. self.vx = vx
  46. self.vy = vy
  47. self.total = total
  48. self.age = 0
  49. self.color = color
  50. self.cv = cv
  51. self.cid = self.cv.create_oval(
  52. x - size, y - size, x + size,
  53. y + size, fill=self.color
  54. )
  55. self.lifespan = lifespan
  56.  
  57. def update(self, dt):
  58. """
  59. 粒子运动函数,膨胀
  60. :param dt:
  61. :return:
  62. """
  63. self.age += dt
  64. if self.alive() and self.expand():
  65. move_x = cos(radians(self.id*360 / self.total)) * self.initial_speed
  66. move_y = sin(radians(self.id*360 / self.total)) * self.initial_speed
  67. # self.vy = move_y / (float(dt)*1000)
  68. self.cv.move(self.cid, move_x, move_y)
  69. self.vx = move_x / (float(dt) * 1000)
  70.  
  71. # 以自由落体坠落
  72. elif self.alive():
  73. move_x = cos(radians(self.id*360 / self.total))
  74. self.cv.move(self.cid, self.vx + move_x, self.vy + GRAVITY*dt)
  75. self.vy += GRAVITY * dt
  76.  
  77. # 移除超过最高时长的粒子
  78. elif self.cid is not None:
  79. self.cv.delete(self.cid)
  80. self.cid = None
  81.  
  82. def alive(self):
  83. """
  84. 检查粒子是否在最高存在时长内
  85. :return: bool
  86. """
  87. return self.age <= 1.2
  88.  
  89. def expand(self):
  90. """
  91. 定义膨胀效果时间帧
  92. :return: bool
  93. """
  94. return self.age <= self.lifespan
  95.  
  96. def simulate(cv):
  97. """
  98. 循环调用保持不停
  99. :param cv: 画布
  100. :return:
  101. """
  102. numb_explode = randint(6, 10)
  103. wait_time = randint(10, 100)
  104. explode_points = []
  105. t = time()
  106. # 为所有模拟烟花绽放的全部粒子创建一个列表
  107. for point in range(numb_explode):
  108. objects = []
  109. x_cordi = randint(50, 550)
  110. y_cordi = randint(50, 150)
  111. speed = uniform(0.5, 1.5)
  112. size = uniform(1, 3) # 随机生成一个0.5-3之间的实数
  113. color = choice(colors)
  114. explosion_speed = uniform(0.2, 1)
  115. total_particals = randint(5, 50)
  116. for i in range(1, total_particals):
  117. r = Part(cv, idx=1, total=total_particals, explosion_speed=explosion_speed, x=x_cordi, y=y_cordi,
  118. vx=speed, vy=speed ,color=color, size=size, lifespan=uniform(0.6,1.75))
  119. objects.append(r)
  120. explode_points.append(objects)
  121.  
  122. # 设置每个粒子没0.01秒更新状态 生命周期1.8秒 1.6秒存活(1.2秒绽放,0.4秒坠落,0.2秒移除)
  123. total_time = .0
  124. # 在1.8秒时间帧内保持更新
  125. while total_time < 1.8:
  126. sleep(0.01)
  127. tnew = time()
  128. t, dt = tnew, tnew - t
  129. for point in explode_points:
  130. for item in point:
  131. item.update(dt)
  132. cv.update()
  133. total_time += dt
  134. # 循环调用
  135. root.after(wait_time, simulate, cv)
  136.  
  137. def close(*ignore):
  138. """
  139. 退出程序,关闭窗口
  140. :param ignore:
  141. :return:
  142. """
  143. global root
  144. root.quit()
  145.  
  146. if __name__ == '__main__':
  147. # 初始化tkinter 创建根部件
  148. root = tk.Tk()
  149.  
  150. cv = tk.Canvas(root, height=400, width=600)
  151. # 绘制一个黑色背景
  152. cv.create_rectangle(0, 0, 600, 600, fill='black')
  153. # 使用背景图片
  154. # image = Image.open('./image.png')
  155. # photo = ImageTk.PhotoImage(image)
  156. # cv.create_image(0, 0, image=photo, anchor='nw')
  157. cv.pack()
  158.  
  159. root.protocol('WM_DELETE_WINDOW', close)
  160. # 1秒后开始条约simulate()
  161. root.after(100, simulate, cv)
  162. root.mainloop()

用python一起来看流星雨的更多相关文章

  1. 基于python2+selenium3+pytest4的UI自动化框架

    环境:Python2.7.10, selenium3.141.0, pytest4.6.6, pytest-html1.22.0, Windows-7-6.1.7601-SP1 特点:- 二次封装了s ...

  2. 夺命雷公狗---DEDECMS----16dedecms取出首页今日更新

    我们这次就要来取出我们的电影和电视剧以及综艺节目: 我们首先在我们受页面的模版文件中获取电影和电视剧的标签: 我们发现这里有一大堆,我只留一个即可: 然后我们到后台更新下首页的模版,看下是否只有一个模 ...

  3. 夺命雷公狗---DEDECMS----13dedecms首页的完成

    我们的dedecms搭建起来后直接复制templets的目录复制一份,如下所示: 然后进入templets目录里面,然后再将default里面的东西都给干掉,然后将我们预先准备好的首页放进来,代码如下 ...

  4. VBA 开发学习--基础语法

    MsgBox "开始学习VBA" '提示框 Dim str As String '声明str变量是string类型 Let str = "一起来看流星雨" '给 ...

  5. 洛谷 P2895 [USACO08FEB]流星雨Meteor Shower 解题报告

    一起来看流星雨吧(话说我还没看到过流星雨呢) 题目 Problem 小A则听说另一个骇人听闻的消息: 一场流星雨即将袭击整个霸中,由于流星体积过大,它们无法在撞击到地面前燃烧殆尽,届时将会对它撞到的一 ...

  6. canvas绘制流星雨特效

    源码: <!DOCTYPE html><html> <head> <meta charset="utf-8"> <meta n ...

  7. 福州11911.562(薇)xiaojie:福州哪里有xiaomei

    福州哪里有小姐服务大保健[微信:11911.562倩儿小妹[福州叫小姐服务√o服务微信:11911.562倩儿小妹[福州叫小姐服务][十微信:11911.562倩儿小妹][福州叫小姐包夜服务][十微信 ...

  8. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  9. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

随机推荐

  1. nghttp2 和nginx的实践

    主要参考https://bg2bkk.github.io/post/HTTP2%E7%9A%84%E5%AE%9E%E8%B7%B5%E8%BF%87%E7%A8%8B/,和https://fangp ...

  2. Unity骨骼动画资源解析与优化

    一,背景 最近发现项目的动画文件有点大,不光内存大,而且文件也很大,所以从这2个方面下手处理 二,动画文件大小优化 为了优化动画文件大小,我们可以先分析下文件,Ctrl+D将动画文件从FBX拷贝出来, ...

  3. 使用 Weinre 调试移动网站

    在 PC 端,我们可以使用 Firebug 或者 Chrome 开发人员工具方便的调试网站或者 Web 应用.但是,当我们想在移动端调试站点或者应用的时候,这些工具就派不上用场了.因此,移动开发人员都 ...

  4. sql 小技巧

    declare @pids varchar(max)='' ),pid)+','+@pids from product where pname like '%red%' select @pids

  5. 记录Js 文本框验证 与 IE兼容性

    最近的日常就是将测试小姐姐提交的bug进行修改,想来这种事情还是比较好开展的,毕竟此项目已上线一年多,现在只是一些前端的问题需要改正.实际上手的时候并不是这样,原项目是在谷歌上运行,后来由于要新增一个 ...

  6. Poj3984 迷宫问题 (BFS + 路径还原)

    Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, ...

  7. P1744 采购特价商品 最短路径

    P1744 采购特价商品 图论-----最短路径算法 弗洛伊德算法  O(n^3) 代码: #include<iostream> #include<cstdio> #inclu ...

  8. 键盘录入一个文件夹路径,统计该文件夹(包含子文件夹)中每种类型的文件及个数,注意:用文件类型(后缀名,不包含.(点),如:"java","txt")作为key, 用个数作为value,放入到map集合中,遍历map集合

    package cn.it.zuoye5; import java.io.File;import java.util.HashMap;import java.util.Iterator;import ...

  9. iOS项目之获取WebView的高度

    获取高度值的方法: - (void)webViewDidFinishLoad:(UIWebView *)webView { // 获取webView的高度 CGFloat webViewHeight ...

  10. 【js】字符串反转可实现的几种方式

    方式1: 这种方式比较简单,推荐使用 字符串转数组,反转数组,数组转字符串. split(""):根据空字符串拆分数组 reverse():数组反转元素位置 join(" ...