• 情人节---快来学习一下程序员的专属浪漫吧


    七夕来袭!是时候展现专属于程序员的浪漫了!你打算怎么给心爱的人表达爱意?鲜花礼物?代码表白?还是创意DIY?或者…无论那种形式,快来秀我们一脸吧!

    让我们一起记忆这美好的今天,愿我们年年有今日,岁岁有今朝。祝天下的情人终成眷属。

    程序员🐒的浪漫

    很多人说工科生不懂浪漫,程序员就更别提了,铁男一枚,钢铁大直男,可程序员其实也是动得浪漫🌹的。

    下面我们用python写出我们程序员的浪漫吧!以程序员的方式撒狗粮,专业浪漫,值得拥有!

    • 效果演示

    • 制作步骤/过程

    这个动态效果是由 Tkinter库来完成的,属于Python的GUI编程部分。Python提供了多个图形开发界面的库,常用的有TkinterxwPythonJythonTkinter是Python的标准GUI库,内置在Python中,不需要额外安装,对于一些简单的图形界面可以轻松实现。

    下面是七夕节烟花效果的代码实现,首先导入所有需要的库:

    • Tkinter:最终的GUI实现;
    • PIL:处理图像,在最后画布背景中使用;
    • time:处理时间,完成时间生命周期的更新迭代;
    • random:随机产生数字,定义燃放过程中的随机变量;
    • math:数学函数方法,计算燃放移动使用;

    然后定义一个通用的烟花颗粒的类(part),烟花颗粒的属性如下:

    • id:每个烟花中颗粒的标识;
    • x, y: 烟花的x,y轴;
    • vx, vy:在x,y轴中颗粒的速度;
    • total:每个烟花的颗粒数量;
    • age:颗粒已经在背景度过的时间;
    • color:颜色;
    • cv:背景;
    • lifespan:颗粒将在背景持续多久;

    然后在这个类中定义了烟花颗粒的一些类方法:

    • update:通过判断颗粒状态更新颗粒的生命时间;
    • expand:定义爆炸的时间;
    • alive:检查颗粒在生命周期内是否还存在;
    1. # 设置重力参数
    2. GRAVITY = 0.05
    3. # 设置随机的颜色列表
    4. colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue']
    5. class part:
    6. def __init__(self, cv, idx, total, explosion_speed, x=0., y=0., vx=0., vy=0., size=2., color='red', lifespan=2,
    7. **kwargs):
    8. self.id = idx
    9. self.x = x
    10. self.y = y
    11. self.initial_speed = explosion_speed
    12. self.vx = vx
    13. self.vy = vy
    14. self.total = total
    15. self.age = 0
    16. self.color = color
    17. self.cv = cv
    18. self.cid = self.cv.create_oval(
    19. x - size, y - size, x + size,
    20. y + size, fill=self.color)
    21. self.lifespan = lifespan
    22. def update(self, dt):
    23. self.age += dt
    24. # 颗粒爆炸
    25. if self.alive() and self.expand():
    26. move_x = cos(radians(self.id * 360 / self.total)) * self.initial_speed
    27. move_y = sin(radians(self.id * 360 / self.total)) * self.initial_speed
    28. self.cv.move(self.cid, move_x, move_y)
    29. self.vx = move_x / (float(dt) * 1000)
    30. # 颗粒降落
    31. elif self.alive():
    32. move_x = cos(radians(self.id * 360 / self.total))
    33. self.cv.move(self.cid, self.vx + move_x, self.vy + GRAVITY * dt)
    34. self.vy += GRAVITY * dt
    35. # 如果颗超过最长持续时间,颗粒消失
    36. elif self.cid is not None:
    37. cv.delete(self.cid)
    38. self.cid = None
    39. # 定义爆炸的时间
    40. def expand(self):
    41. return self.age <= 1.2
    42. # 检查颗粒在生命周内是否还存在
    43. def alive(self):
    44. return self.age <= self.lifespan

    上面完成了一个通用的烟花颗粒类的实现,下面就开始烟花燃放的模拟循环过程:通过递归不断循地在背景中产生新的烟花。

    首先定义一个 simulate 模拟的函数,在函数中定了一些参数:

    • t:时间戳;
    • explode_points:烟花爆炸点列表,供后续更新使用;
    • num_explore:随机的烟花数量;

    然后在所有的烟花数量中循环创建所有的烟花颗粒类,当然在每次循环中颗粒类都需要设置一定的属性参数,参数多是随机产生:

    • objects:存放所有的颗粒对象;
    • x_cordi,y_cordi:随机产生烟花在背景中的x,y坐标位置(50,550);
    • speed:随机产生颗粒移动速度(0.5,1.5);
    • size:随机产生颗粒大小(0.5,3);
    • color:选择颜色随机列表中的颜色;
    • total_particles:随机产生每个烟花中所有颗粒的数量;

    有了这些参数,我们就可以定义循环产生每个颗粒对象了,并将每个烟花的所有颗粒对象储存在objects中。也就是说explore_points是列表中套列表,内层列表是每个烟花的所有颗粒对象,外层列表是所有烟花。

    所有的颗粒对象完成后,就开始对每个颗粒的生命时间进行更新,且总时间设定在1.8秒以内。最后通过root递归使烟花可以一直在背景中燃放。

    1. def simulate(cv):
    2. t = time()
    3. explode_points = []
    4. wait_time = randint(10, 100)
    5. numb_explode = randint(6, 10)
    6. # 循环创建所有的烟花颗粒
    7. for point in range(numb_explode):
    8. objects = []
    9. x_cordi = randint(50, 550)
    10. y_cordi = randint(50, 150)
    11. speed = uniform(0.5, 1.5)
    12. size = uniform(0.5, 3)
    13. color = choice(colors)
    14. explosion_speed = uniform(0.2, 1)
    15. total_particles = randint(10, 50)
    16. for i in range(1, total_particles):
    17. r = part(cv, idx=i, total=total_particles, explosion_speed=explosion_speed, x=x_cordi, y=y_cordi,
    18. vx=speed, vy=speed, color=color, size=size, lifespan=uniform(0.6, 1.75))
    19. objects.append(r)
    20. explode_points.append(objects)
    21. total_time = .0
    22. # 保持在1.8秒内进行更新
    23. while total_time < 1.8:
    24. sleep(0.01)
    25. tnew = time()
    26. t, dt = tnew, tnew - t
    27. for point in explode_points:
    28. for item in point:
    29. item.update(dt)
    30. cv.update()
    31. total_time += dt
    32. # 通过递归持续不断的在背景中添加新烟花
    33. root.after(wait_time, simulate, cv)
    34. def close(*ignore):
    35. """停止模拟循环,关闭窗口"""
    36. global root
    37. root.quit()

    以上代码部分均与Tkinter无关,只是定义了颗粒对象以及模拟颗粒生命周期的全过程,下面将使用Tkinter完成最终的效果。

    • root:Tkinter类的对象;
    • cv:定义了Tkinter中背景画布对象,其中height和width参数可根据实际进行调整;
    • image:打开的图像对象,图像将被作为画布中的背景,图像可根据自己喜好自行选择;
    • photo:使用ImageTk定义了Tkinter中的图像对象;

    然后将在画布对象上创建一个图像(使用定义的photo对象作为参数),最后调用Tkinter对象root进行持续不断地simulate模拟过程。

    1. if __name__ == '__main__':
    2. root = tk.Tk()
    3. cv = tk.Canvas(root, height=600, width=600)
    4. # 自己选择一个好的图像背景填充画布
    5. image = Image.open("image.jpg")
    6. photo = ImageTk.PhotoImage(image)
    7. cv.create_image(0, 0, image=photo, anchor='nw')
    8. cv.pack()
    9. root.protocol("WM_DELETE_WINDOW", close)
    10. root.after(100, simulate, cv)
    11. root.mainloop()

    联系我获取完整代码 ,祝君开心度过一个美好浪漫的情人节

    注意:背景图片可根据自己的喜好进行更换,还不赶紧定制一个属于自己的烟花秀?

    完整代码可以到下面的链接中下载

    程序员们的七夕浪漫礼物,请查收-Python文档类资源-CSDN下载 

  • 相关阅读:
    java高级用法之:JNA中的Structure
    场景交互与场景漫游-场景漫游器(6)
    创建域名邮箱邮件地址的方法与步骤
    M1 Pro MacBook Pro下载Android11源码
    一款适用于勒索病毒应急演练加解密工具
    程序的编译,链接,执行
    2022 APMCM亚太数学建模竞赛 C题 全球是否变暖 问题二python代码实现(更新完毕)
    通俗易懂讲解Redis的哨兵模式
    Haproxy实现负载均衡
    Go编译原理系列10(逃逸分析)
  • 原文地址:https://blog.csdn.net/qq_29235677/article/details/126152705