Create a button to control background music on and off in pygame - python

I want to create a button in my game that can control the background music on and off. The first click will stop the background music, and the second click can bring back the music. Now my button can control the music on and off, but I need to click multiple times to make it work, it seems that the click event is not captured everytime, here is my code:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if 20 + 50 > mouse_position[0] > 20 and 20 + 20 > mouse_position[1] > 20:
play_music = not play_music
if play_music:
pygame.mixer.music.unpause()
else:
pygame.mixer.music.pause()
pygame.display.flip()
clock = pygame.time.Clock()
clock.tick(15)

J0hn's answer is correct. Define a boolean variable (e.g. music_paused = False), toggle it when the user clicks on the button and call pygame.mixer.music.pause to stop the music and pygame.mixer.music.unpause to resume the playback of the music stream.
I also recommend doing the collision check in the event loop (for event in pygame.event.get():), because the button should be clicked only once per pygame.MOUSEBUTTONDOWN event. pygame.mouse.get_pressed() will keep clicking the music button as long as the mouse button is down.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray12')
BLUE = pg.Color('dodgerblue1')
pg.mixer.music.load('your_music_file.ogg')
pg.mixer.music.play(-1)
button = pg.Rect(100, 150, 90, 30)
music_paused = False
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.MOUSEBUTTONDOWN:
if button.collidepoint(event.pos):
# Toggle the boolean variable.
music_paused = not music_paused
if music_paused:
pg.mixer.music.pause()
else:
pg.mixer.music.unpause()
screen.fill(BG_COLOR)
pg.draw.rect(screen, BLUE, button)
pg.display.flip()
clock.tick(60)
pg.quit()

It looks like you have a pygame.mixer.music.pause() but nothing from resume. I'm not sure how pygame's music mixer works but I'd recommend using a flag that is updated on button click
music = 0 by default, if clicked, set music = 1 then have a check if music == 1: pygame.mixer.music.pause() and if music == 0: pygame.mixer.music.unpause(). Make that check and flag change every time the button is clicked.

ya guys don't need a boolean variable only a small function
def toggleMusic():
if pygame.mixer.music.get_busy():
pygame.mixer.music.pause()
else:
pygame.mixer.music.unpause()
pygame.mixer.music.get_busy() is the boolean you need because this checks if music is playing. if music is playing it will return True and vice versa

Related

Game Pausing when while loop in running [duplicate]

