python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python turtle流星雨表白程序

Python turtle打造一个浪漫流星雨表白程序

作者:WL_Aurora

本教程详细介绍使用Python标准库turtle和tkinter实现浪漫表白程序,用户点击好哦后88颗随机流星划划过夜空;点击不要弹出提示框;代码简洁易无需第三方包,适合作为Python教学示例,需要的朋友可以参考下

大家好!今天分享一个用 Python 标准库(turtle + tkinter)实现的浪漫表白程序。点击"好哦"后,80颗流星划过夜空,每一颗都是独一无二的随机生成;点击"不要"或关闭窗口?不存在的!这是一个"霸道总裁式"的表白神器

效果预览

程序启动后弹出一个居中窗口,上面写着"亲爱的,做我女朋友好吗?"。两个按钮:“好哦"和"不要”。

流星雨效果:黑色夜空中,80颗蓝白色流星从左上向右下划过,每颗流星形状、大小、速度、颜色各不相同,循环往复……

技术栈

技术说明
turtlePython 内置图形库,绘制流星形状
tkinterPython 内置 GUI 库,弹窗表白界面
random随机生成流星参数
math三角函数计算流星弧度

纯标准库,无需 pip 安装任何第三方包,开箱即用!

项目结构

流星雨表白/
├── 流星雨.py          # 主程序(完整单文件)
└── README.md

核心功能拆解

tkinter 弹窗 —— "霸道总裁"式表白

import tkinter as tk

def love():
    root = tk.Tk()
    root.title('❤')
    root.resizable(0, 0)  # 禁止调整窗口大小
    root.wm_attributes("-toolwindow", 1)  # 隐藏任务栏按钮

    # 计算居中位置
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    widths, heights = 300, 100
    x = (screenwidth - widths) / 2
    y = (screenheight - heights) / 2
    root.geometry('%dx%d+%d+%d' % (widths, heights, x, y))

    # 表白文字
    tk.Label(root, text='亲爱的,做我女朋友好吗?', 
             width=37, font=('宋体', 12)).place(x=0, y=10)

    # 按钮
    tk.Button(root, text='好哦', width=5, height=1, command=OK).place(x=80, y=50)
    tk.Button(root, text='不要', width=5, height=1, command=NO).place(x=160, y=50)

    # 绑定关闭事件
    root.protocol('WM_DELETE_WINDOW', closeWindow)
    root.mainloop()

关键技巧:

技巧代码效果
窗口居中geometry('%dx%d+%d+%d')弹窗出现在屏幕正中央
禁止关闭protocol('WM_DELETE_WINDOW', closeWindow)拦截右上角关闭按钮
隐藏任务栏wm_attributes("-toolwindow", 1)窗口不显示在任务栏
禁止调整resizable(0, 0)窗口大小固定

按钮逻辑:

def OK():
    root.destroy()      # 销毁弹窗
    Meteors()           # 启动流星雨

def NO():
    tk.messagebox.showwarning('❤', '再给你一次机会!')

def closeWindow():
    tk.messagebox.showwarning('❤', '逃避是没有用的哦')

流星形状 —— 数学之美

每颗流星由两段直线 + 一段圆弧组成,形成一个"水滴"或"彗星"形状:

def star(self):
    t.pensize(self.outline)
    t.penup()
    t.goto(self.x, self.y)
    t.pendown()
    t.color(self.color)
    t.begin_fill()
    t.fillcolor(self.color)

    t.setheading(-30)           # 初始朝向:右下 30°
    t.right(self.t)             # 偏转随机角度 t
    t.forward(self.r)           # 前进 r(流星长度)
    t.left(self.t)              # 回正

    # 画圆弧:半径 = r * sin(t°),角度 = 180°
    t.circle(self.r * math.sin(math.radians(self.t)), 180)

    t.left(self.t)
    t.forward(self.r)           # 返回起点
    t.end_fill()

几何分析:

          起点
            \   圆弧(180°)
             \ /
              * —— 顶点
             / \
            /   \
           /     \
          终点   中点

    整体形状:"水滴"或"柳叶"
    偏转角 t 越大,流星越"胖"
    长度 r 越大,流星越长

关键公式:

圆弧半径=r×sin⁡(t°)
其中 t∈[1°,3°],r∈[50,100] 

t 很小时,sin⁡(t°)≈t°×π/180,圆弧接近半圆,流星呈细长水滴状。

流星运动 —— 循环重生

def move(self):
    if self.y >= -500:           # 还在画布内
        self.y -= self.speed     # 向下移动
        self.x += 2 * self.speed # 向右移动(斜率 2:1)
    else:
        # 超出画布,重置参数,从上方重新出现
        self.r = ra.randint(50, 100)
        self.t = ra.randint(1, 3)
        self.x = ra.randint(-2000, 1000)
        self.y = 444
        self.speed = ra.randint(5, 10)
        self.color = ra.choice(colors)

运动轨迹:

屏幕坐标系(turtle):
    y ↑
      │
  999 ├────────── 流星生成区
      │    \    \    \
  444 ├─────\────\────\───
      │      \    \    \
      │       \    \    \
      │        \    \    \
   -500├─────────\────\────\── 消失边界
      │           \    \    \
      └────────────────────────→ x
    -2000                    1000

参数范围:

参数范围作用
r50-100流星长度
t1-3偏转角度(影响胖瘦)
x-2000 ~ 1000初始水平位置
y444 ~ 999初始垂直位置
speed5-10下落速度
colorskyblue/white/cyan/aqua颜色

双缓冲动画 —— 消除闪烁

tu.tracer(0)      # 关闭自动刷新
# ... 绘制所有流星 ...
tu.update()       # 手动刷新一次

