I have the following code in which I try to react to user events in pygame:
import pygame
from pygame.locals import *
from pygame.time import set_timer
from sys import exit
def timerFunc():
print "Timer CallBack"
pygame.init()
screen = pygame.display.set_mode((640,480),0,32)
set_timer(USEREVENT+1, 1000)
while True:
pressed_keys = pygame.key.get_pressed()
if pressed_keys[K_SPACE]:
exit()
for event in pygame.event.get():
print event
if event == QUIT:
exit()
if event == USEREVENT+1:
timerFunc()
Unfortunately the timerFunc() doesn't get executed, events are propagated by the set_timer() function, since in the output I get:
<Event(25-UserEvent {'code': 0})
You need to use the event.type attribute:
for event in pygame.event.get():
print event
if event.type == QUIT:
exit()
if event.type == USEREVENT+1:
timerFunc()
Related
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()
I'm using Python 3.5, and I want to make multi-keystroke function.
I mean, I want to make a function that notices Ctrl+S and Q.
But my program doesn't notice it.
Here's my code:
import threading, pygame, sys
from pygame.locals import *
from time import sleep
pygame.init()
screen = pygame.display.set_mode((1160, 640), 0, 0)
screen.fill((255, 255, 255))
pygame.display.flip()
def background():
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if pygame.key.get_mods() & pygame.KMOD_CTRL and event.key == pygame.K_s:
print('GOOD')
def foreground():
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
print('HELLO_WORLD')
if event.type == QUIT:
pygame.quit()
sys.exit()
b = threading.Thread(name='background', target=background)
b.start()
foreground()
By calling b.start(), you let the program go into the infinite loop of listening Ctrl+S event. The event of key combination, once obtained in the background thread, will not be released back into the event queue. and the foreground function won't be able to capture and process it.
If you want your program to be able to process different key combination. You should let one function to listen to key press event, and dispatch the event to different processing functions.
I am trying to change the mouse position programmatically, in PyGame, using its mouse API:
from pygame import mouse
mouse.set_pos(0, 0)
This seems to work fine in windowed mode, but in fullscreen mode, nothing happens. I've tried forcefully making the cursor invisible then showing it again, in vain hope that it would reset the thing, but no luck.
EDIT In the interest of full disclosure, I'm not using PyGame directly. I'm using OpenSesame, with its "Legacy" backend (which is essentially a wrapper over PyGame). However, I do have access to PyGame primitives, if needs be.
https://www.pygame.org/docs/ref/mouse.html#comment_pygame_mouse_get_pos
Test with a print to see if 0,0 coords are on the screen
Python 2.7
#!/usr/bin/python
import pygame
from pygame.locals import *
def main():
pygame.init()
pygame.display.set_mode((300,200))
pygame.display.set_caption('Testing')
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == KEYDOWN and event.key == K_ESCAPE:
running = False
if event.type == MOUSEBUTTONDOWN:
#print event.button
print pygame.mouse.get_pos()
pygame.display.quit()
if __name__ == '__main__':
main()
Python 3.4
#!/usr/bin/python
import pygame
from pygame.locals import *
def main():
pygame.init()
pygame.display.set_mode((300,200))
pygame.display.set_caption('Testing')
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == KEYDOWN and event.key == K_ESCAPE:
running = False
if event.type == MOUSEBUTTONDOWN:
#print event.button
print(pygame.mouse.get_pos())
pygame.display.quit()
if __name__ == '__main__':
main()
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()
When I am trying to catch keys pressed, they are printed in Terminal, but not caught by pygame and the script. Script is executed as follows:
>>>import scriptname
>>>scriptname.wa()
scriptname file:
import pygame
from pygame.locals import *
def wa():
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
alive_key = True
while alive_key:
for event in pygame.event.get():
if event.type == QUIT:
alive_key = False
elif event.type == KEYDOWN and event.key == K_q:
print '\nThis is not happening\n'
screen.fill((0, 0, 0))
if pygame.mouse.get_pressed()[0]:
pygame.event.post(
pygame.event.Event(KEYDOWN, key=K_q, mod=0, unicode=u'q'))
pygame.display.update()
pygame.quit()
If events are created on mouse press (as presented in code), they work.
I am using OS X 10.8.5, python 2.7, pygame2.7 1.9.1. Everything works perfectly in Windows 7 with similar configuration.
Thanks!
change your code to:
elif event.type == KEYDOWN or event.type == pygame.KEYDOWN:
# for testing purpose
print event
if event.key == pygame.K_q:
print '\nThis is not happening\n
I'm using OS X 10.9.5, python 2.7.7, pygame-1.9.2pre-py2.7-macosx10.7. Had the similar problem as yours earlier. I found this solution here: http://content.gpwiki.org/index.php/Python:Pygame_keyboard_input
I think this is not mac's fault, possibly.