Search code examples
pythoneventspygameinputbox

pygame event input box


I'm working on a game but i don't quite understand how the event handling works. I want to make it so when the player inputs the correct first number of 6-digit number the, keyboard focus will be on the input box to the right, but i have a very limited understanding of Pygame and i have been scratching my head and searching for a solution for a while. i'd be very grateful if someone could help.

# Import needed sub-programs to act as tools with given function
import pygame
import time
import random

# Initialising pygame sub-program
pygame.init()

# Calling height and width of the frame of the program as Variables
display_height = 900
display_width = 600

# Changing essential colours from RGB colour code to Variables
black = (0,0,0)
white = (255,255,255)
grey = (96, 96, 96)
yellow = (255, 233, 0)
orange = (255, 147, 7)
orange2 = (255, 102, 0)
dark_orange = (175, 105, 0)
green = (0, 255, 12)
dark_green = (3, 130, 8)
dark_red = (114, 9, 0)
brown = (81, 48, 16)
red = (255,0,0)
blue = (0,97,255)

# Sets the height and width of program using variables on lines 7, 8
gamedisplay = pygame.display.set_mode((display_height,display_width))

# Sets title of the Window
pygame.display.set_caption('For-Get-Ful')

# A variable to set up a method of maintaining a certain FPS count
clock = pygame.time.Clock()

# Starts the program background off as white from Variable line 12
gamedisplay.fill(white)

# Update the screen to show off the colour implemented on line 38
pygame.display.flip()

# A tool to display any text on any surface
def text_objects(text, font, color):
textSurface = font.render(text, True, color)
return textSurface, textSurface.get_rect()

# a tool to display the in-game numbers
def game_subject(text,dw,dh):
largeText = pygame.font.Font('freesansbold.ttf',115)
TextSurf, TextRect = text_objects(text, largeText, black)
TextRect.center = (dw,dh)
gamedisplay.blit(TextSurf, TextRect)

def game_loop():
font = pygame.font.Font("freesansbold.ttf", 200)
text1 = ''
text2 = ''
text3 = ''
text4 = ''
text5 = ''
text6 = ''

# In-game random 6-digit number generator
subject1 = random.randint(1,9)
subject1 = str(subject1)

subject2 = random.randint(1,9)
subject2 = str(subject2)

subject3 = random.randint(1,9)
subject3 = str(subject3)

subject4 = random.randint(1,9)
subject4 = str(subject4)

subject5 = random.randint(1,9)
subject5 = str(subject5)

subject6 = random.randint(1,9)
subject6 = str(subject6)

subjects_tog = (subject1,subject2,subject3,subject4,subject5,subject6)
subjects_tog = str(subjects_tog)

# In-game objects
time_bar = pygame.Rect(0,590,900,80)

# In-game objects
time_bar_2 = pygame.Rect(0,270,900,35)

# In-game objects
time_bar_3 = pygame.Rect(0,315,900,25)

# In-game objects
time_bar_4 = pygame.Rect(0,350,900,15)

input_box = pygame.Rect(5,375,140,205)
input_box_2 = pygame.Rect(155,375,140,205)
input_box_3 = pygame.Rect(305,375,140,205)
input_box_4 = pygame.Rect(455,375,140,205)
input_box_5 = pygame.Rect(605,375,140,205)
input_box_6 = pygame.Rect(755,375,140,205)

# Random box color generator
subject_color = (blue,green,red,yellow)
ran_color1 = random.choice(subject_color)
ran_color2 = random.choice(subject_color)
ran_color3 = random.choice(subject_color)
ran_color4 = random.choice(subject_color)
ran_color5 = random.choice(subject_color)
ran_color6 = random.choice(subject_color)
ran_color7 = random.choice(subject_color)
ran_color8 = random.choice(subject_color)
ran_color9 = random.choice(subject_color)
ran_color10 = random.choice(subject_color)

here is where my problem is!!

loop = True

