Change a value using mouse click with pygame - python

I am trying to create a nice and simple game just for practice with pygame, and I was trying to change a value using mouse click and I can't find out what to do
global item
ev = pygame.event.get()
item = 0
while True:
for event in ev:
if event.type == QUIT:
pygame.quit()
sys.exit()
for event in ev:
if event.type == pygame.MOUSEBUTTONDOWN:
item + 1
print (item)
After this is run, and I click the mouse, the game just freezes and nothing appears in the shell.
Please help
Thanks

Welcome to stackoverflow.
A simple script where clicking in the window increments item by 1 and prints it:
import pygame
pygame.init()
screen = pygame.display.set_mode((400,400))
clock = pygame.time.Clock()
item = 0
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
item += 1
print item
clock.tick(30)
pygame.quit()
This example shows the basic layout and flow of a pygame program.
Notice the for event in pygame.event.get() loop contains both of the loops in your example.
Hope this helps

Related

How do I make hotkeys in pygame

I'm making a game with pygame and I want to add a hotkey to close the game. Right now I am using:
keys_pressed = pygame.key.get_pressed()
# Hotkey for exiting game. CTRL + SHIFT + Q
if keys_pressed[pygame.K_LCTRL] and keys_pressed[pygame.K_LSHIFT] and keys_pressed[pygame.K_q]:
pygame.quit()
sys.exit()
This works in closing the game but if I press other keys with it (Ex/ CTRL + SHIFT + L + Q), it also closes the game. Is there a way I can fix this and have it only work if my desired keys are pressed and nothing else.
If you're handling KEYDOWN or KEYUP events, the event object has a bit field attribute called mod that will tell you which other modifier keys are pressed.
Here's a minimal example:
import pygame
screen = pygame.display.set_mode((480, 320))
pygame.init()
run = True
clock = pygame.time.Clock()
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
print(f"Key {pygame.key.name(event.key)} pressed")
if event.key == pygame.K_q:
if event.mod & pygame.KMOD_CTRL and event.mod & pygame.KMOD_SHIFT:
print("Hotkey Exit!")
run = False
elif event.type == pygame.KEYUP:
print(f"Key {pygame.key.name(event.key)} released")
screen.fill(pygame.Color("grey"))
pygame.display.update()
clock.tick(60) # limit to 60 FPS
pygame.quit()
When running the code and then pressing Ctrl+Shift+Q you'll see the following on the console:
$ python3.9 -i pyg_simple_hotkey.py
pygame 2.1.2 (SDL 2.0.18, Python 3.9.13)
Hello from the pygame community. https://www.pygame.org/contribute.html
Key left ctrl pressed
Key left shift pressed
Key q pressed
Hotkey Exit!
>>>
Just count the total number of keys pressed and include that as a condition in your if statement:
import pygame
import sys
import time
pygame.init()
display = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
while True:
clock.tick(100)
pygame.event.pump()
keys_pressed = pygame.key.get_pressed()
num_keys_pressed = len([x for x in keys_pressed if x])
if (
num_keys_pressed == 3
and keys_pressed[pygame.K_LCTRL]
and keys_pressed[pygame.K_LSHIFT]
and keys_pressed[pygame.K_q]
):
break
pygame.quit()

How to use multiple displays in pygame

I'm trying to add a title screen to my game in pygame using a title_screen function but whenever I call it it doesn't actually load the title screen, what am I doing wrong?
This is my code for the title screen function:
#started
started = False
#declaring surface
window = pygame.display.set_mode((WIDTH,HEIGHT), 0, 32)
pygame.display.set_caption('Pong')
def title_screen(canvas):
canvas.fill(BLACK)
#NOT WORKING
and this is how I'm calling it + how I'm calling the rest of the code for my game
while not started:
title_screen(window)
pygame.display.update()
fps.tick(60)
init()
while True:
draw(window)
for event in pygame.event.get():
if event.type == KEYDOWN:
keydown(event)
elif event.type == KEYUP:
keyup(event)
elif event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
fps.tick(60)
try to do pygame.init() before declaring window as an surface.

My game won't work when I use the controls, how do I fix it?

