python - 奇异果和游戏中的声音:游戏更新循环等待声音完成,然后继续[奇异果中使用SoundLoader的FPS问题]

标签 python audio kivy

我正在学习通过使用Kivy制作游戏来对Python进行编程,但是我在实现针对不同事件的声音时遇到了麻烦(例如,在拾取了盾牌项目时,shield.on.play()。),因为游戏更新循环似乎停止了待一会儿,直到声音播放完毕。我在这里做了相关代码的简短版本...

shield_on = soundLoader('shield_on.wav')
class game(Widget):
#...loads of other stuff...

    def update_loop(foo):
        self.player_one.update()
        self.player_two.update()
        self.player_item_collision_detector()
        if "game_file_says_player_one's_shields_are on":
            self.player_one.drawShield()
            shield_on.play()

目前,我只是在全局加载声音。我知道那很糟糕,但他们也是我唯一的全局性专家。然后是一个包含游戏本身的小部件,其中包含很多东西和更新循环...它会更新玩家的位置,检查是否与物品发生碰撞-发生碰撞时,该物品(此处为盾牌)被注册为“开”在游戏文件中。然后,更新循环检查游戏文件中“盾牌”的状态,看它们是否打开并应播放声音。

声音播放的很好,但是循环似乎停止了,直到完成播放声音为止。从本质上讲,播放器停了一微秒。如何使更新循环不等待声音结束...?

最佳答案

PyGame的解释和解决方法:

问题的原因在这里解释:github.com/kivy/kivy/issues/2728
本质上,SoundLoader.load()函数应返回最适合播放传递给您的声音文件的类。最终并没有完全做到这一点,据我所知,问题不在于Kivy,而在于GStreamer。这会导致该应用程序出现明显的临时帧速率下降,无论您在何处调用.play()方法。

github-thread中的offerend是解决这个问题的两种可能的方法。
1)确保使用SoundSDL2直接返回合适的类
2)改用PyGame

我实现了后者,并且效果很好。

# Initialize files and PyGame mixer:
import pygame
pygame.init()
pygame.mixer.pre_init(44100, 16, 2, 4096) # Frequency, size, channels and buffersize    
shield_on = pygame.mixer.Sound("shield_on.wav")

class game(Widget):
    ...
    def update_loop(self):
        ...
        if "game_file_says_shield_is_on":
            shield_on.play()

希望这对其他人有帮助!

我想说上述答案也很有用,因为它使我能够确定真正的问题。我给它投票,但我在这里还没有声誉。

关于python - 奇异果和游戏中的声音:游戏更新循环等待声音完成,然后继续[奇异果中使用SoundLoader的FPS问题],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31234970/

相关文章:

python - 如何将在纯 python 中动态创建的按钮添加到用 Kivy 语言编写的 kivy 布局?

python - DataFrame.drop_duplicates 和 DataFrame.drop 不删除行

python TypeError : frozenset expected at most 1 arguments, 得到 4

python - 无法使用网络摄像头读取帧。错误-2147483638

python - Kivy Buttons - 在执行时播放声音,而不是在点击时播放

python - Kivy:弹出窗口未显示

python - 无法使用 openpyxl Workbook 将数据写入 Excel-Sheet

javascript - 如何在jQuery中使用Goto语句?

linux - 将音频从浏览器流式传输到 nodejs

c# - SystemSounds.Asterisk.Play()在发布后无法正常工作