I'm trying to play background music and the music keeps on starting. I tried to use music.busy, but I can't figure it out. I want it to check if sound/music is playing, then I want it to print "music is playing". If a sound/music isn't playing I want it to start up a new song and loop it.
def musica():
if pygame.mixer.music.get_busy() == True:
print("music is playing")
if pygame.mixer.music.get_busy() == False:
music.play(loops=-1)
An easy way to play looped sounds is winsound. See the python documentation (https://docs.python.org/3.4/library/winsound.html) and set the parameter 'flags' in PlaySound to winsound.SND_LOOP.
I ended up doing this it is more of a workaround but it works:
m = 0
def musica():
global m
if m == 0:
music.play(loops=-1)
m = 1
if you are looking to play a sound during a specific event in a loop (e.g. opening a menu), it is possible to play sound only once by using timers.
example:
sound = pygame.mixer.Sound('sound.wav')
playSound = True
playSound_counter = 0
while:
playSound_counter += 1
if playSound_counter >= 11:
playSound = True
playSound_counter = 0
if i.rect.collidepoint(mouse_position):
if playSound == True :
sound.play()
playSound = False
elif playSound_counter == 10:
playSound_counter = 0
This is essentially two timers - one sets sound back to True every 11 secs, another negates it while mouse is over a rect.
by "playing once" i meant to be able to play it again in a controlled way when a certain event is triggered
Related
I am fairly new to Python and am trying to make a "List the States" game (in which the player has to input the name of the 50 states in the US). However, I wanted to add a countdown to stop the game if you ran out of time. The problem is that I can't get the countdown to update while the "screen.textinput" box is open.
I have tried using multiprocessing and threading modules to run 2 simultaneous while loops. With the first, it opens two separate windows and with the latter, I found info online that it doesn't work with the turtle module.
This my code at the moment:
timer = turtle.Turtle()
timer.penup()
timer.ht()
timer.goto(-300, 250)
game_is_on = True
while game_is_on:
# Update the timer
screen.update()
end = time.time()
timer.clear()
timer.write(f"{int(300 - (end - start))}")
# Input state name and analyze input
right_answers = len(previous_answers)
if right_answers == 0:
answer_state = screen.textinput(title=f"Guess the State", prompt="What's another state's name?").title()
else:
answer_state = screen.textinput(title=f"{right_answers}/50 States Correct",
prompt="What's another state's name?").title()
if answer_state in data.state.to_list() and answer_state not in previous_answers:
name = Names(answer_state, data)
previous_answers.append(answer_state)
if right_answers == 50:
game_is_on = False
if answer_state == "end":
game_is_on = False
Any ideas how to make this work? Perhaps there is a simpler way out that I am not seeing?
everything works except the next song doesn't play after the first is finished.
import os, random
from pygame import mixer
from pynput import keyboard
startup = 0
pause = 0
volume = 0.5
def Picker():
global startup
global volume
startup += 1
if startup > 1:
ThisSong = random.choice(os.listdir("C:\\Users\\...\\Music"))
NextSong = random.choice(os.listdir("C:\\Users\\...\\Music"))
ThisSong = NextSong
if ThisSong != NextSong:
mixer.init()
mixer.music.load("C:\\Users\\...\\Music" + ThisSong)
mixer.music.play(0)
mixer.music.set_volume(volume)
while mixer.music.get_busy():
def on_press(key):
global pause
global volume
if key == keyboard.KeyCode(char='-'):
volume -= 0.1
if volume < 0.1:
volume = 0.1
mixer.music.set_volume(volume)
if key == keyboard.KeyCode(char='='):
volume += 0.1
if volume > 1:
volume = 1
mixer.music.set_volume(volume)
if key == keyboard.KeyCode(char='['):
pause += 1
if pause == 1:
mixer.music.pause()
pause = 2
if pause == 3:
mixer.music.unpause()
pause = 0
with keyboard.Listener(on_press=on_press) as listener: listener.join()
else:
Picker()
else:
pass
Picker()
Picker()
screenshot of code
I can't get it to work, i'm very new to python so i'm probably missing something
obvious
Before starting: Thx #JGreenwell for copying the code.
Ok, so first, I’ll help you clean your code.
Things that are wrong
Having all that ThisSong and NextSong things: It won’t get saved when you restart Picker(). Either just have ThisSong, or place the ThisSong and NextSong assignment with the volume and pause variables:
.
pause = 0 # this is a problem! Next point
volume = 0.5
ThisSong = random.choice(...)
NextSong = random.choice(...)
The pause variable should be a boolean (True/False) and the pausing code should be like this:
.
pause = not pause
if pause:
# pause
else:
# unpause
Also, it would ideally be called paused
on_press and the Listener declaration should be outside the while loop, because otherwise they just keep being declared every time it loops. Then you should import time and put time.sleep(500) or something like that in the while loop, so that it doesn’t check every fraction of second.
As for the next song not playing, I don’t really know, but I’d suggest entering Picker() in the shell after the program has run (python -i script.py from CMD, IDLE leaves you in a shell by default). I would also suggest really following recommendation #3 as having them in the loop may break the loop and stop it from finishing. Most importantly, I would ask you to debug your code by adding print in every step of your code:
print(1)
if something:
print(2)
etc...
And seeing where it blocks
P.S.: The random dots are because you can’t have code in lists, so I had to exit the list.
Working solution, incase anyone else has the same problem as me in the future :)
from pygame import mixer
from pynput import keyboard
import threading
import random
import os
paused = 0
def player():
song = random.choice(os.listdir("C:\\users\\...\\desktop\\music"))
mixer.init()
mixer.music.load("C:\\users\\...\\desktop\\music\\" + song)
mixer.music.play(0)
while mixer.music.get_busy():
pass
else:
player()
def main():
t = threading.Thread(target = player, name = 'thread1', args = ())
t.start()
main()
def on_press(key):
global paused
if key == keyboard.KeyCode(char='['):
paused = not paused
if paused:
mixer.music.pause()
else:
mixer.music.unpause()
with keyboard.Listener(on_press=on_press) as listener: listener.join()
Recently I've been working with a simple and straightforward RPG in python with pygame, but I'm having some problems delaying specific events. Running the code below, everything happens at once.
if event.key == pygame.K_SPACE and buttonHighlight == 0:
FireAnimation() #displays a fire image
#DELAY HERE
if player[6] == 'Magic': #you deal damage to the enemy
enemy[0] = enemy[0]-(((player[1])+((player[1])*1)-enemy[4]))
else:
enemy[0] = enemy[0]-(((player[1])+((player[1])*1)-enemy[3]))
#DELAY HERE
StarAnimation() #displays a star image
#DELAY HERE
if enemy[6] == 'Magic': #enemy deals damage to you
player[0] = player[0]-(((enemy[1])+((enemy[1])*1)-player[4]))
else:
player[0] = player[0]-(((enemy[1])+((enemy[1])*1)-player[3]))
The rest of the code isn't really relevant, I just wanted to point out where I want to delay. Running this, both images displays, the player and the enemy takes damage at the same time. Thanks!
EDIT: I forgot to mention that I already have tried pygame.time.delay/wait and time.sleep, but all those delays the whole operation! It simply pushes everything forward when I use it, so everything happens at the same time several seconds later
You can create two new events (FIRE_ANIMATION_START, STAR_ANIMATION_START) which you post to the event queue with a delay (with pygame.time.set_timer(eventid, milliseconds)). Then in your event loop you just check for it.
FIRE_ANIMATION_START = pygame.USEREVENT + 1
STAR_ANIMATION_START = pygame.USEREVENT + 2
# ... Your code ...
for event in pygame.event.get():
if event.key == pygame.K_SPACE and buttonHighlight == 0:
pygame.time.set_timer(FIRE_ANIMATION_START, 10) # Post the event every 10 ms.
pygame.time.set_timer(STAR_ANIMATION_START, 1000) # Post the event every 1000 ms.
elif event.code == FIRE_ANIMATION_START:
pygame.time.set_timer(FIRE_ANIMATION_START, 0) # Don't post the event anymore.
FireAnimation() #displays a fire image
if player[6] == 'Magic': #you deal damage to the enemy
enemy[0] = enemy[0]-(((player[1])+((player[1])*1)-enemy[4]))
else:
enemy[0] = enemy[0]-(((player[1])+((player[1])*1)-enemy[3]))
elif event.code == STAR_ANIMATION_START:
pygame.time.set_timer(STAR_ANIMATION_START, 0) # Don't post the event anymore.
StarAnimation() #displays a star image
if enemy[6] == 'Magic': #enemy deals damage to you
player[0] = player[0]-(((enemy[1])+((enemy[1])*1)-player[4]))
else:
player[0] = player[0]-(((enemy[1])+((enemy[1])*1)-player[3]))
Documentation for pygame.time.set_timer(eventid, milliseconds). Also, as the code is right now it has bugs in it. The attributes for the events differs between different event types, so always make sure to check whether an event is KEYDOWN or USEREVENT before accessing the attributes event.key or event.code. The different types and attributes can be found here.
If you know how much time you need, you can simply add:
from time import sleep
...
sleep(0.1)
This will add a 100 milliseconds delay
You can use
pygame.time.delay(n)
or
pygame.time.wait(n)
to pause the program for n milliseconds. delay is a little more accurate but wait frees the processor for other programs to use while pygame is waiting. More details in pygame docs.
The first time playing the game, the timer works, the second time playing the game, the timer counts by two?
def main():
win1 = Tk()
win1x = 750
win1y = 720
gui1 = MakeGUI(win1,win1x,win1y,"light blue")
def countdown1(remaining,win):
if gui1.gameTimer > 0:
gui1.gameTimer-= 1
win1.after(1000,countdown1,remaining,win1)
else:
pass
while (gui1.quitGame == False):
while gui1.startGame == True:
# start the timer
countdown1(gui1.gameTimer,win1)
# start a loop until time up
while(gui1.gameTimer > 0):
gui1.drawGUI()
gui1.cleanupGUI()
gui1.initializeGUI()
main()
Found the issue in one of the class files. Good to go.
I'm writing a basic game where you use the mouse to dodge stars, but I can't get a certain part to work properly.
I'm trying to make it so that after 10 seconds of playing you beat the stage and if you lose, the 10 second timer resets.
Here is what I'm trying:
def time_pass(self):
self.time_passed = time.clock()
print self.time_passed
if self.time_passed > 10:
self.state = 3
This method only runs if self.state == 2 which is the main game, and if self.state == 3 you win, and the losing screen is if self.state == 0. But what happens is I run the game and when I click play it runs self.state 2 and starts the timer, and if I lose the timer keeps going. So then when I go back to the main screen and press play again, it picks up where the timer left off instead of resetting.
If you want to see the full game code:
Star Dodger Git
Thanks in advance.
-ChristianCareaga
Save the time into say start_time when you set self.state = 2.
Change self.time_passed > 10: to if self.time_passed > (start_time + 10):
The game will end 10 after starting.
IOW, don't reset the clock.