zzzznl 发表于 2022-11-27 09:31

Python写的比嗓门小游戏

本帖最后由 zzzznl 于 2022-11-27 21:43 编辑

之前媳妇抖音刷到一个干嚎的游戏,我也不知道叫啥名字,媳妇说想玩。前天媳妇威胁我说要去窗边找组织,要和他们一起嚎,于是昨天我花了一天时间,Python写了一个小程序,然而已经没有意义了,我写程序时媳妇已经冲下楼去找组织了。于是这玩意需要的小伙伴自己拿去玩吧。我对自己的艺术修养很有信心,所以左键单击图片是更换背景图,右键是重置关卡。那个按钮挺丑,讲究的自己画个吧。难度随手设的,第一级有没有嘴都行,第8级可能要用力嚎,第9级可能根本完不成。计算用的rms声音能量,也就是音调高了可能有用。本人没啥水平,代码不讲究,大佬有啥槽点都可以来吐吐。
这种我连名字都不知道的东西,我确实不知有没有小伙伴发过类似的,如有,告诉我一声,我就删了

云盘内文件增加调参版,进行了少量更新,主要包括:
1.右键改为参数调整,由于以我媳妇的水平为基准,调参尽量设为选择题,但也没放弃填空题。这个读写文件会好点,但对外发的我不打算放随便建文件的,反正Python本来文件处理就是强项,看到这个的应该都能自己搞定
2.挑战失败增加提示
3.初始背景图由我媳妇选择,直接固化在打包文件中,所以包成了单文件
更新前后代码都是很简单的,帖子里代码就不更新了,云盘中源代码已更新
包后链接:https://pan.baidu.com/s/1Y-cn6N4XOLnvb-b6Ei8SUA
提取码:hvj5

import audioop
import pyaudio
from tkinter import *
from PIL import Image, ImageTk
import tkinter.filedialog
import tkinter.messagebox

level = 1


def background(filename):
    global im_gray
    im = Image.open(filename).resize((360, 640))
    im_gray = im.convert('L')
    return ImageTk.PhotoImage(im)


def ask_file():
    # 从本地选择一个文件,并返回文件的目录
    filename: str = tkinter.filedialog.askopenfilename()
    if filename != '':
      try:
            Image.open(filename)
      except IOError:
            msg = tkinter.messagebox.showinfo('提示', '请选择图片文件')
    else:
      msg = tkinter.messagebox.showinfo('提示', '您没有选择任何文件,将恢复原始背景')
      filename = '背景图片.jpg'
    return filename


def mainwindow():
    global level
    global im_gray, im_root

    def changeimage(event):
      global im_root
      filename = ask_file()
      im_root = background(filename)
      img = ImageTk.PhotoImage(im_gray)
      canvas_root.itemconfig(backid, image=im_root)
      canvas_root.itemconfig(foreid, image=img)
      canvas_root.image = img
      root.update()

    def resetlevel(event):
      global level
      msg = tkinter.messagebox.askokcancel('提示', '确认重置关卡?')
      if msg:
            level = 1
            btn1.config(text='挑战\n第%d关' % level)

    def record_audio():
      global level
      global im_gray, im_root
      score = 0
      basescore = int(1.5 ** (level - 1) * 1000)
      CHUNK = 1024
      FORMAT = pyaudio.paInt16
      CHANNELS = 2
      RATE = 44100
      p = pyaudio.PyAudio()
      stream = p.open(format=FORMAT,
                        channels=CHANNELS,
                        rate=RATE,
                        input=True,
                        frames_per_buffer=CHUNK)
      print("* recording")
      for i in range(0, 1292):
            data = stream.read(CHUNK)
            rms = audioop.rms(data, 2)
            rms -= basescore
            score += rms
            if score < 0:
                score = 0
            elif score > 1000000:
                if level < 9:
                  msg = tkinter.messagebox.showinfo('恭喜您', '挑战成功!\n您已获得嘴强王者%d段称号!' % level)
                  level += 1
                  btn1.config(text='挑战\n第%d关' % level)
                else:
                  msg = tkinter.messagebox.showinfo('恭喜您', '挑战成功!\n这个游戏对您来说已经没有什么意义了,\n可以去寻找更广阔的舞台。')
                break
            print(score)
            # if i % 4 == 0:
            img = im_gray.crop((0, 0, 360, 640 - int(score / 1000000 * 640)))
            img = ImageTk.PhotoImage(img)
            canvas_root.itemconfig(foreid, image=img)
            # canvas_root.image = img
            root.update()
      img = im_gray.crop((0, 0, 360, 640))
      img = ImageTk.PhotoImage(img)
      canvas_root.itemconfig(foreid, image=img)
      canvas_root.image = img
      root.update()
      print("* done recording")
      stream.stop_stream()
      stream.close()
      p.terminate()

    # 生成窗口
    root = Tk()
    root.title("嗓门大挑战")
    root.geometry('360x640+300+150')
    root.resizable = (False, False)

    im_root = background('背景图片.jpg')
    img = ImageTk.PhotoImage(im_gray)
    canvas_root = Canvas(root, width=360, height=640)
    backid = canvas_root.create_image(0, 0, anchor=NW, image=im_root)
    foreid = canvas_root.create_image(0, 0, anchor=NW, image=img)
    canvas_root.bind("<Button-1>", changeimage)
    canvas_root.bind("<Button-3>", resetlevel)
    canvas_root.pack()

    btn1 = Button(root, text='挑战\n第%d关' % level, command=record_audio)
    btn1.config(font=('宋体', 20))
    btn1.place(x=130, y=500, width=100, height=100)
    # 显示窗口
    root.mainloop()


if __name__ == '__main__':
    mainwindow()

zzzznl 发表于 2022-11-27 12:12

本来以为没啥意义的小东西,结果媳妇还是玩的挺卖力,生生给自己嚎耳鸣了,看得我也有动力稍微优化下了,这里说下最大的问题,可能由于录音设备差异,我之前在自己电脑上调的难度,嚎的快缺氧也没嚎过的第9关,在媳妇的电脑上还没发力就过了,弄得她非要把我电脑搬去嚎。如果使用体验不佳,建议就别用包后的了,源码改下basescore的设置吧

losingstars 发表于 2022-11-27 12:54

zzzznl 发表于 2022-11-27 12:12
本来以为没啥意义的小东西,结果媳妇还是玩的挺卖力,生生给自己嚎耳鸣了,看得我也有动力稍微优化下了,这 ...

看来这程序费耳朵呀。

linhao374 发表于 2022-11-27 11:30

这个好有趣,下个给孩子玩~

zg2600 发表于 2022-11-27 14:00

太吵了 ,影响不好

peoplefocus 发表于 2022-11-27 14:04

好像很有趣的样子

列明 发表于 2022-11-27 14:10

这不是音量100%就通关?

WZL1188888 发表于 2022-11-27 14:12

感谢分享,虽然我不懂,学习。

wangxingbo 发表于 2022-11-27 14:23

感谢分享

myj520 发表于 2022-11-27 14:34

哈哈哈,非常有趣,感谢分享
页: [1] 2
查看完整版本: Python写的比嗓门小游戏