注册

当程序员纠结中午应该吃什么,那就用pygame来解决吧

写多了kotlin和android,最近想搞点小东西,于是拿出了长期没有宠爱的python,打算搞个小项目


想想应该写什么,对了,该吃饭了,诶,刚好,写一个能随机选择吃什么的小程序吧,只需要点击按钮,就会随机出现菜谱,然后再点一下,就会得出今天吃什么的结论


思路是这样的,读入一个txt文件,文件中写满想吃的东西,做到数据和代码区分,然后开始写UI,UI通过按钮点击随机展示美食即可


麻辣香锅
糖醋排骨
红烧肉
...

    import pygame
import random

class App:
   def __init__(self):
       # 初始化 Pygame
       pygame.init()

       # 创建窗口和设置标题
       self.window_size = (600, 300)
       self.window = pygame.display.set_mode(self.window_size)
       pygame.display.set_caption("What to Eat Today")

       # 设置字体对象
       self.font = pygame.font.Font('myfont.ttf', 32)

       # 加载菜单数据
       self.menu = []
       with open("menu.txt", "r") as f:
           for line in f:
               line = line.strip()
               if line != "":
                   self.menu.append(line)
               print(line) # 打印数据

if __name__ == "__main__":
   app = App()


运行一下


image-20230828201918635.png


nice,文件已经读入


这个时候的UI是一闪而过的,因为程序瞬间就执行完毕了,ok,那么我们就需要用一个循环维持UI窗口,然后设置开始选择按键,以及键盘控制按键,同时设置变量


today_menu表示今天吃的东西,


btn_start_stop表示按键文字,


cur_menu表示正处于随机中的美食,当我们按下开始按键时,cur_menu开始变换,当我们按下关闭按键时,cur_menu的数据就赋值到today_menu中,


show_wheel表示当前正处于随机中,还是已经结束了


只要增加一个无限循环,一切就会好起来的



       # 随机选择一道菜
       self.today_menu = ""
       self.btn_start_stop = "start"
       self.cur_menu = ""

       # 游戏主循环
       self.running = True
       self.show_wheel = False


       # 开关程序
       while self.running:
           for event in pygame.event.get():
               if event.type == pygame.QUIT:
                   self.running = False
               elif event.type == pygame.MOUSEBUTTONDOWN:
               ...

               # 增加一个elif 按键s,show_wheel为true, 按下q, show_wheel为false
               elif event.type == pygame.KEYDOWN:
               ...

运行结果


image-20230828202631700.png


现在已经有了窗口,接下来需要在上面画东西了


