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
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)
I am currently making a fighting game and was wondering how command inputs could be added. I understand it is kind of irrelevant and many substitutes are possible, but it would be nice to use familiar fighting game inputs.
I currently have something like this:
keys = pygame.key.get_pressed()
if keys[pygame.K_DOWN]:
commandcount +=1
if commandcount > 0 and commandcount < 30 and keys[pygame.K_RIGHT] and keys[pygame.K_z]:
player1.projectile = True
The "commandcount" helps keep the window of action available until a certain amount of time.
The main problem with this is that you could still press the inputs in whatever order and the projectile would still come out.
Thanks
Try using the pygame.KEYDOWN events instead of pygame.key.get_pressed() so the order can be observed. Use a list to keep track of the order of these KEYDOWN events. When the order matches a specific combo then execute the move and reset the list. The list also gets reset after a certain amount of time with a combo. I made an example program with the combo down, right, z activating a fireball.
import pygame
# pygame setup
pygame.init()
# Open a window on the screen
width, height = 600, 600
screen = pygame.display.set_mode((width, height))
def main():
clock = pygame.time.Clock()
black = (0, 0, 0)
move_combo = []
frames_without_combo = 0
while True:
clock.tick(30) # number of loops per second
frames_without_combo += 1
if frames_without_combo > 30 or len(move_combo) > 2:
print("COMBO RESET")
frames_without_combo = 0
move_combo = []
screen.fill(black)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
move_combo.append(event.key) # Only keys for combos should be added
if move_combo == [pygame.K_DOWN, pygame.K_RIGHT, pygame.K_z]:
print("FIRE BALL")
frames_without_combo = 0
print(move_combo)
pygame.display.update()
main()
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)
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()
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.