# To keep the game running longer than 1 frame
while loop:
  for event in pygame.event.get():
      if event.type == pygame.QUIT:
          pygame.quit()
          quit()
      pressed = pygame.key.get_pressed()
      if pressed[pygame.K_ESCAPE]:
         game_intro()
      elif event.type == pygame.KEYDOWN:
              if event.key == pygame.K_RETURN:
                  if text1 == subject1:
                      text1 = str(text1)
                      print("correct")
                  text1 = ''
              elif event.key == pygame.K_BACKSPACE:
                  text1 = text1[:-1]
              else:
                  text1 += event.unicode

  pygame.display.update()
  gamedisplay.fill(black)
  txt_surface = font.render(text1, True, black)
  txt_surface2 = font.render(text2, True, black)
  txt_surface3 = font.render(text3, True, black)
  txt_surface4 = font.render(text4, True, black)
  txt_surface5 = font.render(text5, True, black)
  txt_surface6 = font.render(text6, True, black)

  pygame.draw.rect(gamedisplay, ran_color5, input_box)
  gamedisplay.blit(txt_surface, (input_box.x+5, input_box.y+5))

  pygame.draw.rect(gamedisplay, ran_color6, input_box_2)
  gamedisplay.blit(txt_surface2, (input_box_2.x+5, input_box_2.y+5))

  pygame.draw.rect(gamedisplay, ran_color7, input_box_3)
  gamedisplay.blit(txt_surface3, (input_box_3.x+5, input_box_3.y+5))

  pygame.draw.rect(gamedisplay, ran_color8, input_box_4)
  gamedisplay.blit(txt_surface4, (input_box_4.x+5, input_box_4.y+5))

  pygame.draw.rect(gamedisplay, ran_color9, input_box_5)
  gamedisplay.blit(txt_surface5, (input_box_5.x+5, input_box_5.y+5))

  pygame.draw.rect(gamedisplay, ran_color10, input_box_6)
  gamedisplay.blit(txt_surface6, (input_box_6.x+5, input_box_6.y+5))

  # Subject display squares
  pygame.draw.rect(gamedisplay, orange,(5,10,140,250))
  pygame.draw.rect(gamedisplay, orange,(155,10,140,250))
  pygame.draw.rect(gamedisplay, orange,(305,10,140,250))
  pygame.draw.rect(gamedisplay, orange,(455,10,140,250))
  pygame.draw.rect(gamedisplay, orange,(605,10,140,250))
  pygame.draw.rect(gamedisplay, orange,(755,10,140,250))

  # Time bar and its function
  pygame.draw.rect(gamedisplay, ran_color1, time_bar)
  time_bar_numb = time_bar.move_ip(-2,0)

  # Time bar and its function
  pygame.draw.rect(gamedisplay, ran_color2, time_bar_2)
  time_bar_numb_2 = time_bar_2.move_ip(+2,0)

  # Time bar and its function
  pygame.draw.rect(gamedisplay, ran_color3, time_bar_3)
  time_bar_numb_3 = time_bar_3.move_ip(-2,0)

  # Time bar and its function
  pygame.draw.rect(gamedisplay, ran_color4, time_bar_4)
  time_bar_numb_4 = time_bar_4.move_ip(+2,0)

  # Random in-game subject numbers
  game_subject(subject1,73.5,140)
  game_subject(subject2,225,140)
  game_subject(subject3,375,140)
  game_subject(subject4,525,140)
  game_subject(subject5,675,140)
  game_subject(subject6,827,140)

  pygame.display.update()
  clock.tick(60)

Solution

  • I'd put the input_box rects into a list and then use for loops to draw the boxes and blit the numbers. You can use only one text variable instead of text1, text2, etc. and iterate over the characters in this variable to blit them.

    The built-in zip function can be used to zip the text and the boxes together, so that you have the number and the coordinates available at the same time (alternatively use indexes).

    input_boxes = [
        pygame.Rect(5,375,140,205),
        pygame.Rect(155,375,140,205),
        pygame.Rect(305,375,140,205),
        pygame.Rect(455,375,140,205),
        pygame.Rect(605,375,140,205),
        pygame.Rect(755,375,140,205),
        ]
    

    In the while loop:

    # Draw the boxes.
    for box in input_boxes:
        pygame.draw.rect(gamedisplay, ran_color1, box)
    
    # Blit one number after the other at the corresponding box.
    for number, box in zip(text, input_boxes):
        txt_surface = font.render(number, True, black)
        gamedisplay.blit(txt_surface, (box.x+5, box.y+5))
    

    If you're not familiar with the zip function, you can use indexes:

    for i in range(len(text)):
        txt_surface = font.render(text[i], True, black)
        gamedisplay.blit(txt_surface, (input_boxes[i].x+5, input_boxes[i].y+5))