I'm using PyGame on Ubuntu and I want to make a while loop that ends when the user presses any button on the keyboard.
This code does not leave the loop, and Eclipse gives no errors and no warnings but never leaves the loop. What is wrong?
import time
import pygame
pygame.init()
test = False
while not test:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
print "gotcha"
test = True;
break;
print "Still looping"
time.sleep(1);
print "made it out of the loop" ;
Ideally every second "still loopin" should be printed to the screen until I press any key, when "made it out of the loop" should be printed.
This doesn't happen: the loops continues forever (until I terminate the script).
You need to
According to the game programming wiki:
If you do not set a pygame display pygame screen, no input will get to pygame's event handling.
import time
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption('Pygame Caption')
test = False
while not test:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
print "gotcha"
test = True
break
print "Still looping"
time.sleep(1)
print "made it out of the loop"
Related
So I started programming a game for a school project and currently face a problem with event.type KEYDOWN.
This is my Code. When running it a window opens but it stays completely black without showing either the background color or the sprite. I tried pinpointing the issue with the print() commands to see in what line exactly the code stops working. Every, except the last print command is executed, which leaves me to believe the While Loop is the cause of my problem.
import pygame
from pygame.locals import *
print("Import complete")
WIDTH = 640
HEIGHT = 480
TITLE = "Tales of Tesbold"
print("Window complete")
Tesbold = Actor("tesbold.png") #Sprites vordefinition
Tesbold.x = 200
Tesbold.y = 100
print("Tesbold complete")
wechsel = True
def draw(): #Hintergrund und alle Sprites
screen.clear()
screen.fill((200,200,200))
Tesbold.draw()
print("Draw Screen complete")
while True:
for event in pygame.event.get():
if event.type == quit:
sys.exit()
if event.type == KEYDOWN:
if(event.key == K_RIGHT):
Tesbold.x += 10
print("While Loop complete")
This is the console output:
pygame 2.0.1 (SDL 2.0.14, Python 3.8.5)
Hello from the pygame community. https://www.pygame.org/contribute.html
Import complete
Window complete
Tesbold complete
Draw Screen complete
---------- FINISHED ----------
exit code: 2 status: 0
Can someone tell me what I did wrong for it to not function anymore?
Python is case sensitive. The event type enumerators are all written in capital letters. See pygame.event module:
if event.type == quit:
if event.type == QUIT:
pygame.quit() is a function and uninitialize all pygame modules.
I use device files to read entries with the open() and f.read() functions, but the problem is that read() doesn't stop until there is a new entry. So I can't let my program do anything else...
running = True
with open("/dev/input/js0", "rb") as f:
while running:
event = f.read(8)
pygame.display.flip()
clock.tick(30)
pygame.quit()
For example, here I can only draw the window if the device is used.
Thanks for reading.
One option is to use Python's select.poll method, which lets you check to see if a file descriptor has any input available. We could rewrite your code something like this:
import select
import pygame
pygame.init()
pygame.display.init()
pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
running = True
poll = select.poll()
with open("/dev/input/js0", "rb") as f:
poll.register(f, select.POLLIN)
while running:
events = poll.poll(0)
if events:
event = f.read(8)
print('FLIP!')
pygame.display.flip()
clock.tick(30)
pygame.quit()
For more reading, look for articles on "non blocking io" with Python.
Alternately, you could use Pygame's event handling code rather than reading directly from /dev/input/js0 yourself. For example:
import pygame
pygame.init()
pygame.joystick.init()
pygame.display.init()
pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
js = pygame.joystick.Joystick(0)
js.init()
running = True
while running:
event = pygame.event.poll()
if event.type == pygame.QUIT:
break
if event.type == pygame.JOYHATMOTION:
print('FLIP!')
pygame.display.flip()
clock.tick(30)
pygame.quit()
The above code will only react to hat pressed, but you could easily extend it to listen to axis and button actions as well.
I want to exit the fullscreen mode of my pygame display by pressing f. I understand that I can archive exit fullscreen by:
pygame.display.toggle_fullscreen()
And get the keyboard event by:
for event in pygame.event.get():
if event.type == KEYDOWN:
logging.warning("event")
if event.key == K_f:
logging.info("TOGGLE: toggle fullscreen")
return 1
My problem is that I need to leave the function where the display is initialized. I can not stay there until an event comes up. But I noticed that getting the keyboard event outside this function does not work (no display -> no keyboard). Since I can not have two displays, I can note "fake" one for the keyboard event. I also don't want to rebuild my display again if there are no relevant events (otherwise I could probably just call the initializing function from time to time and check my events in there).
Is it possibly to disallow pygame making use of the keyboard? So I can use Keyboardinterrupt to get out of the fullscreen? Am I missing something? Thank you for any help. I hope it is not to confusing.
The documentation for pygame.display.toggle_fullscreen() states:
This function only works under the UNIX X11 video driver. For most situations it is better to call pygame.display.set_mode() with new display flags.
So it looks like you'll probably have to recreate your top level surface.
Here's a minimal example that implements this:
import pygame
pygame.init()
def init_screen(full=False):
resolution = (1024, 768)
if full:
return pygame.display.set_mode(resolution, pygame.FULLSCREEN)
else:
return pygame.display.set_mode(resolution)
full_screen = False
screen = init_screen(full_screen)
finished = False
clock = pygame.time.Clock() #for limiting FPS
while not finished:
for event in pygame.event.get():
if event.type == pygame.QUIT:
finished = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
finished = True
elif event.key == pygame.K_f:
full_screen = not full_screen
screen = init_screen(full_screen)
if full_screen:
screen.fill(pygame.color.Color("grey"))
else:
screen.fill(pygame.color.Color("aquamarine"))
pygame.display.flip()
clock.tick(60)
pygame.quit()
If you'd like any further clarifications, let us know.
I wrote a little Python script that is supposed to run a webcam-preview and exit it when ESC is pressed (using Pygame).
It kind of works, but more often than not it freezes the screen..
Does anyone see any issues with this code?
#!/usr/bin/python3
from picamera import PiCamera
camera = PiCamera()
camera.start_preview()
import pygame
import subprocess
def main():
pygame.init()
screen = pygame.display.set_mode((10, 10))
while True:
pressed = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
camera.stop_preview()
return
main()
You need to have a call to pygame.display.flip() somewhere in your game loop otherwise it'll act like it's frozen.
I am learning pygame and have been working on examples given in 'Python Crash Course' book by Eric Matthews (https://g.co/kgs/WP5fay). I have installed pygame version 1.9.3 on macOS High Sierra.
When I run the following program, a window opens and when I click 'X' to close it, the window freezes and the curses keeps circling and I get a python not responding error in activity monitor. I have tried a number of option to fix the problem but it is not going away.
import pygame
import sys
def run_game():
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Alien Invasion')
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.display.flip()
run_game() #when I run this function, a window opens and freezes a couple of seconds after
You have to terminate the application loop and uninitialize all pygame modules with pygame.quit():
def run_game():
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Alien Invasion')
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.flip()
pygame.quit()
sys.exit()