2019-01-12 22:32:48 (edited by jonikster 2019-01-12 22:33:52)

Hi.
I need to create a logo for the game.
It is necessary, that the sound was reproduced, and the program didn't work further until the end of playback. Also, so that if the user pressed Return, you could skip this. I decided to do this through a while loop. But it doesn't work correctly...


My sound class
from attr import attrs, attrib, Factory
import pygame
import time
pygame.mixer.init(frequency=44100, buffer=512)
@attrs
class sound():
    handle=attrib(default=Factory(int))
    def load(self,filename=""):
        self.handle = pygame.mixer.Sound(filename)
    def play(self):
        self.handle.play()
    def stop(self):
        self.handle.stop()
    def get_volume(self):
        return self.handle.get_volume()
    def set_volume(self, new_volume):
        self.handle.set_volume(new_volume)
    def fade(self, fadeSpeed):
        self.handle.fadeout(fadeSpeed)
    def isPlaying(self):
        return self.handle.get_busy()


My logo function
import pygame
from AGK.audio import sound
from AGK.mainframe import keyboard
import time
dlgAudio = sound.sound()
def dlgPlay(dlgSound, dlgFade=False, fadeSpeed=1000):
    dlgAudio.load(dlgSound)
    dlgAudio.play()
    while dlgAudio.isPlaying:
        if keyboard.pressed() == pygame.K_RETURN:
            if dlgFade == True:
                dlgAudio.fade(fadeSpeed)
                time.sleep(2)
            break


If I press Return while the logo is playing, it works. Sound fadeing and exit from the loop. But if the sound plays to the end, then after the playback is completed, the loop continues to work until you press Return. Although the loop should work until the sound is played.
Why so? Who can helps me?

2019-01-12 23:16:14

There seem to be multiple problems here:
First, if the code pasting mechanism of this forum didn't do anything wrong here, it looks like you put the break command directly into the body of the while loop, which will force the while loop to run only once in any case, even if you press a different key than the return key.
Then, time.sleep() only within the if. This should be at the main while loop body instead, and you should probably increase the sleep time a bit, to at least 20, maybe even 50 milliseconds.
The last and more important thing, keyboard.pressed() seems to be blocking, which means that it will stop your program's executing until any key is pressed, no matter which one. It looks like that isn't what you actually want. I'd suggest to search for an alternative, either within the audiogaming toolkit you're using, or trash this thing and kick off using pygame directly, it will work just as fine.
Best Regards.
Hijacker

2019-01-12 23:35:56

Hijacker,
No, break is inside the loop.
I don't think this is because of the waiting keys.

import pygame
def pressed():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            return event.key

2019-01-13 00:46:51 (edited by stewie 2019-01-13 00:47:12)

this line has a problem    
while dlgAudio.isPlaying:
You never actually call isPlaying as a function, so the while loop is just being passed the reference to the isPlaying function of the sound instance and not actually triggering the function. Since isPlaying is set and not a reference to null, it returns as true for the while loop and loops forever. Also is_busy may not directly correspond to whether or not a sound is playing, you may want to use pygame audio channels to make life easier.

Deep in the human unconscious is a pervasive need for a logical universe that makes sense. But the real universe is always one step beyond logic.