|
|
033.生日提醒器
import pygameimport datetimeimport jsonimport osimport mathimport randompygame.init()WIDTH, HEIGHT = 750, 600screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption("🎂 生日提醒器【美化科技版】")clock = pygame.time.Clock()FPS = 60# ========== 配色 ==========BG_COLOR = (10, 14, 24)TEXT_NORMAL = (210, 225, 250)COLOR_TITLE = (0, 220, 255)COLOR_TODAY = (255, 210, 80)COLOR_RED = (255, 60, 90)COLOR_BLUE = (0, 170, 255)GRAY_DARK = (30, 36, 52)GRAY_LINE = (60, 80, 110)# ========== 字体 ==========try: font_title = pygame.font.SysFont("simhei", 40) font_head = pygame.font.SysFont("simhei", 28) font_text = pygame.font.SysFont("simhei", 23) font_small = pygame.font.SysFont("simhei", 20) font_popup = pygame.font.SysFont("simhei", 52)except: font_title = pygame.font.SysFont("arial", 40) font_head = pygame.font.SysFont("arial", 28) font_text = pygame.font.SysFont("arial", 23) font_small = pygame.font.SysFont("arial", 20) font_popup = pygame.font.SysFont("arial", 52)# ========== 音效加载 ==========birthday_sound = Nonesound_path = "sound/birthday.wav"if os.path.exists(sound_path): try: birthday_sound = pygame.mixer.Sound(sound_path) except: birthday_sound = None# ========== 工具函数:发光文字 ==========def draw_glow_text(surface, font, text, color, x, y, glow=3): surf = font.render(text, True, color) for ox in [-glow, -1, 1, glow]: for oy in [-glow, -1, 1, glow]: surface.blit(surf, (x + ox, y + oy)) surface.blit(surf, (x, y))# ========== 数据 ==========DATA_FILE = "birthday.json"birthday_list = []def load_data(): global birthday_list if os.path.exists(DATA_FILE): try: with open(DATA_FILE, "r", encoding="utf-8") as f: birthday_list = json.load(f) except: birthday_list = []def save_data(): with open(DATA_FILE, "w", encoding="utf-8") as f: json.dump(birthday_list, f, ensure_ascii=False, indent=2)def get_days_left(month, day): today = datetime.date.today() try: next_birth = datetime.date(today.year, month, day) except ValueError: return 999 if next_birth < today: next_birth = datetime.date(today.year + 1, month, day) return (next_birth - today).daysload_data()# ========== 界面控件 ==========input_name = ""input_month = ""input_day = ""active_input = Nonebtn_add_rect = pygame.Rect(560, 510, 140, 50)input_name_rect = pygame.Rect(30, 510, 180, 42)input_m_rect = pygame.Rect(230, 510, 80, 42)input_d_rect = pygame.Rect(330, 510, 80, 42)# 背景粒子particles = []for _ in range(50): particles.append({ "x": random.randint(0, WIDTH), "y": random.randint(0, HEIGHT), "size": random.uniform(1, 2.5), "speed": random.uniform(0.15, 0.6), "alpha": random.randint(40, 130) })# ========== 生日弹窗变量 ==========show_popup = Falseconfetti_list = []popup_played_sound = Falsetoday_names = []# 生成彩带粒子def spawn_confetti(): colors = [(255,80,80),(255,220,60),(80,255,160),(80,180,255),(230,100,230)] for _ in range(120): confetti_list.append({ "x": random.randint(0, WIDTH), "y": random.randint(-60, -10), "vx": random.uniform(-2.5, 2.5), "vy": random.uniform(1, 3.5), "color": random.choice(colors), "size": random.uniform(3,7), "rotate": random.uniform(0,360) })running = Trueframe_count = 0while running: screen.fill(BG_COLOR) frame_count += 1 mouse_pos = pygame.mouse.get_pos() # ========== 事件 ========== for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.MOUSEBUTTONDOWN: # 如果弹窗打开,点击任意位置关闭弹窗 if show_popup: show_popup = False confetti_list.clear() popup_played_sound = False else: active_input = None if input_name_rect.collidepoint(mouse_pos): active_input = "name" elif input_m_rect.collidepoint(mouse_pos): active_input = "month" elif input_d_rect.collidepoint(mouse_pos): active_input = "day" elif btn_add_rect.collidepoint(mouse_pos): try: m = int(input_month) d = int(input_day) if 1 <= m <= 12 and 1 <= d <= 31 and input_name.strip(): birthday_list.append({"name": input_name.strip(), "month": m, "day": d}) save_data() input_name = input_month = input_day = "" except: pass if event.type == pygame.KEYDOWN and active_input and not show_popup: if event.key == pygame.K_BACKSPACE: if active_input == "name": input_name = input_name[:-1] elif active_input == "month": input_month = input_month[:-1] elif active_input == "day": input_day = input_day[:-1] else: char = event.unicode if active_input == "name": input_name += char else: if char in "0123456789": if active_input == "month": input_month += char else: input_day += char # ========== 背景特效 ========== grid_alpha = 28 grid_color = (*GRAY_LINE, grid_alpha) grid_size = 50 for x in range(0, WIDTH, grid_size): pygame.draw.line(screen, grid_color, (x, 0), (x, HEIGHT)) for y in range(0, HEIGHT, grid_size): pygame.draw.line(screen, grid_color, (0, y), (WIDTH, y)) scan_y = (frame_count * 1.6) % HEIGHT pygame.draw.line(screen, (*COLOR_BLUE, 50), (0, scan_y), (WIDTH, scan_y), 1) for p in particles: p["y"] += p["speed"] if p["y"] > HEIGHT: p["y"] = 0 p["x"] = random.randint(0, WIDTH) surf = pygame.Surface((int(p["size"]*2), int(p["size"]*2)), pygame.SRCALPHA) pygame.draw.circle(surf, (*COLOR_BLUE, p["alpha"]), (p["size"], p["size"]), p["size"]) screen.blit(surf, (p["x"], p["y"])) # ========== 整理生日数据 ========== today_list = [] soon_list = [] today_names.clear() for item in birthday_list: days = get_days_left(item["month"], item["day"]) info = f"{item['name']} | {item['month']}月{item['day']}日 | 剩余{days}天" if days == 0: today_list.append(info) today_names.append(item["name"]) else: soon_list.append((days, info)) soon_list.sort(key=lambda x: x[0]) # 检测:今天有人过生日,自动弹出庆祝窗口 if len(today_list) > 0 and not show_popup: show_popup = True spawn_confetti() # ========== 绘制主界面文字 ========== draw_glow_text(screen, font_title, "🎂 生日提醒器", COLOR_TITLE, 30, 25) y = 90 if today_list: draw_glow_text(screen, font_head, "✨ 今日寿星", COLOR_RED, 30, y) y += 40 breath = int(160 + 95 * math.sin(frame_count * 0.05)) live_color = (255, breath, 80) for text in today_list: draw_glow_text(screen, font_text, text, live_color, 50, y) y += 34 y += 12 draw_glow_text(screen, font_head, "📅 近期生日列表", TEXT_NORMAL, 30, y) y += 40 for _, txt in soon_list: draw_glow_text(screen, font_small, txt, TEXT_NORMAL, 50, y) y += 28 # ========== 输入框绘制 ========== def draw_input_box(rect, hint, text, active): color = COLOR_BLUE if active else GRAY_LINE pygame.draw.rect(screen, GRAY_DARK, rect, border_radius=8) pygame.draw.rect(screen, color, rect, 2, border_radius=8) show_text = text if text else hint ts = font_small.render(show_text, True, TEXT_NORMAL) screen.blit(ts, (rect.x + 10, rect.y + 8)) draw_input_box(input_name_rect, "姓名", input_name, active_input=="name") draw_input_box(input_m_rect, "月", input_month, active_input=="month") draw_input_box(input_d_rect, "日", input_day, active_input=="day") # 添加按钮 btn_hover = btn_add_rect.collidepoint(mouse_pos) radius = 8 if btn_hover: pygame.draw.rect(screen, (0, 90, 150), btn_add_rect, border_radius=radius) pygame.draw.rect(screen, COLOR_BLUE, btn_add_rect, 3, border_radius=radius) else:
|
|