【趣味Python】第2课:漫天繁星疯狂闪闪闪

专栏导读

  • 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手

  • 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注

  • 👍 该系列文章专栏:请点击——>Python办公自动化专栏求订阅

  • 🕷 此外还有爬虫专栏:请点击——>Python爬虫基础专栏求订阅

  • 📕 此外还有python基础专栏:请点击——>Python基础学习专栏求订阅

  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏

  • ❤️ 欢迎各位佬关注! ❤️

背景介绍

  • 今天我要带大家用Python制作一个超酷的动画效果——漫天繁星疯狂闪烁!这个程序会生成200个彩色五角星,在黑色背景上随机分布,并且以跳动的动画效果展现,看起来就像夜空中的星星在闪烁一样。

效果预览

  • 运行程序后,你会看到一个黑色窗口,里面布满了彩色的五角星,它们会周期性地放大缩小,创造出一种跳动的视觉效果。星星的颜色随机生成,包括红、橙、黄、绿、蓝、紫、粉、青、品红等多种颜色。

在这里插入图片描述

库的安装

  • tkinter:Python的标准GUI库,用于创建图形界面

  • random:生成随机数,用于星星的随机位置、大小和颜色

  • math:提供数学函数,特别是三角函数用于计算五角星顶点和跳动效果

用途安装
tkinter界面设计pip install tkinter -i https://pypi.tuna.tsinghua.edu.cn/simple/

代码解析

  • 让我们一步步拆解这个动画效果的实现原理。

1. 导入必要的库

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

2. 设置画布参数

  • 定义了画布的宽度和高度,以及中心点坐标。
width = 888
height = 500
center_x = width / 2
center_y = height / 2

3. 颜色和星星数量设置

  • colors:星星可能使用的颜色列表
  • num_stars:生成的星星数量
  • frames:动画帧数,决定动画流畅度
colors = ["red", "orange", "yellow", "green", "blue", "purple", "pink", "cyan", "magenta"]
num_stars = 200
frames = 20

4. 五角星顶点生成函数

  • 这个函数计算五角星的10个顶点坐标(5个外顶点和5个内顶点)。五角星由5个外顶点和5个内顶点交替连接形成。
def star_points(cx, cy, r, rotation=0):
    points = []
    for i in range(5):
        outer_angle = rotation + i * 2 * pi / 5
        inner_angle = outer_angle + pi / 5
        outer_x = cx + r * cos(outer_angle)
        outer_y = cy + r * sin(outer_angle)
        inner_x = cx + r * 0.5 * cos(inner_angle)
        inner_y = cy + r * 0.5 * sin(inner_angle)
        points.extend([outer_x, outer_y, inner_x, inner_y])
    return points

5. 跳动曲线函数

  • 这个函数定义了星星跳动的节奏和幅度,使用正弦函数创造周期性变化效果。
def curve(p):
    return 2 * (2 * sin(4 * p)) / (2 * pi)

6. StarAnimation类

  • 这个类负责管理所有星星的状态和动画。
class StarAnimation:
    def __init__(self, generate_frame=frames):
        self.stars = []
        self.frames = generate_frame
        self.all_star_states = {}

        # 初始化星星
        for _ in range(num_stars):
            star = {
                "x": random.randint(100, width - 100),
                "y": random.randint(100, height - 100),
                "radius": random.randint(8, 18),
                "color": random.choice(colors),
                "rotation": random.uniform(0, 2 * pi),
            }
            self.stars.append(star)

        # 预计算所有帧
        for frame in range(generate_frame):
            self.calc(frame)
  • 构造函数初始化星星列表,为每个星星生成随机的位置、大小、颜色和旋转角度。
def calc(self, frame):
    ratio = 1 + 0.3 * curve(frame / 10 * pi)
    frame_state = []
    for star in self.stars:
        x, y = star["x"], star["y"]
        r = star["radius"] * ratio
        points = star_points(x, y, r, star["rotation"])
        frame_state.append((points, star["color"]))
    self.all_star_states[frame] = frame_state
  • calc方法计算每一帧中所有星星的状态,包括根据跳动曲线调整大小后的顶点坐标。