原理: tracer(0) 关闭 turtle 的自动渲染,所有绘制操作先在内存中完成,最后调用 update() 一次性显示到屏幕,避免逐帧绘制导致的闪烁。

对比:

模式代码效果
默认无 tracer每步都刷新,严重闪烁
双缓冲tracer(0) + update()批量刷新,流畅无闪烁

颜色主题切换

# 蓝色主题(默认)
colors = ['skyblue', 'white', 'cyan', 'aqua']

# 粉色主题(注释掉的浪漫选项)
# colors = ['pink', 'lightpink', 'deeppink']

只需注释/取消注释即可切换整体色调!

快速开始

步骤 1:直接运行

python 流星雨.py

无需安装任何依赖,Python 内置库即可运行!

步骤 2:自定义表白文字

tk.Label(root, text='这里写你的表白语', width=37, font=('宋体', 12))

步骤 3:调整流星数量

for i in range(100):    # 默认 100 颗,改小更流畅,改大更壮观
    Stars.append(Star())

while True:
    for i in range(100):    # 与上面保持一致
        Stars[i].move()
        Stars[i].star()

步骤 4:调整画布边界

# 流星重生边界
if self.y >= -500:        # 下边界,改小流星飞得更远

# 初始位置范围
self.x = ra.randint(-2000, 1000)   # 水平范围
self.y = ra.randint(444, 999)       # 垂直范围(生成高度)

自定义改造指南

改造 1:添加背景音乐

import pygame

pygame.mixer.init()
pygame.mixer.music.load("romantic.mp3")
pygame.mixer.music.play(-1)  # 循环播放

改造 2:流星拖尾效果

def move(self):
    # 保存历史位置
    self.trail.append((self.x, self.y))
    if len(self.trail) > 5:
        self.trail.pop(0)

    # 绘制拖尾
    for i, (tx, ty) in enumerate(self.trail):
        alpha = i / len(self.trail)
        t.pensize(self.outline * alpha)
        t.goto(tx, ty)

改造 3:添加星星背景

def draw_background():
    t.penup()
    for _ in range(200):
        x = ra.randint(-1000, 1000)
        y = ra.randint(-500, 500)
        t.goto(x, y)
        t.dot(2, 'white')  # 画小星星

改造 4:表白成功后的文字

def OK():
    root.destroy()
    # 显示成功文字
    success = tk.Tk()
    tk.Label(success, text='❤️ 余生请多指教 ❤️', 
             font=('华文行楷', 24), fg='red').pack()
    success.after(2000, Meteors)  # 2秒后进入流星雨
    success.mainloop()

改造 5:多行表白语

messages = [
    '遇见你,是我最美的意外',
    '愿余生与你,星河滚烫',
    '做我女朋友好吗?'
]

for i, msg in enumerate(messages):
    tk.Label(root, text=msg, font=('宋体', 12)).place(x=0, y=10 + i*20)

完整源码

import turtle as tu
import random as ra
import tkinter as tk
import math

def Meteors():
    tu.setup(1.0, 1.0)
    tu.screensize(1.0, 1.0)
    tu.bgcolor('black')
    tu.title("流星雨")
    t = tu.Pen()
    t.hideturtle()
    colors = ['skyblue', 'white', 'cyan', 'aqua']

    class Star():
        def __init__(self):
            self.r = ra.randint(50,100)
            self.t = ra.randint(1,3)
            self.x = ra.randint(-2000,1000)
            self.y = ra.randint(444, 999)
            self.speed = ra.randint(5,10)
            self.color = ra.choice(colors)
            self.outline = 1

        def star(self):
            t.pensize(self.outline)
            t.penup()
            t.goto(self.x,self.y)
            t.pendown()
            t.color(self.color)
            t.begin_fill()
            t.fillcolor(self.color)
            t.setheading(-30)
            t.right(self.t)
            t.forward(self.r)
            t.left(self.t)
            t.circle(self.r*math.sin(math.radians(self.t)),180)
            t.left(self.t)
            t.forward(self.r)
            t.end_fill()

        def move(self):
            if self.y >= -500:
                self.y -= self.speed
                self.x += 2*self.speed
            else:
                self.r = ra.randint(50,100)
                self.t = ra.randint(1,3)
                self.x = ra.randint(-2000,1000)
                self.y = 444
                self.speed = ra.randint(5,10)
                self.color = ra.choice(colors)
                self.outline = 1

    Stars = []
    for i in range(100):
        Stars.append(Star())
    while True:
        tu.tracer(0)
        t.clear()
        for i in range(100):
            Stars[i].move()
            Stars[i].star()
        tu.update()
    tu.mainloop()

def love():
    root = tk.Tk()
    root.title('❤')
    root.resizable(0, 0)
    root.wm_attributes("-toolwindow", 1)
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    widths = 300
    heights = 100
    x = (screenwidth - widths) / 2
    y = (screenheight - heights) / 2
    root.geometry('%dx%d+%d+%d' % (widths, heights, x, y))
    tk.Label(root, text='亲爱的,做我女朋友好吗?', width=37, font=('宋体', 12)).place(x=0, y=10)

    def OK():
        root.destroy()
        Meteors()
    def NO():
        tk.messagebox.showwarning('❤', '再给你一次机会!')
    def closeWindow():
        tk.messagebox.showwarning('❤', '逃避是没有用的哦')

    tk.Button(root, text='好哦', width=5, height=1, command=OK).place(x=80, y=50)
    tk.Button(root, text='不要', width=5, height=1, command=NO).place(x=160, y=50)
    root.protocol('WM_DELETE_WINDOW', closeWindow)
    root.mainloop()

if __name__ == "__main__":
    love()

总结

本项目展示了 Python 标准库的强大表现力:

以上就是Python turtle打造一个浪漫流星雨表白程序的详细内容,更多关于Python turtle流星雨表白程序的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文