I'm creating a program in Python using Pygame and I can't find a working method to detect when I scroll up.
I'm trying to recreate a popular video called "Interstellar Mouse"
https://www.youtube.com/watch?v=aANF2OOVX40
I'm trying to get it to play the same music when you scroll (to do the same thing without having to edit it in).
I've been able to get this to work with keypresses by doing something like this:
keys = pygame.key.get_pressed()
if keys[pygame.K_KEYNAME]:
pygame.mixer.music.unpause()
Just using keys seems to work fine but I need to use the mouse wheel.
This is the main loop:
run = True
while run:
#quit game after pressing the close button
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
#exit game by pressing ESC
if keys[pygame.K_ESCAPE]:
run = False
#scroll to activate
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
pygame.mixer.music.unpause()
else:
pygame.music.pause()
#update background
win.blit(bg, (width / 4, height / 4))
pygame.display.update()
pygame.quit()
The results are very inconsistent. Sometimes if I scroll really fast it will start playing after about a second but never stop. Sometimes it just doesn't play at all.
This part here:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
pygame.mixer.music.unpause()
else:
pygame.music.pause()
Every time you have event.type == pygame.MOUSEBUTTONDOWN you are either pausing or unpausing the music. Mouse clicks and scroll downs will pause your music. I would change this to a specific pause option, say if event.button == 2 instead of your else for better control.
Related
I would like to know how to make it so that when you hold down the pygame mouse, it continues getting events in the event loop.
I do not want to use pygame.mouse.get_pressed() because I want to also have a hold-down time to where it doesn't do anything.
Kind of like if you hold down a key in a text box in your browser: it types one key, then waits for about half a second, then starts typing a lot of keys really fast.
Also, I think it involves something before the main loop when the window is created or something, but I'm not sure.
I know there's a way to do this in pygame because I saw a Stack Overflow answer to it before, but after a while of searching, I cannot find it. If you have seen it or can find it, that is also appreciated too. This is my first time asking a question, so if I did anything wrong, please tell me.
Here is the code:
import pygame
WIDTH = 1000
HEIGHT = 800
WIN = pygame.display.set_mode()
def main():
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
print("the mouse was pressed")
WIN.fill((0, 0, 0))
pygame.display.update()
I would like to know how to make it so that when you hold down the pygame mouse, it continues getting events in the event loop.
Yo can't. However you can use pygame.mouse.get_pressed():
import pygame
WIDTH = 1000
HEIGHT = 800
WIN = pygame.display.set_mode()
def main():
run = True
clock = pygame.time.Clock()
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
buttons = pygame.mouse.get_pressed()
if any(buttons):
print("the mouse was pressed")
WIN.fill((0, 0, 0))
pygame.display.update()
The MOUSEBUTTONDOWN event occurs once when you click the mouse button and the MOUSEBUTTONUP event occurs once when the mouse button is released.
pygame.mouse.get_pressed() returns a list of Boolean values that represent the current state (True or False) of all mouse buttons. The state of a button is True as long as a button is held down.
I'm trying to make a menu show up when you press a button. When you press the button, it appears. However, when I move my cursor, the menu disappears.
if event.type == pygame.MOUSEBUTTONUP:
if self.ui.menuUI.get_rect(topright = (1850, 0)).collidepoint(pygame.mouse.get_pos()):
self.ui.show_menu()
Here's the show_menu()
def show_menu(self):
self.display_surface.blit(self.menuUII,self.MenuUII_rect)
Thanks for helping!
You must draw the image in the application loop. Set a state when the button is clicked. And draw the image depending on the state:
Constructor:
self.show_ui = False
Event handling:
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONUP:
if self.ui.menuUI.get_rect(topright = (1850, 0)).collidepoint(pygame.mouse.get_pos()):
self.show_ui = True
when drawing the scene
if self.show_ui:
self.ui.show_menu()
If you hold the mouse button, it counts that you are still clicking. I want to fix it so that when you click once, it counts once.
import pygame, sys, time
from pygame.locals import *
pygame.init()
ev = pygame.event.get()
clock = pygame.time.Clock()
w = 800
h = 600
ScreenDisplay = pygame.display.set_mode((w,h))
pygame.display.set_caption('Tap Simulator')
while True: # main game loop
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
clock.tick(30)
handled = False
if pygame.mouse.get_pressed()[0] and not handled:
print("click!")
handled = pygame.mouse.get_pressed()[0]
pygame.display.flip()
You have to use the MOUSEBUTTONDOWN event instead of pygame.mouse.get_pressed():
run = True
while run: # main game loop
for event in pygame.event.get():
if event.type == QUIT:
run = False
if event.type == MOUSEBUTTONDOWN:
if event.button == 1: # 1 == left button
print("click!")
pygame.display.flip()
clock.tick(30)
pygame.quit()
sys.exit()
pygame.mouse.get_pressed() returns a list of Boolean values that represent the state (True or False) of all mouse buttons. The state of a button is True as long as a button is held down.
The MOUSEBUTTONDOWN event occurs once when you click the mouse button and the MOUSEBUTTONUP event occurs once when the mouse button is released.
The pygame.event.Event() object has two attributes that provide information about the mouse event. pos is a tuple that stores the position that was clicked. button stores the button that was clicked. Each mouse button is associated a value. For instance the value of the attributes is 1, 2, 3, 4, 5 for the left mouse button, middle mouse button, right mouse button, mouse wheel up respectively mouse wheel down. When multiple keys are pressed, multiple mouse button events occur. Further explanations can be found in the documentation of the module pygame.event.
You can't check for a mouse click explicitly, but you can check for the mouse button being pressed down (event.type == pygame.MOUSEBUTTONDOWN) or released (event.type == pygame.MOUSEBUTTONUP).
click_count = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP:
click_count += 1
Since event.type == pygame.MOUSEBUTTONUP evaluates to True only when the mouse button is released, holding the mouse button down will not increment click_count.
I'm trying to integrate a "pause" menu and "main" menu in pygame, along with a screen that will show during the game. My code first loads the intro, or main menu, which works fine, and then handles a button click to call the main game loop function. The problem arises when, within that loop, I try to call the function for the pause menu. I use the same loops to do this so I'm not sure why one works and the other doesn't. Below I've added code snippets for reference.
The main menu (which is called first in the program):
def intro_screen():
intro = True
while intro:
# Event listeners
for event in pygame.event.get():
main_window.fill(tan)
...
I also have other buttons etc. which are unimportant, but to get out of the intro, a mouse event sets intro to false and calls the function game_loop:
# Handle the click event
if click[0] == 1:
intro = False
game_loop()
The game_loop function has a similar while loop:
def game_loop():
playing = True
paused = False
while playing:
# This is the main loop
# Load in the play screens...
main_window.fill(white)
play_screen = PlayScreen(main_window)
And buttons etc...
But when I set playing to False and paused to True, which calls the pause_screen() function, it doesn't pull up any new screen. It just stays on the game menu as if no event was received.
for event in pygame.event.get():
if event.type == pygame.QUIT:
playing = False
# Listen for the escape key and bring up the pause menu
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
playing = False
paused = True
pygame.display.update()
while paused:
pause_menu()
For reference, these are all contained in functions. The last line of my code simply calls intro_screen(), which works fine.
I can provide the rest of the code if that would be helpful. The only thing I could think of is that the mouse event works and the keydown event doesn't, but my syntax looks to be correct from what I can tell.
Looks like your while loop for the pause menu is out of the game loop. Try this:
def game_loop():
playing = True
paused = False
while playing:
# This is the main loop
# Load in the play screens...
main_window.fill(white)
play_screen = PlayScreen(main_window)
for event in pygame.event.get():
if event.type == pygame.QUIT:
playing = False
# Listen for the escape key and bring up the pause menu
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
playing = False
paused = True
pygame.display.update()
while paused:
pause_menu()
Why don't you create a separate function for your pause menu? This will be easier as you can then call it properly.
For example:
pause = True
while pause:
# Event listeners
for event in pygame.event.get():
main_window.fill(tan)```
I have some python code that uses a pygame window to establish which key is being pressed. When a key is pressed, the code heads off and does things before coming back to see what the next key pressed might be.
The problem I have is that if the user presses a key repeatedly, even while the 'code heads off and does things', pygame seems to remember what has been pressed rather than waiting for the next keypress. What I want is for the code to ignore any keypresses while the 'go and do stuff' is done then once that's finished, get the next keypress. Hope this makes sense!
import pygame
import time
pygame.init()
screen = pygame.display.set_mode((450,282))
screen.fill((0,0,0))
pygame.display.flip()
clock = pygame.time.Clock()
done = False
def go_and_do_things():
print("doing things")
time.sleep(2)
print("things done")
# Loop as long as done == False
while not done:
for event in pygame.event.get(): # User did something
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)
time.sleep(4)
pygame.quit()
You could use pygame.event.clear. As written below, it will discard any keypresses during go_and_do_things().
while not done:
for event in pygame.event.get(): # User did something
# Any key down
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
pygame.event.clear(eventtype=[pygame.KEYDOWN,
pygame.KEYUP)
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)
This is a fairly simple problem, you just need to add another
event.type for keyup. You also need to add a variable to make it stop
running which I will label as stopV if event.type == pygame.KEYUP:
stopV = True This should let you instantly stop it when you want to. edit because I want to reword this:
Re-doing this to make it more clear.
import pygame
import time
pygame.init()
screen = pygame.display.set_mode((450,282))
screen.fill((0,0,0))
pygame.display.flip()
clock = pygame.time.Clock()
done = False
unClick = False
def go_and_do_things():
if unClick == False
print("hello")
# do anything you want in the function here
else
return
while not done:
for event in pygame.event.get(): # User did something
# Any key down
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
if event.type == pygame.KEYUP:
unClick == True
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)