page contents

python制作一个会动的爱心代码编程

本文讲述了python制作一个会动的爱心代码编程,具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2023-02-7Zv8myer63e44e4a30c6f.jpg本文讲述了python制作一个会动的爱心代码编程,具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2023-02-CBnM9PLA63e44dd897bfb.jpgPython跳动爱心:

涉及到了不少数学知识,需定义曲线函数,然后去调整爱心跳动周期。

源代码如下,感兴趣的小伙伴可以去试试。

可玩的东西还是挺多的,比如改变颜色,添加字幕,打包成exe,然后发给别人。

import random

from math import sin, cos, pi, log

from tkinter import *

 

CANVAS_WIDTH = 640  # 画布的宽

CANVAS_HEIGHT = 480  # 画布的高

CANVAS_CENTER_X = CANVAS_WIDTH / 2  # 画布中心的X轴坐标

CANVAS_CENTER_Y = CANVAS_HEIGHT / 2  # 画布中心的Y轴坐标

IMAGE_ENLARGE = 11  # 放大比例

HEART_COLOR = "#ff2121"  # 心的颜色,这个是中国红

 

 

def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):

    """

    “爱心函数生成器”

    :param shrink_ratio: 放大比例

    :param t: 参数

    :return: 坐标

    """

    # 基础函数

    x = 16 * (sin(t) ** 3)

    y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t))

 

    # 放大

    x *= shrink_ratio

    y *= shrink_ratio

 

    # 移到画布中央

    x += CANVAS_CENTER_X

    y += CANVAS_CENTER_Y

 

    return int(x), int(y)

 

 

def scatter_inside(x, y, beta=0.15):

    """

    随机内部扩散

    :param x: 原x

    :param y: 原y

    :param beta: 强度

    :return: 新坐标

    """

    ratio_x = - beta * log(random.random())

    ratio_y = - beta * log(random.random())

 

    dx = ratio_x * (x - CANVAS_CENTER_X)

    dy = ratio_y * (y - CANVAS_CENTER_Y)

 

    return x - dx, y - dy

 

 

def shrink(x, y, ratio):

    """

    抖动

    :param x: 原x

    :param y: 原y

    :param ratio: 比例

    :return: 新坐标

    """

    force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6)  # 这个参数...

    dx = ratio * force * (x - CANVAS_CENTER_X)

    dy = ratio * force * (y - CANVAS_CENTER_Y)

    return x - dx, y - dy

 

 

def curve(p):

    """

    自定义曲线函数,调整跳动周期

    :param p: 参数

    :return: 正弦

    """

    # 可以尝试换其他的动态函数,达到更有力量的效果(贝塞尔?)

    return 2 * (2 * sin(4 * p)) / (2 * pi)

 

 

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 - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520)  # 魔法参数

 

        dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-1, 1)

        dy = ratio * force * (y - CANVAS_CENTER_Y) + 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=HEART_COLOR)

 

 

def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):

    render_canvas.delete('all')

    render_heart.render(render_canvas, render_frame)

    main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)

 

 

if __name__ == '__main__':

    root = Tk()  # 一个Tk

    canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)

    canvas.pack()

    heart = Heart()  # 心

    draw(root, canvas, heart)  # 开始画画~

    root.mainloop()

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2023-02-09 09:37
  • 阅读 ( 798 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
王昭君
王昭君

209 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章