Reputation: 9
I am trying to create a wordle clone in python. I am not very experienced with pygame, and am trying to set up user input in the small grey boxes on the screen. However, the code I am using will either not correctly accept user input, or not correctly render it. (I suspect it's the latter.) I have looked at the code tutorial I am referencing many times, checked stack overflow posts, but none seem to work. I would expect that after typing and hitting return, the word would show up, as the word being rendered while you are typing has been removed for code simplicity. Any help would be appreciated.
import random
import pygame
word_options = ("birth", "happy", "nancy")
word = random.choice(word_options).upper
WIDTH = 600
HEIGHT = 700
MARGIN = 10
T_MARGIN = 100
B_MARGIN = 100
LR_MARGIN = 100
GREY = (225, 227, 229)
GREY_FILLED = (120, 124, 126)
GREEN = (6,214,160)
YELLOW = (255, 209, 102)
INPUT = ""
GUESSES = ["berry"]
ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
UNGUESSED = ALPHABET
GAME_OVER = False
pygame.init()
pygame.font.init()
pygame.display.set_caption("Nancdle")
SQ_SIZE = (WIDTH-4*MARGIN-2*LR_MARGIN) // 5
FONT = pygame.font.SysFont("free sans bold", SQ_SIZE)
FONT_SMALL = pygame.font.SysFont("free sans bold", SQ_SIZE//2)
#screen
screen = pygame.display.set_mode((WIDTH, HEIGHT))
white = (255, 255, 255)
#animation loop
animating = True
while animating:
screen.fill(white)
letters =FONT_SMALL.render(UNGUESSED, False, GREY_FILLED)
surface = letters.get_rect(center = (WIDTH//2, T_MARGIN//2))
screen.blit(letters, surface)
y = T_MARGIN
for i in range(6):
x = LR_MARGIN
for j in range(5):
square = pygame.Rect(x, y, SQ_SIZE, SQ_SIZE)
pygame.draw.rect(screen, GREY, square, 2)
#to add past letters/words
if i < len(GUESSES):
color = GREY_FILLED
pygame.draw.rect(screen, color, square)
letter = FONT.render(GUESSES[i][j], False, (255,255,255))
surface = letter.get_rect(center = (x+SQ_SIZE//2, y+SQ_SIZE//2))
screen.blit(letter, surface)
x += SQ_SIZE + MARGIN
y += SQ_SIZE + MARGIN
#to update screen
pygame.display.flip()
for event in pygame.event.get():
#so you can close window
if event.type == pygame.QUIT:
animating = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
if len(INPUT) == 5:
GUESSES.append(INPUT)
GAME_OVER = True if INPUT == ANSWER else false
INPUT = ""
elif len(INPUT) < 5 and not GAME_OVER:
INPUT = INPUT + event.unicode.upper()
I will gladly remove this post if the question is worded poorly or asked incorrectly.
Upvotes: 1
Views: 71
Reputation: 3245
Your code is only handling events for K_Return
, not any other keys. This is caused by indenting elif len(INPUT) < 5 and not GAME_OVER:
too far.
If you change your event handler code as follows, it should work:
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
if len(INPUT) == 5:
GUESSES.append(INPUT)
GAME_OVER = True if INPUT == word else False
INPUT = ""
elif len(INPUT) < 5 and not GAME_OVER:
INPUT = INPUT + event.unicode.upper()
Note I also had to replace ANSWER
with word
and capitalise false
.
You are using two spaces for indentation, it might have been easier to identify the scope mismatch if you'd used four.
Using event.unicode
is reasonably robust, but users can still add numbers and spaces. If you want to loop through all letter keys but don't want something horrible like if event.key in [pygame.K_a, pygame.K_b, ...
, you can use range
, e.g.
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
if len(INPUT) == 5:
GUESSES.append(INPUT)
GAME_OVER = True if INPUT == ANSWER else False
INPUT = ""
elif event.key in range(pygame.K_a, pygame.K_z + 1):
# any other letter keys pressed
if len(INPUT) < 5 and not GAME_OVER:
INPUT = INPUT + event.unicode.upper()
elif event.key in [pygame.K_BACKSPACE, pygame.K_DELETE]:
INPUT = INPUT[:-1] # don't need to check length
Upvotes: 0