def render(self, canvas, frame):
    canvas.delete("all")
    stars = self.all_star_states[frame % self.frames]
    for points, color in stars:
        canvas.create_polygon(points, fill=color, outline="black")
  • render方法在画布上绘制指定帧的星星状态。

7. StarApp类

  • 这个类负责创建Tkinter窗口和动画循环。
  • animate方法每80毫秒更新一帧,创建动画效果。
class StarApp:
    def __init__(self, root):
        self.root = root
        self.root.title("跳动的五角星")
        self.canvas = tk.Canvas(root, width=width, height=height, bg="black")
        self.canvas.pack()
        self.star_anim = StarAnimation()
        self.frame = 0
        self.animate()

    def animate(self):
        self.star_anim.render(self.canvas, self.frame)
        self.frame += 1
        self.root.after(80, self.animate)
  1. 主程序
if __name__ == '__main__':
    root = tk.Tk()
    app = StarApp(root)
    root.mainloop()

如何自定义

你可以通过修改以下参数来自定义动画效果:

  • 修改num_stars改变星星数量
  • 修改colors列表改变星星颜色
  • 调整frames改变动画流畅度
  • 修改curve函数改变跳动效果
  • 调整after方法的参数改变动画速度

完整代码

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

width = 888
height = 500
center_x = width / 2
center_y = height / 2

colors = ["red", "orange", "yellow", "green", "blue", "purple", "pink", "cyan", "magenta"]
num_stars = 200
frames = 20

# 生成五角星顶点
def star_points(cx, cy, r, rotation=0):
    points = []
    for i in range(5):
        outer_angle = rotation + i * 2 * pi / 5
        inner_angle = outer_angle + pi / 5
        outer_x = cx + r * cos(outer_angle)
        outer_y = cy + r * sin(outer_angle)
        inner_x = cx + r * 0.5 * cos(inner_angle)
        inner_y = cy + r * 0.5 * sin(inner_angle)
        points.extend([outer_x, outer_y, inner_x, inner_y])
    return points

# 缩放+跳动曲线
def curve(p):
    return 2 * (2 * sin(4 * p)) / (2 * pi)

# 星星类
class StarAnimation:
    def __init__(self, generate_frame=frames):
        self.stars = []
        self.frames = generate_frame
        self.all_star_states = {}

        for _ in range(num_stars):
            star = {
                "x": random.randint(100, width - 100),
                "y": random.randint(100, height - 100),
                "radius": random.randint(8, 18),
                "color": random.choice(colors),
                "rotation": random.uniform(0, 2 * pi),
            }
            self.stars.append(star)

        for frame in range(generate_frame):
            self.calc(frame)

    def calc(self, frame):
        ratio = 1 + 0.3 * curve(frame / 10 * pi)
        frame_state = []
        for star in self.stars:
            x, y = star["x"], star["y"]
            r = star["radius"] * ratio
            points = star_points(x, y, r, star["rotation"])
            frame_state.append((points, star["color"]))
        self.all_star_states[frame] = frame_state

    def render(self, canvas, frame):
        canvas.delete("all")
        stars = self.all_star_states[frame % self.frames]
        for points, color in stars:
            canvas.create_polygon(points, fill=color, outline="black")


# Tkinter 窗口
class StarApp:
    def __init__(self, root):
        self.root = root
        self.root.title("跳动的五角星")
        self.canvas = tk.Canvas(root, width=width, height=height, bg="black")
        self.canvas.pack()
        self.star_anim = StarAnimation()
        self.frame = 0
        self.animate()

    def animate(self):
        self.star_anim.render(self.canvas, self.frame)
        self.frame += 1
        self.root.after(80, self.animate)


if __name__ == '__main__':
    root = tk.Tk()
    app = StarApp(root)
    root.mainloop()

总结

  • 希望对初学者有帮助

  • 致力于办公自动化的小小程序员一枚

  • 希望能得到大家的【一个免费关注】!感谢

  • 求个 🤞 关注 🤞

  • 此外还有办公自动化专栏,欢迎大家订阅:Python办公自动化专栏

  • 求个 ❤️ 喜欢 ❤️

  • 此外还有爬虫专栏,欢迎大家订阅:Python爬虫基础专栏

  • 求个 👍 收藏 👍

  • 此外还有Python基础专栏,欢迎大家订阅:Python基础学习专栏

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小庄-Python办公

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值