I can not get the controls to work, I try to press escape to open a menu I made but it will not open and I do not know if I am checking for events correctly, is there a way I am SUPPOSED to do it?
I tried using the functions for checking for different keys and I went to the spread-sheet that displays all the event names so you can map them at pygame.org but it will not open when I use the escape or also known as:
elif event.type == pygame.K_ESCAPE:
Frame.blit('Textures/GUI/loom.png', (0,0))
Heres the full code:
import pygame
#Textures/Blocks/loom_side.png
pygame.init()
Screen = "None"
DB = 0
Width = 800
Height = 600
Frame = pygame.display.set_mode((Width,Height))
pygame.display.set_caption("HypoPixel")
FPS = pygame.time.Clock()
def Raycast(TTR, RayXPos, RayYPos, RaySizeX, RaySizeY):
RaycastThis = pygame.image.load(TTR)
RaycastThis = pygame.transform.scale(RaycastThis,(RaySizeX,RaySizeY))
Frame.blit(RaycastThis, (RayXPos, RayYPos))
Loop = True
Raycast('Textures/Screens/Skybox/Earth.png',0,0,800,600)
while Loop == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.K_ESCAPE:
Frame.blit('Textures/GUI/loom.png', (0,0))
pygame.display.update()
FPS.tick(60)
I expected to get the loom GUI that I made. Once I tried to press escape, nothing happened.
pygame.K_ESCAPE is not event type (see pygame.event), but it is a pygame.key.
First check if a key was pressed by comparing the event type to pygame.KEYDOWN:
event.type == pygame.KEYDOWN
Then check if the event.key, which cause the event, is the pygame.K_ESCAPE key:
event.key == pygame.K_ESCAPE
Furthermore, the parameter to Surface.blit() has to be a Surface object rather than a filename.
first load the image to a Surface, by pygame.image.load(), then blit the Surface:
sprite = pygame.image.load('Textures/GUI/loom.png')
Frame.blit(sprite, (0,0))
Of course the your Raycast function can be called to do so:
Raycast('Textures/GUI/loom.png',0,0,800,600)
Your code should look somehow like this:
while Loop == True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
Raycast('Textures/GUI/loom.png',0,0,800,600)

pygame joystick slows down event handling

I am using a function to wait until a controller is present, but i ran into a problem. I wanted the function to stop when I press a key. Usually these events are handled just fine, but in this part it works terrible. The event seems to be added to the event queue very late or sometimes not at all. My guess is that it is because of the uninitialisation and reinitialisation of pygame.joystick. I just don't know how to solve it. I used this program to create the error:
import pygame, sys
from pygame.locals import *
pygame.init()
SCREEN = pygame.display.set_mode((500,500))
ChangeRun = False
pygame.joystick.init()
if pygame.joystick.get_count() == 0:
while pygame.joystick.get_count() == 0:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type in [KEYUP, KEYDOWN]:
if event.key == K_ESCAPE:
ChangeRun = True
if ChangeRun == True:
break
pygame.joystick.quit()
pygame.joystick.init()
pygame.quit()
sys.exit()
I wanted to use the escape key to end the program, but only after a lot of pressing it works. The same happens with the QUIT event. When printing the events I found that most of the time no event was found.
I use windows 8.1 and python 3.4 and pygame 1.9.2
I have no joystick so I can't test it but normally I would do this similar to mouse and I wouldn't wait for controller:
import pygame
from pygame.locals import *
pygame.init()
pygame.joystick.init()
screen = pygame.display.set_mode((500,500))
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == JOYBUTTONDOWN:
print 'joy:', event.joy, 'button:', event.button
# the end
pygame.joystick.quit()
pygame.quit()

multiple clicks registering in pygame

I'm trying to make a board that changes color upon a left mouse click. But when I click it cycles through is_square_clicked() 3 times. That's a problem, I only want it to do it once. As you can probably guess this causes an issue for my program. So how do I limit it to 1 pass through per click? Thanks!
def is_square_clicked(mousepos):
x, y = mousepos
for i in xrange(ROWS):
for j in xrange(COLS):
for k in xrange(3):
if x >= grid[i][j][1] and x <= grid[i][j][1] + BLOCK:
if y >= grid[i][j][2] and y <= grid[i][j][2] + BLOCK:
if grid[i][j][0] == 0:
grid[i][j][0] = 1
elif grid[i][j][0] == 1:
grid[i][j][0] = 0
while __name__ == '__main__':
tickFPS = Clock.tick(fps)
pygame.display.set_caption("Press Esc to quit. FPS: %.2f" % (Clock.get_fps()))
draw_grid()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
mousepos = pygame.mouse.get_pos()
is_square_clicked(mousepos)
pygame.display.update()
The reason that it cycles through is because you hold down the mouse long enough for it to check three times. I think if you have it wait between clicks, or you have it check not every time a cycle, it should be fixed.
im going to guess that since the game loops more than once each click it changes more then once
even though a click is very fast the loop is looping faster (depending on the FPS)
here is an example that will change the color of the screen on each click:
"""Very basic. Change the screen color with a mouse click."""
import os,sys #used for sys.exit and os.environ
import pygame #import the pygame module
from random import randint
class Control:
def __init__(self):
self.color = 0
def update(self,Surf):
self.event_loop() #Run the event loop every frame
Surf.fill(self.color) #Make updates to screen every frame
def event_loop(self):
for event in pygame.event.get(): #Check the events on the event queue
if event.type == pygame.MOUSEBUTTONDOWN:
#If the user clicks the screen, change the color.
self.color = [randint(0,255) for i in range(3)]
elif event.type == pygame.QUIT:
pygame.quit();sys.exit()
if __name__ == "__main__":
os.environ['SDL_VIDEO_CENTERED'] = '1' #Center the screen.
pygame.init() #Initialize Pygame
Screen = pygame.display.set_mode((500,500)) #Set the mode of the screen
MyClock = pygame.time.Clock() #Create a clock to restrict framerate
RunIt = Control()
while 1:
RunIt.update(Screen)
pygame.display.update() #Update the screen
MyClock.tick(60) #Restrict framerate
this code will blit a random color background each time you click so you can probably figure out the proper way to do it from the above code
Good Luck!

Categories