This question already has answers here:
How to add pause mode to Python program
(1 answer)
Making a pause screen
(1 answer)
Closed 4 months ago.
so I am learning Python via pygame
I am trying to make it that you can click on something to move it
but when (while clicked) loop start the screen freeze (it is as if it's paused)
and yes the game itself is responsive
and when I click again to stop the loop actually stops as it should do and the game goes on
the thing is, when I click to stop moving the ship or whatever it actually moves to where the mouse is as it should be doing
but no, when the loop is going, nothing moves on the screen, however the position of the Player is actually following the mouse, so the loop is kind of working
is there something I am missing here?
def main():
run = True
clicked = False
while run:
clock.tick(FPS)
events = pygame.event.get()
for event in events:
if event.type ==pygame.QUIT:
run = False
Draw_Background(Light_Yellow)
Draw_WIN(Player1, Player2)
Player1_move()
Player2_move()
Shooting(events)
# here it gets user click and set clicked to true
for event in events:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button ==1:
Mouse_Pos= pygame.mouse.get_pos()
if Mouse_Pos[0]>= Player1.x and Mouse_Pos[0]<=Player1.x+Player_Ship_Width and Mouse_Pos[1]>= Player1.y and Mouse_Pos[1]<= Player1.y+Player_Ship_Hight:
print("Ship Clicked")
clicked = True
#here it should make the object follow the mouse and when clicked it stops
while clicked:
Mouse_Pos = pygame.mouse.get_pos()
Player1.x = Mouse_Pos[0]-Player_Ship_Width//2
Player1.y = Mouse_Pos[1]-Player_Ship_Hight//2
events2 = pygame.event.get()
for event in events2:
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button ==1:
Mouse_Pos = pygame.mouse.get_pos()
if Mouse_Pos[0]>= Player1.x and Mouse_Pos[0]<=Player1.x+Player_Ship_Width and Mouse_Pos[1]>= Player1.y and Mouse_Pos[1]<= Player1.y+Player_Ship_Hight:
clicked = False
print ("Stopped")
pygame.display.update()

How do I stop the screen from updating?

I'm making a calculator in pygame but when I click the button, I want the number to stay on the screen but instead of staying on the screen, the number just appears when my mouse is clicked. When I release it, the numbers disappears. Does anyone know a solution for this?
My code:
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((600,800))
pygame.display.set_caption("Calculator")
clock = pygame.time.Clock()
font1 = pygame.font.Font("c:/Users/oreni/OneDrive/Masaüstü/sprites/minecraft.ttf", 100)
one = 1
one_main = font1.render(str(one), False, "black")
one_main_r = one_main.get_rect(center = (75,100))
one_button = pygame.Surface((142.5,142.5))
one_button.fill("white")
one_button_r = one_button.get_rect(topleft = (0,160))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.fill("black")
screen.blit(one_button,one_button_r)
if event.type == pygame.MOUSEBUTTONDOWN:
if one_button_r.collidepoint(event.pos):
screen.blit(one_main,one_main_r)
pygame.display.update()
clock.tick(60)
The usual way is to redraw the scene in each frame. You need to draw the text in the application loop. Set a variable that indicates that the image should be drawn when the mouse is clicked, and draw the image according to that variable:
draw_r = False
run = True
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
if one_button_r.collidepoint(event.pos):
draw_r = True
screen.fill("black")
screen.blit(one_button,one_button_r)
if draw_r:
screen.blit(one_main, one_main_r)
pygame.display.update()
clock.tick(60)
pygame.quit()
exit()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()

How to freeze pygame window?

When I want to freeze my pygame window for a few seconds I usually use time.sleep(). However, if I accidentaly press any key on my keyboard meanwhile it detects the key after the time has passed. Is there any way to freeze my pygame window so that the code won’t consider the key pressed?
You have to use pygame.time.wait() rather than time.sleep(). Be aware that the input has to be set in millisecond.
See documentation: time.wait()
Here is an example where the screen will change color every frame. The title bar displays the last key pressed.
If the space bar is pressed, the color change is paused for three seconds. Key presses are ignored, but other events may be handled during this period.
This is accomplished by setting up a custom timer and using a variable to track the paused state.
import pygame
import itertools
CUSTOM_TIMER_EVENT = pygame.USEREVENT + 1
my_colors = ["red", "orange", "yellow", "green", "blue", "purple"]
# create an iterator that will repeat these colours forever
color_cycler = itertools.cycle([pygame.color.Color(c) for c in my_colors])
pygame.init()
pygame.font.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode([320,240])
pygame.display.set_caption("Timer Example")
done = False
paused = False
background_color = next(color_cycler)
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == CUSTOM_TIMER_EVENT:
paused = False
pygame.display.set_caption("")
pygame.time.set_timer(CUSTOM_TIMER_EVENT, 0) # cancel the timer
elif not paused and event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
pygame.time.set_timer(CUSTOM_TIMER_EVENT, 3000)
pygame.display.set_caption("Paused")
paused = True
else:
pygame.display.set_caption(f"Key: {event.key} : {event.unicode}")
if not paused:
background_color = next(color_cycler)
#Graphics
screen.fill(background_color)
#Frame Change
pygame.display.update()
clock.tick(5)
pygame.quit()
EDIT: Change to ignore key-presses during the paused period as the question asked.

Python, pygame mouse position and which button is pressed

I have been trying to get my code collecting which mouse button is pressed and its position yet whenever I run the below code the pygame window freezes and the shell/code keeps outputting the starting position of the mouse. Does anybody know why this happens and more importantly how to fix it?
(For the code below I used this website https://www.pygame.org/docs/ref/mouse.html and other stack overflow answers yet they were not specific enough for my problem.)
clock = pygame.time.Clock()
# Set the height and width of the screen
screen = pygame.display.set_mode([700,400])
pygame.display.set_caption("Operation Crustacean")
while True:
clock.tick(1)
screen.fill(background_colour)
click=pygame.mouse.get_pressed()
mousex,mousey=pygame.mouse.get_pos()
print(click)
print(mousex,mousey)
pygame.display.flip()
You have to call one of the pygame.event functions regularly (for example pygame.event.pump or for event in pygame.event.get():), otherwise pygame.mouse.get_pressed (and some joystick functions) won't work correctly and the pygame window will become unresponsive after a while.
Here's a runnable example:
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
BG_COLOR = pygame.Color('gray12')
done = False
while not done:
# This event loop empties the event queue each frame.
for event in pygame.event.get():
# Quit by pressing the X button of the window.
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
# MOUSEBUTTONDOWN events have a pos and a button attribute
# which you can use as well. This will be printed once per
# event / mouse click.
print('In the event loop:', event.pos, event.button)
# Instead of the event loop above you could also call pygame.event.pump
# each frame to prevent the window from freezing. Comment it out to check it.
# pygame.event.pump()
click = pygame.mouse.get_pressed()
mousex, mousey = pygame.mouse.get_pos()
print(click, mousex, mousey)
screen.fill(BG_COLOR)
pygame.display.flip()
clock.tick(60) # Limit the frame rate to 60 FPS.

Lock mouse in window Pygame

I want to make a FPS game in Pygame in windowed mode.
I need to be able to move my camera around for 360 degrees and more without limitation and with the hidden cursor.
I used Pygame's set_visible and set_pos but it doesn't prevent my mouse going out of the window and blocking on the screen borders.
import pygame
pygame.init()
game_display = pygame.display.set_mode((800,600))
pygame.mouse.set_visible(False)
exit = False
while (not exit):
pygame.mouse.set_pos = (400, 300)
mouse_move = (0,0)
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit = True
if event.type == pygame.MOUSEMOTION:
mouse_move = event.rel
if mouse_move != (0,0):
print(mouse_move)
pygame.quit()
You have to call pygame.event.set_grab(True) as well.
Better allow the users to exit with the Esc or another key, because they won't be able to click the x button anymore to close the window.
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
exit = True

Categories