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.
Related
so i'm doing the states of my game right now :
import pygame
import sys
screen=pygame.display.set_mode((1200,700))
play_image=pygame.Surface((100,200))
play_image.fill('red')
play_rect=play_image.get_rect(topleft=(200,200))
retry_image=pygame.Surface((100,200))
retry_image.fill('red')
retry_rect=retry_image.get_rect(topleft=(200,200))
game_over=False
menustatus=True
while menustatus:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
pygame.font.quit()
sys.exit()
mouse_pos=pygame.mouse.get_pos()
mousecheck=pygame.mouse.get_pressed()
if play_rect.collidepoint(mouse_pos) and mousecheck[0]:
game_over=True
menustatus=False
screen.blit(play_image,play_rect)
pygame.display.update()
while game_over:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
pygame.font.quit()
sys.exit()
mouse_pos=pygame.mouse.get_pos()
mousecheck=pygame.mouse.get_pressed()
if retry_rect.collidepoint(mouse_pos) and mousecheck[0]:
menustatus=True
game_over=False
screen.blit(retry_image,retry_rect)
pygame.display.update()
problem is, when i click the red rectangle, which is a placeholder for my play button to head into the gameover screen, it crashes instead of showing me a game over screen
I've written a function state_machine() which decides what is happening and what to do next, but is uses states to 'jump' from one thing to another:
import pygame
import sys
screen=pygame.display.set_mode((1200,700))
play_image=pygame.Surface((100,200))
play_image.fill('red')
play_rect=play_image.get_rect(topleft=(200,200))
retry_image=pygame.Surface((100,200))
retry_image.fill('red')
retry_rect=retry_image.get_rect(topleft=(200,200))
def state_machine(state):
if state == "menu_status":
if play_rect.collidepoint(mouse_pos) and mousecheck[0]: #checks if player clicks a button to play
state = "game_over"
elif state == "game_over":
if retry_rect.collidepoint(mouse_pos) and mousecheck[0]: #checks if player clicks a button to retry
state = "game_active"
elif state == "game_active":
if player.rect.y>screen_height: #checks if player dies
state = "game_over"
return state
game_state = "menu_status"
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
pygame.font.quit()
sys.exit()
mouse_pos=pygame.mouse.get_pos()
mousecheck=pygame.mouse.get_pressed()
game_state = state_machine(game_state)
screen.blit(play_image,play_rect)
pygame.display.update()
I've not run this code because I'm not sure I've captured everything from your code.
I am new to python and pygame and I am developing a weather app as a project to learn both.
I want to display a new rectangle when a user is clicking an area (=button) of the screen. The new rectangle should be visible until the user clicks again, this time anywhere on the screen.
I have my main loop where the screen is drawn, and then checking for event MOUSEBUTTONUP and with collidepoint checking if the mouse was on the button and then updating variable newscreen to True
Then I have a new loop that should be running until the user is clicking again, anywhere on the screen.
The problem is that the new while loop is breaking as soon as the mouse is moved. It also looks like the first condition, checking if the user is clicking the button, is returning true in every iteration until the mouse is moved. Why is this not only returning true one time?
Can this be done without having a second while loop?
import pygame
import pygame.freetype
from pygame.locals import *
pygame.init()
SIZE = 500, 200
RED = (75, 0, 0)
NOTGREY = (75, 150, 150)
#set up the screen
screen = pygame.display.set_mode([800, 480])
# create rectangle
#Rect(position from left, position from top, width in pixels, height in pixels)
rect = Rect(50, 20, 200, 80)
rect2 = Rect(50,200, 200, 300)
running = True
newscreen = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
running = False
screen.fill(NOTGREY)
pygame.draw.rect(screen, RED, rect)
# If user is clicking (on release of click) on the rectangle area update newscreen to true
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: # Left mouse button.
if rect.collidepoint(event.pos):
newscreen = True
print("Clicking area")
while newscreen == True:
pygame.draw.rect(screen, RED, rect2)
pygame.display.flip()
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: # Left mouse button.
print("now you clicked again")
newscreen = False
pygame.display.flip()
You have to draw the rectangles depending on the state of newscreen:
if newscreen:
pygame.draw.rect(screen, RED, rect2)
else:
pygame.draw.rect(screen, RED, rect)
All the events need to be handled in one event loop. Toggle the state of newscreen when the button is clicked (newscreen = not newscreen):
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: # Left mouse button.
if newscreen or rect.collidepoint(event.pos):
newscreen = not newscreen
Complete example:
import pygame
import pygame.freetype
from pygame.locals import *
pygame.init()
SIZE = 500, 200
RED = (75, 0, 0)
NOTGREY = (75, 150, 150)
#set up the screen
screen = pygame.display.set_mode([800, 480])
# create rectangle
#Rect(position from left, position from top, width in pixels, height in pixels)
rect = Rect(50, 20, 200, 80)
rect2 = Rect(50,200, 200, 300)
running = True
newscreen = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
running = False
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: # Left mouse button.
if newscreen or rect.collidepoint(event.pos):
newscreen = not newscreen
screen.fill(NOTGREY)
if newscreen:
pygame.draw.rect(screen, RED, rect2)
else:
pygame.draw.rect(screen, RED, rect)
pygame.display.flip()
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()
I might not use the second while loop:
while running:
# keep loop running at the right speed
clock.tick(30) // Frame per second
screen.fill(BLACK) // never forget this line of code, especially when you work with animation
pos = pygame.mouse.get_pos()
# Process input (events)
for event in pygame.event.get():
# check for closing window
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
click = True
if click:
show_new_screen()
click = False
Solved with adding all events into one event loop as mentioned above. I still wanted the second box to be closed when clicking anywher on the screen. Solved by adding another event check, for MOUSEBUTTONDOWN. It did not work to have another MOUSEBUTTONUP event.
running = True
newscreen = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
running = False
# If user is clicking (on release of click) on the rectangle area update newscreen to true
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1: # Left mouse button.
if rect.collidepoint(event.pos):
newscreen = True
print("Clicking area")
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Left mouse button.
newscreen = False
print("now you clicked again")
screen.fill(NOTGREY)
pygame.draw.rect(screen, RED, rect)
if newscreen:
pygame.draw.rect(screen, RED, rect2)
pygame.display.flip()
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()
I use this code to get a separate position of each left click on pygame:
for event in pygame.event.get():
if event.type==QUIT:
running=False
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = event.pos
I use mouse_x and mouse_y for drawing , but they are always change. So, how to get an exact position of each click on a screen in pygame and to use them to draw ?
Thank you
1. To get the position when the mouse is clicked
You can use pygame.event.get() to get the position at the exact frame when you begin to press the button like that:
import pygame
from pygame.locals import * # import constants like MOUSEBUTTONDOWN
pygame.init()
screen = pygame.display.set_mode((640, 480))
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEBUTTONDOWN and event.button = 0: # detect only left clicks
print(event.pos)
pygame.display.flip()
pygame.quit()
exit()
2. To get the position each frame
In this case, you can use pygame.mouse.get_pos() like that:
import pygame
from pygame.locals import * # import constants like MOUSEBUTTONDOWN
pygame.init()
screen = pygame.display.set_mode((640, 480))
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
print(pygame.mouse.get_pos())
pygame.display.flip()
pygame.quit()
exit()
If you want to get the mouse position only if the left button is pressed:
Place the line print(pygame.mouse.get_pos()) in if pygame.mouse.get_pressed()[0]::
...
if pygame.mouse.get_pressed()[0]: # if left button of the mouse pressed
print(pygame.mouse.get_pos())
...
This code actually detects all kinds of mouse clicks, if you just want the left clicks you can add this to your if statement:
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
You are also not getting the coordinates the right way, you need to write it like this:
mouse_x, mouse_y = pygame.mouse.get_pos()
If you need to use all the clicks that are happening you need to store the x_mouse and y_mouse to a log which you can do like this:
# This outside the pygame loop
mouse_clicks = []
# This inside the pygame loop
for event in pygame.event.get():
if event.type==QUIT:
running=False
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
mouse_clicks.append(pygame.mouse.get_pos())
Now you have a list of tuples with all x,y coordinates for all clicks
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.