import tkinter as tk from tkinter import messagebox, simpledialog import time import json import os # 排行榜文件名 LEADERBOARD_FILE = "leaderboard.json" # 读取排行榜数据 def load_leaderboard(): if os.path.exists(LEADERBOARD_FILE): try: with open(LEADERBOARD_FILE, "r", encoding="utf-8") as f: return json.load(f) except: return [] return [] # 保存排行榜数据 def save_leaderboard(): with open(LEADERBOARD_FILE, "w", encoding="utf-8") as f: json.dump(leaderboard, f, ensure_ascii=False, indent=2) # 获取参赛者姓名 def get_player_name(): name = simpledialog.askstring("参赛者姓名", "请输入您的姓名:") if not name: messagebox.showwarning("警告", "姓名不能为空,请重新输入。") return get_player_name() return name # 更新排行榜(同名保留最小误差) def update_leaderboard(name, error): found = False for i, (n, e) in enumerate(leaderboard): if n == name: found = True if abs(error) < e: leaderboard[i] = (name, abs(error)) break if not found: leaderboard.append((name, abs(error))) leaderboard.sort(key=lambda x: x[1]) save_leaderboard() # 写入文件 # 更新显示 rank_listbox.delete(0, tk.END) for i, (n, e) in enumerate(leaderboard[:], 1): rank_listbox.insert(tk.END, f"{i}. {n:<8} 误差: {e:.3f}s") # 更新时间函数 def update_time(): if flag: now = time.time() timex = now - start_time timex_label.config(text=f"⏱ 时间:{timex:.3f} 秒") root.after(10, update_time) def show_win_animation(): anim = tk.Toplevel(root) anim.geometry("320x200") anim.title("🎉 胜利动画") anim.configure(bg="#ffffff") anim.attributes("-topmost", True) # 置顶显示 label = tk.Label(anim, text="🎉 完美掌控时间!🎉", font=("微软雅黑", 18, "bold"), bg="#ffffff") label.pack(expand=True) colors = ["#ff6666", "#66cc66", "#3399ff", "#ffcc00", "#cc66ff"] sizes = [18, 22, 26, 30, 26, 22, 18] def animate(i=0): if i < len(sizes): label.config(font=("微软雅黑", sizes[i], "bold"), fg=colors[i % len(colors)]) anim.after(150, animate, i + 1) else: anim.destroy() animate() # 控制开始/停止 def change(): global flag, start_time if not flag: flag = True start_time = time.time() update_time() else: flag = False end_time = time.time() timex = end_time - start_time error = timex - 10 timex_label.config(text=f"✅ 实际时间:{timex:.3f} 秒\n误差:{error:.3f} 秒") name = get_player_name() update_leaderboard(name, error) if abs(error) < 0.01: show_win_animation() else: messagebox.showinfo("结果", "还差一点点,再接再厉吧!") # ================================ # 主窗口 # ================================ leaderboard = load_leaderboard() root = tk.Tk() root.geometry("340x500") root.title("10秒挑战") root.configure(bg="#f0faff") # 标题 title_label = tk.Label(root, text="🎯 10 秒挑战 🎯", font=("微软雅黑", 18, "bold"), fg="#004466", bg="#f0faff") title_label.pack(pady=15) # 排行榜框 rank_frame = tk.Frame(root, bg="#ffffff", bd=2, relief="groove") rank_frame.pack(pady=10) rank_title = tk.Label(rank_frame, text="🏆 排行榜(误差越小越靠前)", font=("微软雅黑", 10, "bold"), bg="#ffffff", fg="#333333") rank_title.pack(pady=(5, 0)) rank_listbox = tk.Listbox(rank_frame, font=("Courier", 10), height=5, width=35, bg="#f9f9f9") rank_listbox.pack(padx=10, pady=5) # 初始显示排行榜 for i, (n, e) in enumerate(leaderboard[:5], 1): rank_listbox.insert(tk.END, f"{i}. {n:<8} 误差: {e:.3f}s") # 时间标签 timex_label = tk.Label(root, text="点击按钮开始挑战", font=("微软雅黑", 12), bg="#f0faff", fg="#333333") timex_label.pack(pady=20) # 按钮 start_button = tk.Button(root, text="🎮 开始 / 停止", font=("微软雅黑", 12, "bold"), bg="#66ccff", fg="white", activebackground="#3399cc", width=20, height=2, command=change, relief="raised", bd=3) start_button.pack(pady=30) # 控制变量 flag = False start_time = 0 # 启动主循环 root.mainloop()