Pygame Window not Responding after few seconds - python

The below code makes the window not respond when started.. I wanted to make hangman game and I got the logic done and I was just trying to make the window pop up and its not responding. Also when I run the program, when I type in the letter and type another one then it erases the previous letter a writes the new letter with the underscores. How can I make it so that it keeps the previous letter and prints it with the new letter?
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed = []
guessed.append(input("write your letter here -> "))
for i in word:
if i in guessed:
answer += i + " "
else:
answer += "_ "
print(answer)
answer = ""
pygame.quit()

Your game is not responding, because you ask for an input inside the application loop. input stops the application loop and waits for input to be confirmed. If you stop the application loop, the window stops responding. Use the KEYDOWN event to get an input in PyGame (see pygame.event):
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
guessed has to be initialized before the application loop. Don't reset it in the loop:
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
guessed = []
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
pygame.quit()

Your issue is here:
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed = [] # <-----ISSUE
Everytime the while loop starts over, you're assigning the guessed list to an empty list. What you need to do is place the guessed = [] before the while like this:
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
guessed = []
while running:
pygame.display.update() # <---- Needs to be called every loop passing to update the window
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed.append(input("write your letter here -> "))
for i in word:
if i in guessed:
answer += i + " "
else:
answer += "_ "
print(answer)
answer = ""
pygame.quit()
You also need to update your window every time the while loop goes by. I added it in the code I provided above.

you should create another string variable that has the same amount of letters as the word but instead of letters, it has dashes. you can do that using this:
guessedWord = []
for letter in word:
guessedWord.append("-")
then when the user guesses something you can substitute the guessedWord variable instead of the word. so basically you compare the guessed letter to the corresponding letter in the word and then if they were the same, you substitute the _ with the guessed letter. btw you don't have to put the guessed letters in a list unless you want to use them later.
i = -1
for letter in word:
i += 1
if letter == guessedLetter:
guessedWord[i] = guessedLetter
print(guessedLetter)

Related

Why Does the screen Crash after i Click it? [duplicate]

The below code makes the window not respond when started.. I wanted to make hangman game and I got the logic done and I was just trying to make the window pop up and its not responding. Also when I run the program, when I type in the letter and type another one then it erases the previous letter a writes the new letter with the underscores. How can I make it so that it keeps the previous letter and prints it with the new letter?
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed = []
guessed.append(input("write your letter here -> "))
for i in word:
if i in guessed:
answer += i + " "
else:
answer += "_ "
print(answer)
answer = ""
pygame.quit()
Your game is not responding, because you ask for an input inside the application loop. input stops the application loop and waits for input to be confirmed. If you stop the application loop, the window stops responding. Use the KEYDOWN event to get an input in PyGame (see pygame.event):
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
guessed has to be initialized before the application loop. Don't reset it in the loop:
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
guessed = []
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
pygame.quit()
Your issue is here:
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed = [] # <-----ISSUE
Everytime the while loop starts over, you're assigning the guessed list to an empty list. What you need to do is place the guessed = [] before the while like this:
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
guessed = []
while running:
pygame.display.update() # <---- Needs to be called every loop passing to update the window
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed.append(input("write your letter here -> "))
for i in word:
if i in guessed:
answer += i + " "
else:
answer += "_ "
print(answer)
answer = ""
pygame.quit()
You also need to update your window every time the while loop goes by. I added it in the code I provided above.
you should create another string variable that has the same amount of letters as the word but instead of letters, it has dashes. you can do that using this:
guessedWord = []
for letter in word:
guessedWord.append("-")
then when the user guesses something you can substitute the guessedWord variable instead of the word. so basically you compare the guessed letter to the corresponding letter in the word and then if they were the same, you substitute the _ with the guessed letter. btw you don't have to put the guessed letters in a list unless you want to use them later.
i = -1
for letter in word:
i += 1
if letter == guessedLetter:
guessedWord[i] = guessedLetter
print(guessedLetter)

ERROR: pygame.error: video system not initialized

