pygame.mouse.get_pressed() not responding - python

the code is as follows
import pygame
pygame.init()
info = pygame.display.Info()
win = pygame.display.set_mode(((info.current_h//10)*10,(info.current_w//10)*10))
running = True
while running:
if pygame.mouse.get_pressed() == (1,0,0):
Mouse = pygame.mouse.get_pos()
X = (Mouse[0]//10)*10
Y = (Mouse[1]//10)*10
print(X)
print(Y)
pygame.draw.rect(win,(255,255,255),(X,Y,10,10))
pygame.display.update()
the Problem is the pygame window itself does not respond when i run the program and click it does not even print X or Y
i tried adding some delay thinking maybe pygame does not like how fast it is

You have to implement an event loop and to get the events messages with pygame.event.get(). At least you have to invoke pygame.event.pump():
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system. If you are not using other event functions in your game, you should call pygame.event.pump() to allow pygame to handle internal actions.
Since pygame.mouse.get_pressed() returns a sequence of booleans you have to use subscription to evaluate the state of a button:
buttons = pygame.mouse.get_pressed()
if buttons[0]:
# [...]
I recommend to add an event loop to the application:
import pygame
pygame.init()
info = pygame.display.Info()
win = pygame.display.set_mode(((info.current_h//10)*10,(info.current_w//10)*10))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
buttons = pygame.mouse.get_pressed()
if buttons[0]:
Mouse = pygame.mouse.get_pos()
X = (Mouse[0]//10)*10
Y = (Mouse[1]//10)*10
print(X)
print(Y)
pygame.draw.rect(win,(255,255,255),(X,Y,10,10))
pygame.display.update()

There's a couple of issues here.
First is that pygame.mouse.get_pressed() returns a tuple of button states, something like ( True, False, False ). But it only returns a valid state after pygame.event.get() has been called. Ref: https://www.pygame.org/docs/ref/mouse.html#pygame.mouse.get_pressed
The easiest way to achieve what it looks like you are trying to do, is to first wait for a MOUSEBUTTONDOWN (or MOUSEBUTTONUP) event, and then check the location of the click and state of the buttons.
# Main loop
while not done:
# Handle user-input
for event in pygame.event.get():
if ( event.type == pygame.QUIT ):
done = True
elif ( event.type == pygame.MOUSEBUTTONUP ):
# On mouse-click
mouse_x, mouse_y = event.pos
mouse_buttons = pygame.mouse.get_pressed()
if ( mouse_buttons[0] ): # ( True, ... )
X = ( mouse_x // 10 ) * 10
Y = ( mouse_y // 10 ) * 10
print( "Mouse-click at %d, %d -> %d, %d" % ( mouse_x, mouse_y, X, Y ) )
pygame.draw.rect( win, (255,255,255), (X,Y,10,10) )

The pygame.mouse.get_pressed() returns Boolean values such as True or False but doesn't store actual mouse cursor press position. So try instead to use this in your main loop:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
Hope this helps. More on pygame.mouse commands here

https://www.pygame.org/docs/ref/mouse.html#pygame.mouse.get_pressed
As you can see, mouse.get pressed returns a sequence of boolean variables, not a tuple of integers as you were evaluating it to.
Before running the while loop, print pygame.mouse.get_pressed() to see how it works and what it returns specifically in your program.

pygame.mouse.get_pressed() returns a tuple of boolean, something like (False,True,False).
So if you want to check whether left click is pressed for example you would do
mouse=pygame.mouse.get_pressed() #(True,False,False)
if mouse[0]: #If first mouse button pressed AKA left click.
#your code
Regarding the screen freezing, you need an event loop inside your main while to get event messages.
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
Without it the pygame screen will freeze.
Hope this helps you fix your code.

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()

Is there a way to close the pygame window with a MOUSEBUTTONDOWN event?

I am trying to make a clickable image that exits pygame, but im not sure how to make it close. I have tried using the pygame.quit() and sys.exit() but that loads for a second but doesn't do anyhting. I will show the code I have here(the only relevant code is the x and y variables nad the exit button down the bottom):
import pygame, sys
clock = pygame.time.Clock()
from pygame.locals import *
pygame.init() # inititates Pygame
pygame.display.set_caption('Lightmind')
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) # initiates the window
logo = pygame.image.load("GameLogo.png").convert()
logo = pygame.transform.scale(logo, (256, 256))
start_button = pygame.image.load("StartButton.png").convert()
start_button = pygame.transform.scale(start_button, (256, 256))
exit_button = pygame.image.load("ExitButton.png").convert()
exit_button = pygame.transform.scale(exit_button, (256, 100))
x_2 = 560
y_2 = 400
fade_in = True
fade_out = True
fade_in_ball = True
fade_in_start = True
fade_in_exit = True
running = True
while running: # game loop
for event in pygame.event.get():
if event.type == QUIT:
running = False
pygame.quit()
sys.exit()
# fade in the logo
if fade_in == True:
for i in range(255):
screen.fill((0,0,0))
logo.set_alpha(i)
screen.blit(logo, (560,260))
pygame.display.flip()
clock.tick(60)
fade_in = False
# fade out the logo
if fade_out == True:
for i in range(255):
screen.fill((0,0,0))
logo.set_alpha(255-i)
screen.blit(logo, (560,260))
pygame.display.flip()
clock.tick(60)
fade_out = False
# fade in the start button
if fade_in_start == True:
for i in range(255):
start_button.set_alpha(i)
screen.blit(start_button, (560, 240))
pygame.display.flip()
clock.tick(60)
fade_in_start = False
# fade in the exit button
if fade_in_exit == True:
for i in range(255):
exit_button.set_alpha(i)
screen.blit(exit_button, (x_2, y_2))
pygame.display.flip()
clock.tick(60)
fade_in_exit = False
# make exit button exit game
if event.type == pygame.MOUSEBUTTONDOWN:
x_2, y_2 = event.pos
if exit_button.get_rect().collidepoint(x_2, y_2):
pygame.quit()
sys.exit()
pygame.display.update()
Any help is appreciated!
You're checking the event outside of your event loop. Move it up instead:
for event in pygame.event.get():
if event.type == QUIT:
running = False
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
x_2, y_2 = event.pos
if exit_button.get_rect().collidepoint(x_2, y_2):
pygame.quit()
pygame.event.get() get all the messages and remove them from the queue. See the documentation:
This will get all the messages and remove them from the queue. [...]
If pygame.event.get() is called in multiple event loops, only one loop receives the events, but never all loops receive all events. As a result, some events appear to be missed.
You must handle the click detection in the event loop.
pygame.Surface.get_rect.get_rect() returns a rectangle with the size of the Surface object, but it returns a rectangle that always starts at (0, 0) since a Surface object has no position.
The Surface is placed at a position on the display with the blit function.
You've to set the location of the rectangle, either by a keyword argument, e.g:
running = True
while running: # game loop
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
extit_button_rect = exit_button.get_rect(topleft = (x_2, y_2))
if extit_button_rect.collidepoint(event.pos):
running = False
# [...]
pygame.quit()
sys.exit()

pygame.mouse.get_pressed() not working as I need in my button function

As part of a game, I am attempting to create a login page in pygame. As I require buttons I have been trying to get a button function (that I saw on another tutorial page) to work. However, I seem to run into a problem with getting the program to register when the mouse is clicked. Below I have pasted my function for the button:
def button(self,msg,x,y,w,h,ic,ac,action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
print(click)
if x+w > mouse[0] > x and y+h > mouse[1] > y:
pygame.draw.rect(screen, ac,(x,y,w,h))
if click[0] == 1 and action != None:
action()
else:
pygame.draw.rect(screen, ic,(x,y,w,h))
smallText = pygame.font.Font("freesansbold.ttf",20)
textSurf, textRect = self.text_objects(msg, smallText)
textRect.center = ( (x+(w/2)), (y+(h/2)) )
screen.blit(textSurf, textRect)
pygame.display.update()
Each time I run my program - no matter what I do, my buttons remain static objects and do not change colour or allow any actions to run. Additionally the line 'print(click)' only ever outputs (0,0,0). I am using a laptop to code this program so maybe my trackpad is what is causing issues? I'm not too sure really but any alternatives on how to get this function to work would be much appreciated!
With Pygame you usually run an event function in your main loop that handles all your events.
while self.playing:
self.draw()
self.events()
etc...
In your event function you can write something like this:
for event in pygame.event.get():
# Always here to make it possible to exit when pressing X in game window:
if event.type == pygame.QUIT:
self.playing = False
pygame.quit()
quit()
# Left mouse button down events:
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
pos = pygame.mouse.get_pos()
if button.collidepoint(pos):
print('do what button is supposed to do')
Hope this helps!

Updating the position of a rectangle

I am trying to get familiar with pygame so am starting with a simple program that draws a rectangle and moves it around with the mouse. The rectangle draws fine however it does not move with the mouse position and I cannot think why.
I found one other with this problem however this fix didnt work for me and was much more long winded than I felt it needed to be.
pygame.init()
screen = pygame.display.set_mode((500,300))
# --- mainloop / event loop ---
running = True
playerstartposX = 100
playerstartposY = 100
playerwidth = 50
playerheight = 50
screen.fill((30,30,30))
newrect = pygame.draw.rect(screen, (255,0,0) , ( playerstartposX ,
playerstartposY ,
playerwidth ,
playerheight))
pygame.display.update()
while running:
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == 4: #if event is mouse motion
newrect.move(event.pos) #move the rectangle to mouse pos
pygame.display.update()
pygame.quit()
4 is not an event type. An event type is MOUSEMOTION (see pygame.event).
Create a pygame.Rect object:
newrect = pygame.Rect(playerstartposX, playerstartposY, playerwidth, playerheight)
Change its position when the event occurs:
if event.type == pygame.MOUSEMOTION:
newrect.center = event.pos
In the main application loop you've to continuously
handle the events
clear the display
draw the scene respectively rectangle
update the display
If you want to control the frames per second, then you can pass a parameter to the method .tick() of pygame.time.Clock rather than pygame.time.delay:
import pygame
pygame.init()
screen = pygame.display.set_mode((500,300))
clock = pygame.time.Clock()
running = True
playerstartposX = 100
playerstartposY = 100
playerwidth = 50
playerheight = 50
newrect = pygame.Rect(playerstartposX, playerstartposY, playerwidth, playerheight)
while running:
clock.tick(60)
# handle the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEMOTION:
newrect.center = event.pos
# clear the display
screen.fill((30,30,30))
# draw the rectangle
pygame.draw.rect(screen, (255,0,0), newrect)
# update the display
pygame.display.update()
pygame.quit()
First, the event type you need to check against is pygame.MOUSEMOTION (I believe it's 1024?) and you are checking with 4.
Then you have to redraw the rect on every iteration of the main loop to reflect the updated position

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