所用到的就是draw函数



   def draw(self):
       # 绘制界面
       self.window.fill((255, 255, 255))

       # 绘制菜单
       menu_surface = self.font.render(f"Today's Menu: {self.today_menu}", True, (0, 0, 0))
       ...

       # 绘制按钮
       button_size = min(self.window_size[0] // 4, self.window_size[1] // 4)
    ...

       btn_start = self.font.render(f"{self.btn_start_stop}", True, (0, 0, 0))
        # 缩小start 文字字号 以适应按钮
       btn_start = pygame.transform.scale(btn_start, (button_size // 3 * 2, button_size // 3 * 2))
       self.window.blit(btn_start, (button_x + button_size // 2 - btn_start.get_width() // 2, button_y + button_size // 2 - btn_start.get_height() // 2))

       # 滚轮动画
       ...
       pygame.display.update()

运行


image-20230828202741990.png


上面的代码仅仅能够展示一个静态的页面,


虽然界面平平无奇,似乎只有两行字?不然,实际上暗藏玄🐔,只要我们加上这段,



       # 绘制滚轮动画
       if self.show_wheel:
           wheel_size = min(self.window_size) // 2
           wheel_x = self.window_size[0] // 2 - wheel_size // 2
           wheel_y = self.window_size[1] // 2 - wheel_size // 2
           wheel_rect = pygame.Rect(wheel_x, wheel_y, wheel_size, wheel_size)
...

           # 随机选择并显示菜谱
           menu_index = random.randint(0, len(self.menu) - 1)
           menu_surface = self.font.render(self.menu[menu_index], True, (0, 0, 0))
           self.window.blit(menu_surface, (wheel_x + wheel_size // 2 - menu_surface.get_width() // 2, wheel_y + wheel_size // 2 - menu_surface.get_height() // 2))
           self.cur_menu = self.menu[menu_index]

当我们点击“start"


QQ20230828-203131-HD.gif


发现中间的菜谱动了起来,动了起来!都是大家爱吃的,只需要点击右边的stop就可以固定结果!


真正麻烦的在于那个滚轮动画,可以想见,我们需要额外的一个无限循环,每一帧都要修改cur_menu,同时更新动画中的菜谱,然后点击stop后,将cur_menu赋值给到today_menu,最麻烦的不是这些逻辑,而是位置,滚轮动画的位置设置为窗口正中间,然后画了两条线,看起来更好看,有一种,狙击枪瞄准的感觉


最后,进行简单优化,比如设置定时关闭等,全代码如下,如果你也不知道吃什么,就用这段代码 + 在同目录自定义一个txt文件,把自己想吃的写上去吧



import pygame
import random

class App:
   def __init__(self):
       # 初始化 Pygame
       pygame.init()

       # 创建窗口和设置标题
       self.window_size = (600, 300)
       self.window = pygame.display.set_mode(self.window_size)
       pygame.display.set_caption("What to Eat Today")

       # 设置字体对象
       self.font = pygame.font.Font('myfont.ttf', 32)

       # 加载菜单数据
       self.menu = []
       with open("menu.txt", "r") as f:
           for line in f:
               line = line.strip()
               if line != "":
                   self.menu.append(line)

       # 随机选择一道菜
       self.today_menu = ""
       self.btn_start_stop = "start"
       self.cur_menu = ""

       # 游戏主循环
       self.running = True
       self.show_wheel = False
       self.wheel_count = 0     # 记录滚轮动画播放的帧数


       # 开关程序
       while self.running:
           for event in pygame.event.get():
               if event.type == pygame.QUIT:
                   self.running = False
               elif event.type == pygame.MOUSEBUTTONDOWN:
                   if not self.show_wheel:
                       self.show_wheel = True
                       self.wheel_count = 0  # 点击按钮后重置计数器为0
                       self.btn_start_stop = "stop"
                   else:
                       self.show_wheel = False
                       self.today_menu = self.cur_menu  # 点击停止赋值
                       self.btn_start_stop = "start"

               # 增加一个elif 按键s,show_wheel为true, 按下q, show_wheel为false
               elif event.type == pygame.KEYDOWN:
                   if event.key == pygame.K_s:  # 按下 s 键
                       self.show_wheel = True
                       self.wheel_count = 0  # 重置计数器为0
                   elif event.key == pygame.K_q:  # 按下 q 键
                       self.show_wheel = False
                       self.today_menu = self.cur_menu  # 停止赋值

           self.draw()

   def draw(self):
       # 绘制界面
       self.window.fill((255, 255, 255))

       # 绘制菜单
       menu_surface = self.font.render(f"Today's Menu: {self.today_menu}", True, (0, 0, 0))
       menu_x = self.window_size[0] // 2 - menu_surface.get_width() // 2
       menu_y = self.window_size[1] // 2 - menu_surface.get_height() // 2
       self.window.blit(menu_surface, (menu_x, menu_y))

       # 绘制按钮
       button_size = min(self.window_size[0] // 4, self.window_size[1] // 4)
       button_x = self.window_size[0] - button_size - 20
       button_y = self.window_size[1] - button_size - 20
       button_rect = pygame.Rect(button_x, button_y, button_size, button_size)
       pygame.draw.circle(self.window, (255, 0, 0), (button_x + button_size // 2, button_y + button_size // 2), button_size // 2)
       pygame.draw.rect(self.window, (255, 255, 255), button_rect.inflate(-button_size // 8, -button_size // 8))

       btn_start = self.font.render(f"{self.btn_start_stop}", True, (0, 0, 0))
        # 缩小start 文字字号 以适应按钮
       btn_start = pygame.transform.scale(btn_start, (button_size // 3 * 2, button_size // 3 * 2))
       self.window.blit(btn_start, (button_x + button_size // 2 - btn_start.get_width() // 2, button_y + button_size // 2 - btn_start.get_height() // 2))

       # 绘制滚轮动画
       if self.show_wheel:
           wheel_size = min(self.window_size) // 2
           wheel_x = self.window_size[0] // 2 - wheel_size // 2
           wheel_y = self.window_size[1] // 2 - wheel_size // 2
           wheel_rect = pygame.Rect(wheel_x, wheel_y, wheel_size, wheel_size)
           pygame.draw.circle(self.window, (0, 0, 0), (wheel_x + wheel_size // 2, wheel_y + wheel_size // 2), wheel_size // 2)
           pygame.draw.circle(self.window, (255, 255, 255), (wheel_x + wheel_size // 2, wheel_y + wheel_size // 2), wheel_size // 2 - 10)
           pygame.draw.line(self.window, (0, 0, 0), (wheel_x + 10, wheel_y + wheel_size // 2), (wheel_x + wheel_size - 10, wheel_y + wheel_size // 2))
           pygame.draw.line(self.window, (0, 0, 0), (wheel_x + wheel_size // 2, wheel_y + 10), (wheel_x + wheel_size // 2, wheel_y + wheel_size - 10))

           # 随机选择并显示菜谱
           menu_index = random.randint(0, len(self.menu) - 1)
           menu_surface = self.font.render(self.menu[menu_index], True, (0, 0, 0))
           self.window.blit(menu_surface, (wheel_x + wheel_size // 2 - menu_surface.get_width() // 2, wheel_y + wheel_size // 2 - menu_surface.get_height() // 2))
           self.cur_menu = self.menu[menu_index]
           # 播放一定帧数后停止动画
           self.wheel_count += 1
           if self.wheel_count > 500:
               self.show_wheel = False
               self.today_menu = self.cur_menu  # 自动停止赋值
       pygame.display.update()

if __name__ == "__main__":
   app = App()
作者:小松漫步
来源:juejin.cn/post/7272257829770887223


0 个评论

要回复文章请先登录注册