154 lines
5.0 KiB
Python
154 lines
5.0 KiB
Python
import tkinter as tk
|
||
from tkinter import messagebox, simpledialog
|
||
import time
|
||
import requests
|
||
|
||
API_URL = "http://47.80.30.142:6364/"
|
||
|
||
def load_leaderboard():
|
||
try:
|
||
resp = requests.get(f"{API_URL}/get_board")
|
||
if resp.status_code == 200:
|
||
return resp.json()
|
||
else:
|
||
return []
|
||
except Exception as e:
|
||
messagebox.showerror("错误", f"无法加载排行榜数据:{e}")
|
||
return []
|
||
|
||
def get_player_name():
|
||
name = simpledialog.askstring("参赛者姓名", "请输入您的姓名:")
|
||
if not name:
|
||
messagebox.showwarning("警告", "姓名不能为空")
|
||
return get_player_name()
|
||
return name
|
||
|
||
def get_player_message():
|
||
return simpledialog.askstring("祝贺留言", "你太棒了!要留下什么话?")
|
||
|
||
def submit_result(name, error, message=None):
|
||
try:
|
||
leaderboard = load_leaderboard()
|
||
updated = False
|
||
for entry in leaderboard:
|
||
if entry["name"] == name:
|
||
if abs(error) < entry["error"]:
|
||
entry["error"] = round(abs(error), 3)
|
||
if abs(error) < 0.1 and message:
|
||
entry["message"] = message
|
||
updated = True
|
||
break
|
||
if not updated:
|
||
entry = {"name": name, "error": round(abs(error), 3)}
|
||
if abs(error) < 0.1 and message:
|
||
entry["message"] = message
|
||
leaderboard.append(entry)
|
||
|
||
leaderboard.sort(key=lambda x: x["error"])
|
||
resp = requests.post(f"{API_URL}/set_board", json=leaderboard)
|
||
if resp.status_code == 200:
|
||
update_rank_display(leaderboard)
|
||
update_message_display(leaderboard)
|
||
else:
|
||
messagebox.showerror("提交失败", "成绩上传失败")
|
||
except Exception as e:
|
||
messagebox.showerror("错误", f"提交成绩时出错:{e}")
|
||
|
||
def update_rank_display(leaderboard):
|
||
rank_listbox.delete(0, tk.END)
|
||
for i, entry in enumerate(leaderboard, 1):
|
||
rank_listbox.insert(tk.END, f"{i}. {entry['name']:<8} 误差: {entry['error']:.3f}s")
|
||
|
||
def update_message_display(leaderboard):
|
||
messages.clear()
|
||
for entry in leaderboard:
|
||
if "message" in entry and entry["message"]:
|
||
messages.append(f"{entry['name']}:{entry['message']}")
|
||
|
||
def scroll_messages():
|
||
if messages:
|
||
msg = messages.pop(0)
|
||
message_var.set(msg)
|
||
messages.append(msg)
|
||
root.after(3000, scroll_messages)
|
||
|
||
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("300x150")
|
||
anim.configure(bg="white")
|
||
tk.Label(anim, text="🎉 完美掌控时间!", font=("微软雅黑", 18, "bold"), bg="white").pack(expand=True)
|
||
anim.after(1500, anim.destroy)
|
||
|
||
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()
|
||
message = None
|
||
if abs(error) < 0.1:
|
||
message = get_player_message()
|
||
show_win_animation()
|
||
else:
|
||
messagebox.showinfo("结果", "再接再厉!")
|
||
submit_result(name, error, message)
|
||
|
||
# ============================ UI ============================
|
||
|
||
root = tk.Tk()
|
||
root.geometry("360x550")
|
||
root.title("10秒挑战")
|
||
root.configure(bg="#f0faff")
|
||
|
||
title_label = tk.Label(root, text="🎯 10 秒挑战 🎯", font=("微软雅黑", 18, "bold"), bg="#f0faff", fg="#004466")
|
||
title_label.pack(pady=10)
|
||
|
||
rank_frame = tk.Frame(root, bg="#ffffff", bd=2, relief="groove")
|
||
rank_frame.pack(pady=5)
|
||
|
||
rank_title = tk.Label(rank_frame, text="🏆 排行榜", font=("微软雅黑", 10, "bold"), bg="#ffffff")
|
||
rank_title.pack(pady=5)
|
||
|
||
rank_listbox = tk.Listbox(rank_frame, font=("Courier", 10), height=5, width=35, bg="#f9f9f9")
|
||
rank_listbox.pack(padx=10, pady=5)
|
||
|
||
timex_label = tk.Label(root, text="点击按钮开始挑战", font=("微软雅黑", 12), bg="#f0faff")
|
||
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)
|
||
start_button.pack(pady=10)
|
||
|
||
# 滚动留言框
|
||
message_var = tk.StringVar()
|
||
message_label = tk.Label(root, textvariable=message_var, font=("微软雅黑", 10), fg="#444", bg="#f0faff", wraplength=320, justify="center")
|
||
message_label.pack(pady=20)
|
||
|
||
# 初始数据加载
|
||
messages = []
|
||
leaderboard = load_leaderboard()
|
||
update_rank_display(leaderboard)
|
||
update_message_display(leaderboard)
|
||
scroll_messages()
|
||
|
||
flag = False
|
||
start_time = 0
|
||
|
||
root.mainloop()
|