pygame 按住按钮时播放声音

0 投票
3 回答
1411 浏览
提问于 2025-04-18 09:57

为了我的大学项目,我想写一个小工具,我们可以称之为“乐器”。

我的想法是,当我按下指定的按钮时,它会播放一个声音(正弦波),只要我按着这个按钮,它就会一直播放。

我现在的代码大致是这样的:

#create a sine array with frequency, samplerate and duration:
def sine(freq, samplerate, duration):
  duration = duration * samplerate
  wave = [math.sin(2.0 * math.pi * freq * t / samplerate) for t in range(0, duration)]
  return numpy.array(wave)

# this is the point int the main loop where the sound has to be played
if key[pygame.K_p]:
  pygame.sndarray.make_sound(sine(440, 44100, duration).play()

问题是,当我按下按钮时,它会播放我设置的时长,并且每次循环检测到我在按按钮时,声音都会重叠播放。

我觉得可以通过获取当前时间和我松开按钮的时间来解决这个问题,但我不知道该怎么实现。

也许你们能给我一些建议。

3 个回答

0

我在重做一个街机游戏《大金刚》,用这个代码来控制马里奥的走路动作。

        if not pygame.mixer.get_busy():
            pygame.mixer.Sound.play(walk)

当马里奥向右或向左走的时候会发出声音,但为了不让脚步声(这个声音持续一秒,音调不同)一直响,我加了一个新的条件来控制声音。

        elif not keys[pygame.K_LEFT] or not keys[pygame.K_RIGHT]:
            pygame.mixer.Sound.stop(walk)

这样做效果很好。如果我完成这个游戏,我会把它的代码库分享出来。这个游戏不是我做的,但我想在它的基础上进行修改。https://github.com/formazione/DonkeyKong

0

试着使用if语句来检查声音是否正在播放。

# check the mixer is not engaged when the key is down
if key[pygame.K_p] and (not pygame.mixer.get_busy() ):
   <your sound>.play()
#  check if the mixer is engaged when the key is up
elif not key[pygame.K_p] and pygame.mixer.get_busy():
   <your sound>.stop()

为了做到这一点,你可以在一开始就创建声音,并把它存储在一个变量里。这样的话,后面要停止声音的时候就会方便很多。

0

你可以让那个播放声音的if语句每隔“持续时间”秒才处理一次,这样就能确保上一个声音文件结束时,正好开始下一个声音。

另外,你可以试试使用pygame.mixer.sound,这样你就可以播放任何你想要的声音。然后用.play方法,你可以让它播放大约10000次,并在按钮松开时调用.stop。

我建议测试按钮的按下和松开状态,可以用另一个变量来保存按钮的最后状态。例如:

pWasPressed = pygame.K_p

然后你的if语句可以写成:

if (pWasPressed = false and pygame.K_p):

这样只有在你第一次按下这个键的时候才会触发,而不会在每次循环运行时都一直执行这个if语句。

希望这对你有帮助。

撰写回答