I'm working through a python book. So far, all of the programs have worked, but now I'm stuck. I typed in the program, and I'm getting this error when I run it. I checked all of the lines several times, and I think everything's right. It is supposed to open a text window and 10 seconds later show a game character. At first, I had an indent error, but I fixed that. Now I'm getting this new error. it starts up and runs for about 0.5 seconds, but it immediately closes and gives this error. I'm using Python 3.8.10 On Windows 10 Pro 64-bit and this is the error: pygame.error: video system not initialized and here is the code:
import pygame
import time
import subprocess
pygame.init()
screen = pygame.display.set_mode((800, 250))
clock = pygame.time.Clock()
font = pygame.font.Font(None, 25)
pygame.time.set_timer(pygame.USEREVENT, 200)
def text_generator(text):
tmp = ""
for letter in text:
tmp += letter
if letter != " ":
yield tmp
class DynamicText(object):
def __init__(self, font, text, pos, autoreset=False):
self.done = False
self.font = font
self.text = text
self._gen = text_generator(self.text)
self.pos = pos
self.autoreset = autoreset
self.update()
def reset(self):
self._gen = text_generator(self.text)
self.done = False
self.update()
def update(self):
if not self.done:
try: self.rendered = self.font.render(next(self._gen), True, (0, 128, 0))
except StopIteration:
self.done = True
time.sleep(10)
subprocess.Popen("python C:\\Users\\david\\Documents\\pythonbook\\pygame1.py 1", shell=True)
def draw(self, screen):
screen.blit(self.rendered, self.pos)
text=("Steve has gone on a quest to defeat the Ender Dragon. Will he make it?")
message = DynamicText(font, text, (65, 120), autoreset=True)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: break
if event.type == pygame.USEREVENT: message.update()
else:
screen.fill(pygame.color.Color('black'))
message.draw(screen)
pygame.display.flip()
clock.tick(60)
continue
break
pygame.quit()
How can I figure out what the error message means? Or does anyone know?
You quit the game in every frame with pygame.quit(). quit the game after the application loop instead of in the application loop. Also why do you update the game just in the else case? The break statement in case of event.type == pygame.QUIT only breaks the event loop, but not the application loop. Change the control flow of your code:
# application loop
run = True
while run:
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT: run = False
if event.type == pygame.USEREVENT: message.update()
# redraw in every frame
screen.fill(pygame.color.Color('black'))
message.draw(screen)
pygame.display.flip()
clock.tick(60)
# quit after the application loop
pygame.quit()

Transition from one picture to another pygame [duplicate]

The below code makes the window not respond when started.. I wanted to make hangman game and I got the logic done and I was just trying to make the window pop up and its not responding. Also when I run the program, when I type in the letter and type another one then it erases the previous letter a writes the new letter with the underscores. How can I make it so that it keeps the previous letter and prints it with the new letter?
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed = []
guessed.append(input("write your letter here -> "))
for i in word:
if i in guessed:
answer += i + " "
else:
answer += "_ "
print(answer)
answer = ""
pygame.quit()
Your game is not responding, because you ask for an input inside the application loop. input stops the application loop and waits for input to be confirmed. If you stop the application loop, the window stops responding. Use the KEYDOWN event to get an input in PyGame (see pygame.event):
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
guessed has to be initialized before the application loop. Don't reset it in the loop:
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
guessed = []
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
guessed.append(event.unicode)
answer = ""
for c in word:
answer += c + " " if c in guessed else "_ "
print(answer)
pygame.quit()
Your issue is here:
while running:
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed = [] # <-----ISSUE
Everytime the while loop starts over, you're assigning the guessed list to an empty list. What you need to do is place the guessed = [] before the while like this:
import pygame
pygame.init()
running = True
window_width = 600
window_height = 600
window = pygame.display.set_mode((window_width, window_height))
clock = pygame.time.Clock()
word = "something"
guessed = []
while running:
pygame.display.update() # <---- Needs to be called every loop passing to update the window
dt = clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
answer = ""
guessed.append(input("write your letter here -> "))
for i in word:
if i in guessed:
answer += i + " "
else:
answer += "_ "
print(answer)
answer = ""
pygame.quit()
You also need to update your window every time the while loop goes by. I added it in the code I provided above.
you should create another string variable that has the same amount of letters as the word but instead of letters, it has dashes. you can do that using this:
guessedWord = []
for letter in word:
guessedWord.append("-")
then when the user guesses something you can substitute the guessedWord variable instead of the word. so basically you compare the guessed letter to the corresponding letter in the word and then if they were the same, you substitute the _ with the guessed letter. btw you don't have to put the guessed letters in a list unless you want to use them later.
i = -1
for letter in word:
i += 1
if letter == guessedLetter:
guessedWord[i] = guessedLetter
print(guessedLetter)

Detecting duration of a keypress python/pygame

In my program I'd like users to be able to hold down a button. Upon releasing the button I wish to print the duration that they held down the key. I have been trying to use the pygame clock function but have run into some trouble. The program works fine for the first keypress, but on later keypresses records any downtime between keypresses. Any help would be appreciated, here is my code:
import pygame
from pygame.locals import *
def main():
key = 0
pygame.init()
self = pygame.time.Clock()
surface_sz = 480
main_surface = pygame.display.set_mode((surface_sz, surface_sz))
small_rect = (300, 200, 150, 90)
some_color = (255, 0, 0)
while True:
ev = pygame.event.poll()
if ev.type == pygame.QUIT:
break;
elif ev.type == KEYUP:
if ev.key == K_SPACE: #Sets the key to be used
key += 1 #Updates counter for number of keypresses
while ev.type == KEYUP:
self.tick_busy_loop()
test = (self.get_time()/1000.0)
print "number: ", key, "duration: ", test
ev = pygame.event.poll()
main()
You can use keyboard library for this.
Here is a sample code that I made:
import keyboard, time
while True:
a = keyboard.read_event() #Reading the key
if a.name == "esc":break #Loop will break on pressing esc, you can remove that
elif a.event_type == "down": #If any button is pressed (Not talking about released) then wait for it to be released
t = time.time() #Getting time in sec
b = keyboard.read_event()
while not b.event_type == "up" and b.name == a.name: #Loop till the key event doesn't matches the old one
b = keyboard.read_event()
print('Pressed Key "'+ b.name + '" for ' + str(time.time()-t))
If you are looking for more solutions (for Pygame or Pynput), then you can find them on my answer on other related question.
I recommend using get_ticks() instead of get_time(). You should read about the differences, but I feel it may not work as desired since you are not explicitly calling self.tick().
The problem is your code is outputting the time between each KEYUP event. There is another way you make the code work by going over the events once per loop and continuing onward without having the nested while loop.
time_down = 0.0
time_elapsed = 0.0
while True:
for ev in pygame.event.get():
if ev.type == QUIT:
break # you had a semicolon here, there is no need for it
elif ev.type == KEYDOWN:
if ev.key == K_SPACE:
time_down = pygame.time.get_ticks()
elif ev.type == KEYUP:
if ev.key == K_SPACE:
key += 1
time_elapsed = (pygame.time.get_ticks() - time_down)/1000.0
print "number: ", key, "duration: ", time_elapsed
self.tick()
pygame.display.update()

