当前位置: 首页 > news >正文

Python跳动的爱心

跳动的爱心

系列文章

序号直达链接
Tkinter
1Python李峋同款可写字版跳动的爱心
2Python跳动的双爱心
3Python蓝色跳动的爱心
4Python动漫烟花
5Python粒子烟花
Turtle
1Python满屏飘字
2Python蓝色流星雨
3Python金色流星雨
4Python漂浮爱心
5Python爱心光波①
6Python爱心光波②
7Python满天繁星
8Python五彩气球
9Python白色飘雪
10Python七彩花朵
11Python 3D星空
12Python大雪纷飞
13Python一闪一闪亮星星
14Python爱心泡泡
15Python爱心射线
16Python圣诞礼物
17Python礼物圣诞树
18Python浪漫星空
19Python飞舞蝙蝠
20Python万圣礼物
21Python蓝色飘雪
Pygame
1Python跨年烟花
2Python炫酷烟花
3Python黑客帝国字母雨
敬请期待……

写在前面

Python语言实现蓝色跳动的爱心的完整代码。

技术需求

  1. Tkinter库:用于创建图形用户界面(GUI)应用程序。tkinter是Python内置的库,用于构建窗口、画布和交互组件。在这个代码中,Tk类用于创建主窗口,Canvas类用于绘制图形。

  2. 数学函数和坐标计算

    • 爱心形状的计算:通过数学公式绘制爱心的形状。使用了sincos函数来计算爱心的坐标,并根据参数shrink_ratio来缩放图形的大小。
    • 随机扩散和散点效果:使用了对数函数和随机数生成技术(例如random.uniformrandom.choice)来模拟爱心的边缘扩散和中心扩散效果,使得爱心在每帧渲染时看起来更加动态和生动。
    • 力学模拟:通过力学模型计算坐标的变化,以模拟爱心的扩散和收缩效果。
  3. 图形绘制

    • 点的动态变化:每一帧渲染时,通过更新爱心的坐标,创建一种动态效果,使得爱心不断变化,产生扩散和收缩的效果。
    • 创建矩形:在render方法中,使用create_rectangle方法在画布上绘制矩形,表示爱心的每个点。矩形的大小和位置随着每帧的计算不断变化。
  4. 动画效果:通过main.after()方法,每隔160毫秒更新一次帧,从而实现平滑的动画效果。after方法用于定时调用draw函数,不断地渲染新的一帧,达到动画的效果。

  5. 界面布局

    • 屏幕居中:通过winfo_screenwidth()winfo_screenheight()方法获取屏幕的宽度和高度,再计算窗口的起始位置,使得窗口在屏幕中央显示。
    • 文字显示:使用Label组件在画布上显示文字,并且通过place方法将其定位在窗口的中央。

完整代码

import tkinter as tk
import tkinter.messagebox
import random
from math import sin, cos, pi, log
from tkinter.constants import *

width = 888
height = 500
heartx = width / 2
hearty = height / 2
side = 11
heartcolor = "skyblue"  # 爱心颜色,可修改
word = "I Love You!"  # 想要写的字,可修改


# 爱心类
class Heart:
    def __init__(self, generate_frame=20):
        self._points = set()  # 原始爱心坐标集合
        self._edge_diffusion_points = set()  # 边缘扩散效果点坐标集合
        self._center_diffusion_points = set()  # 中心扩散效果点坐标集合
        self.all_points = {}  # 每帧动态点坐标
        self.build(2000)
        self.random_halo = 1000
        self.generate_frame = generate_frame
        for frame in range(generate_frame):
            self.calc(frame)

    def build(self, number):
        for _ in range(number):
            t = random.uniform(0, 2 * pi)
            x, y = heart_function(t)
            self._points.add((x, y))
        for _x, _y in list(self._points):
            for _ in range(3):
                x, y = scatter_inside(_x, _y, 0.05)
                self._edge_diffusion_points.add((x, y))
        point_list = list(self._points)
        for _ in range(4000):
            x, y = random.choice(point_list)
            x, y = scatter_inside(x, y, 0.17)
            self._center_diffusion_points.add((x, y))

    @staticmethod
    def calc_position(x, y, ratio):
        force = 1 / (((x - heartx) ** 2 + (y - hearty) ** 2) ** 0.520)  # 魔法参数
        dx = ratio * force * (x - heartx) + random.randint(-1, 1)
        dy = ratio * force * (y - hearty) + random.randint(-1, 1)
        return x - dx, y - dy

    def calc(self, generate_frame):
        ratio = 10 * curve(generate_frame / 10 * pi)  # 圆滑的周期的缩放比例
        halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))
        halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * pi) ** 2))
        all_points = []
        heart_halo_point = set()
        for _ in range(halo_number):
            t = random.uniform(0, 2 * pi)
            x, y = heart_function(t, shrink_ratio=11.6)
            x, y = shrink(x, y, halo_radius)
            if (x, y) not in heart_halo_point:
                heart_halo_point.add((x, y))
                x += random.randint(-14, 14)
                y += random.randint(-14, 14)
                size = random.choice((1, 2, 2))
                all_points.append((x, y, size))
        for x, y in self._points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 3)
            all_points.append((x, y, size))
        for x, y in self._edge_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))
        for x, y in self._center_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))
        self.all_points[generate_frame] = all_points

    def render(self, render_canvas, render_frame):
        for x, y, size in self.all_points[render_frame % self.generate_frame]:
            render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=heartcolor)