Losing a "life" won't go down after an error? pygame

And I don't know why??? Everything else seems to be working just fine.. but when you click the wrong "button" in the game the error sounds works and it resets the pattern, but the lives that I have put up (which is 3) doesn't go down at all. Wondering if anyone could help me out with this please? (I won't be pasting my entire code, but this is where the command happens and all). Also if you couldn't tell, I'm creating a memory game. If anyone could lead me into the right direction then that could be a big help for me. Thanks in advance!
def main():
global FPSCLOCK, DISPLAYSURF, BASICFONT, BEEP1, BEEP2, BEEP3, BEEP4
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Simulate')
# font
BASICFONT = pygame.font.Font(None, 30)
# load the sound files
BEEP1 = pygame.mixer.Sound('beep1.wav')
BEEP2 = pygame.mixer.Sound('beep2.wav')
BEEP3 = pygame.mixer.Sound('beep3.wav')
BEEP4 = pygame.mixer.Sound('beep4.wav')
SOUNDTRACK = pygame.mixer.Sound('soundtrack.wav')
ERROR = pygame.mixer.Sound('error.wav')
# initialize some variables for a new game
pattern = [] # stores the pattern of colors
currentStep = 0 # the color the player must push next
lastClickTime = 0 # timestamp of the player's last button push
score = 0
# plays the soundtrack music
SOUNDTRACK.play(-1, 0, 1000)
# start-up screen
text = BASICFONT.render('Press enter to play!', 1, WHITE)
textRect = text.get_rect()
textRect.centerx = DISPLAYSURF.get_rect().centerx
textRect.y = 150
DISPLAYSURF.blit(text, textRect)
# update the screen
pygame.display.update()
# the "press enter" command
waiting = True
while waiting:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
waiting = False
# when False, the pattern is playing. when True, waiting for the player to click a colored button:
waitingForInput = False
while True: # main game loop
clickedButton = None # button that was clicked (set to YELLOW, RED, GREEN, or BLUE)
DISPLAYSURF.fill(bgColor)
drawButtons()
# amount of lives
lives = 3
img = BASICFONT.render('I'*lives, 1, WHITE)
livesRect = img.get_rect()
livesRect.topleft = (10, 10)
DISPLAYSURF.blit(img, livesRect)
scoreSurf = BASICFONT.render('Score: ' + str(score), 1, WHITE)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (WIDTH - 100, 10)
DISPLAYSURF.blit(scoreSurf, scoreRect)
checkForQuit()
for event in pygame.event.get(): # event handling loop
if event.type == MOUSEBUTTONUP:
mousex, mousey = event.pos
clickedButton = getButtonClicked(mousex, mousey)
if not waitingForInput:
# play the pattern
pygame.display.update()
pygame.time.wait(1000)
pattern.append(random.choice((YELLOW, BLUE, RED, GREEN)))
for button in pattern:
flashButtonAnimation(button)
pygame.time.wait(FLASHDELAY)
waitingForInput = True
else:
# wait for the player to enter buttons
if clickedButton and clickedButton == pattern[currentStep]:
# pushed the correct button
flashButtonAnimation(clickedButton)
currentStep += 1
lastClickTime = time.time()
if currentStep == len(pattern):
# pushed the last button in the pattern
score += 1
waitingForInput = False
currentStep = 0 # reset back to first step
elif (clickedButton and clickedButton != pattern[currentStep]) or (currentStep != 0 and time.time() - TIMEOUT > lastClickTime):
# pushed the incorrect button, or has timed out
pattern = []
currentStep = 0
waitingForInput = False
lives = lives - 1
SOUNDTRACK.stop()
ERROR.play()
pygame.time.wait(1000)
SOUNDTRACK.play(-1, 0, 1000)
pygame.display.update()
if lives < 1:
gameOverAnimation()
# reset the variables for a new game:
pattern = []
currentStep = 0
waitingForInput = False
score = 0
pygame.time.wait(1000)
pygame.display.update()
FPSCLOCK.tick(FPS)
You set lives = 3 inside your main loop, instead of before it.
This means that you reset it to 3 on every iteration of the loop.

Categories