……

代码分析

这段代码使用了 tkinter 库来创建一个动态的爱心图案,并在屏幕上显示带有动态效果的“我爱你”字样,以下是对这段代码的详细分析。

1. 导入所需的库

  • tkinter 用于创建图形用户界面(GUI)。
  • random 用于生成随机数,主要用于控制爱心图案的扩散效果。
  • math 中的 sincospilog 用于数学计算,生成爱心形状和扩散效果。
  • tkinter.constants 包含了 CENTER 等常量,用于控制控件的对齐方式。

2. 全局变量定义

  • widthheight: 定义画布的大小。
  • heartxhearty: 爱心的中心坐标。
  • side: 用于定义爱心形状的缩放比例。
  • heartcolor: 爱心的颜色。
  • word: 要显示的文本内容。

3. Heart 类的定义

Heart 类是主要的核心,用来生成和管理爱心的坐标点,并计算每一帧的动态效果。

  • 在 __init__ 方法中,build() 方法生成初始的爱心形状的坐标点,calc() 方法计算每一帧的动态效果,generate_frame 控制总的帧数。
  • self._points:存储生成的爱心图案的原始点。
  • self._edge_diffusion_points:存储边缘扩散的点。
  • self._center_diffusion_points:存储中心扩散的点。
  • self.all_points:存储每一帧的所有点,用于动态渲染。

4. build() 方法

  • build 方法用于生成一定数量的爱心坐标点。通过随机选择角度 t,使用 heart_function(t) 计算出坐标 (x, y),并将其加入 _points 集合中。

5. scatter_inside() 和 shrink() 方法

  • scatter_inside(x, y):用于生成坐标点的散布效果,模拟点在爱心内部随机扩散的效果。
  • shrink(x, y):用于将坐标点向爱心的中心收缩,模拟爱心的聚焦效果。

6. calc_position() 方法

  • calc_position(x, y, ratio):根据每一帧的动画计算坐标点的位移,使用一个参数 ratio 来控制动画的流畅度。

7. calc() 方法

  • calc() 方法用于生成每一帧的动态坐标,包含了爱心外部的扩散效果、边缘扩散、中心扩散等效果。通过 random.uniform() 随机生成颜色变化和点的位置。

8. render() 方法

  • render() 方法根据当前帧数 render_frame 渲染出每一帧的爱心图案。通过 create_rectangle() 在画布上绘制一个小矩形来表示每个动态点。

9. heart_function() 方法

  • heart_function(t):生成爱心形状的基本坐标,通过参数 t 控制点的分布,并根据 shrink_ratio 来调整爱心的大小。

10. curve() 方法

  • curve(p):生成一个周期性的曲线函数,用于控制动态效果的平滑度。

11. draw() 方法

  • draw():这是一个递归的函数,每隔 160 毫秒调用一次,用来更新动画的每一帧。

12. love() 主函数

  • love():这是程序的入口函数。它初始化了 Tkinter 窗口,设置了窗口的位置和大小,创建了一个画布(Canvas),然后创建了 Heart 对象,并启动了 draw() 函数进行动画渲染。

这段代码使用了 tkinter 创建一个动画效果,绘制了一个动态的爱心图案,并在其上显示“我爱你”字样。代码的核心部分是 Heart 类,它负责生成和计算爱心的形状和每一帧的动态效果。通过随机散布、扩散、收缩等效果,使得爱心看起来富有动态感和生命力。

写在后面

我是一只有趣的兔子,感谢你的喜欢。 

相关文章:

  • go数据结构笔记
  • Spring(5)——IoC DI
  • DevExpress WinForms 中 SwiftPlot 图表控件的使用指南
  • DeepSeek:技术教育领域的AI变革者——从理论到实践的全面解析
  • 修改 Macbook 终端窗口的显示信息
  • 【算法】用“龟兔赛跑”的思想原地移除元素
  • Go Context包详解与最佳实践
  • Vue学习笔记集--六大指令
  • f-string高级字符串格式化与string Template()
  • NestJS(基于 Express 的现代化框架)
  • coze ai assistant Task 3
  • 主流区块链
  • 人工智能在现代科技中的应用和未来发展趋势。
  • 每日Attention学习27——Patch-based Graph Reasoning
  • 来自腾讯的:《详解DeepSeek:模型训练、优化及数据处理的技术精髓》
  • 3.16学习总结
  • C#开发笔记:INI文件操作
  • 三、重学C++—CPP基础
  • Tsfresh + TA-Lib + LightGBM :A 股市场量化投资策略实战入门
  • Suno的对手Luno:AI音乐开发「上传参考音频 - 方式二:通过URL的方式」 —— 「Luno Api系列|AI音乐API」第12篇
  • 受天气等影响SC8041航班三次备降延误超12小时,山航致歉
  • 奥斯卡新规:评委必须看完影片再投票;网友:以前不是啊?
  • 剑指3000亿产业规模,机器人“武林大会”背后的无锡“野望”
  • 人物|德国新外长关键词:总理忠实盟友、外交防务专家、大西洋主义者
  • 陕西省通报6起违反八项规定典型问题,省卫健委原主任刘宝琴违规收受礼品礼金
  • 欢迎回家!神十九返回舱成功着陆