2017-08-15 94 views
1

我想將用戶輸入的文本輸出到屏幕。每次用戶按下返回鍵時,輸入的文本都應該顯示在屏幕上。對於文本輸入,我使用這個[text_input模塊](https://github.com/Nearoo/pygame-text-input)。將用戶文本輸入屏幕

這裏是我想出了迄今爲止代碼:

import pygame_textinput 
import pygame 
pygame.init() 

# Set some parameters 
duration = 5.0 
time = pygame.time.get_ticks()/1000 

screen = pygame.display.set_mode((400, 400)) 
clock = pygame.time.Clock() 

yoffset = 5 
# Function that positions user input rects on screen 
def renderInput(text, xoffset, yoffset): 
    font = pygame.font.SysFont("arial", 20) 
    renderText = font.render(text, False, (0, 0, 0)) 
    rectText = renderText.get_rect() 
    rectText = rectText.move((0 + xoffset), (screen.get_height()/2 + yoffset)) 
    return renderText, rectText 

# Fills the screen once at the beginning 
screen.fill((225, 225, 225)) 

while (pygame.time.get_ticks()/1000) < time + duration: 
    # creat new text input object on every trial 
    textinput = pygame_textinput.TextInput() 

    while True: 
     # Fills the surface after each keypress 
     screen.fill((225, 225, 225)) 

     # Check events 
     events = pygame.event.get() 
     for event in events: 
      if event.type == pygame.QUIT: 
       exit() 

     # Feed with events every frame 
     # This evaluates to True once Return is pressed 
     if textinput.update(events): 
      userInput = textinput.get_text() 
      yoffset += 20 
      break 

     # Blit surface onto the screen 
     screen.blit(textinput.get_surface(), (10, 10)) 
     # Update screen 
     pygame.display.update() 
     clock.tick(30) 

    # Blits user input to screen each time "Return" is pressed 
    # First get input text and the rectangle of the text 
    text, textrect = renderInput(userInput, 5, yoffset) 
    # Then blit it to the screen 
    screen.blit(text, textrect) 
    pygame.display.update() 

我的問題是,如果我不while循環來處理輸入中的每個按鍵之後填充屏幕的阻擊器只適用。如果我這樣做了,那麼每次用戶按下Return鍵後,文本輸入都不會被清除。

因此,有一種方法可以在每次按鍵後重新繪製,並且每次用戶按下返回按鈕後都會顯示下面的文本。

謝謝。

回答

1

如果我理解正確,輸入字段中的文本應該被清除,並且它應該在屏幕的主區域blit。如果用戶按Enter鍵,然後創建一個新的實例來清除輸入字段,我會將該文本分配給user_input變量。

我試着簡化你的代碼,因爲兩個while循環有點混亂,我不確定它們的目的是什麼。遊戲中通常應該只有一個while循環。

import pygame 
import pygame_textinput 


pygame.init() 

screen = pygame.display.set_mode((400, 400)) 
clock = pygame.time.Clock() 
font = pygame.font.SysFont("arial", 20) 

textinput = pygame_textinput.TextInput() 
user_input = '' 

done = False 

while not done: 
    events = pygame.event.get() 
    for event in events: 
     if event.type == pygame.QUIT: 
      done = True 

    if textinput.update(events): 
     user_input = textinput.get_text() 
     textinput = pygame_textinput.TextInput() 

    # Draw everything. 
    screen.fill((225, 225, 225)) 

    screen.blit(textinput.get_surface(), (10, 10)) 

    user_input_surface = font.render(user_input, True, (30, 80, 100)) 
    screen.blit(user_input_surface, (10, 50)) 

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

pygame.quit() 

編輯:在這個版本中我呈現的文本表面添加到列表,並與偏移的blit他們。

import pygame 
import pygame_textinput 


pygame.init() 

screen = pygame.display.set_mode((400, 400)) 
clock = pygame.time.Clock() 
font = pygame.font.SysFont("arial", 20) 

textinput = pygame_textinput.TextInput() 
user_inputs = [] 

done = False 

while not done: 
    events = pygame.event.get() 
    for event in events: 
     if event.type == pygame.QUIT: 
      done = True 

    if textinput.update(events): 
     user_inputs.append(
      font.render(textinput.get_text(), True, (30, 80, 100))) 
     textinput = pygame_textinput.TextInput() 

    screen.fill((225, 225, 225)) 

    screen.blit(textinput.get_surface(), (10, 10)) 

    for y, text_surf in enumerate(user_inputs): 
     screen.blit(text_surf, (10, 50+30*y)) 

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

pygame.quit() 

編輯2:要獲取表格,您可以使用模數來計算列偏移量的行偏移量和平面劃分。這個例子的問題是,如果文本表面太寬,文本表面可能會重疊。

for n, text_surf in enumerate(user_inputs): 
    # 5 rows. Offset = 30 pixels. 
    y_pos = 50 + (n%5) * 30 
    # After 5 rows add a new column. Offset = 100 pixels. 
    x_pos = 10 + n // 5 * 100 
    screen.blit(text_surf, (x_pos, y_pos)) 
+0

非常感謝這個有用的例子。一旦用戶點擊返回,創建一個新實例返回是一個很好的解決方法。但是,我認爲我沒有足夠詳細地說明我的問題。我有第一個while循環和渲染到屏幕的函數的原因如下:我希望用戶輸入顯示在下面(如您執行的那樣),但是當用戶輸入其他內容並再次返回時,該輸入應該顯示在已經顯示的輸入下方。這個過程一直持續到計時器用完爲止(第一次while循環)。 – Ivan

+0

在這種情況下,我可能會渲染文本表面並將其附加到列表中。然後你可以遍歷這個曲面列表,並用主循環中的偏移量對它們進行處理。 – skrx

1

我編輯了包含您的建議的代碼。非常感謝,這似乎解決了我的問題。這是當前版本包括定時器:

import pygame_textinput 
import pygame 
pygame.init() 

# Set some parameters 
duration = 5.0 
time = pygame.time.get_ticks()/1000 
xoffset = 5 
yoffset = 5 

screen = pygame.display.set_mode((400, 400)) 
font = pygame.font.SysFont("arial", 20) 
clock = pygame.time.Clock() 

# Creates textinput instance and an empty list to store inputs 
textinput = pygame_textinput.TextInput() 
userInputs = [] 

# Fills the screen once at the beginning 
screen.fill((225, 225, 225)) 

while (pygame.time.get_ticks()/1000) < time + duration: 

    # Check events 
    events = pygame.event.get() 
    for event in events: 
     if event.type == pygame.QUIT: 
      exit() 

    # Feed with events every frame 
    # This evaluates to True once Return is pressed 
    if textinput.update(events): 
     userInputs.append(font.render(textinput.get_text(), True, (30, 80, 100))) 
     textinput = pygame_textinput.TextInput() 

    # Fill screen 
    screen.fill((225, 225, 225)) 
    # Blit its surface onto the screen 
    screen.blit(textinput.get_surface(), (screen.get_rect().centerx, screen.get_rect().height/5)) 

    for y, text_surf in enumerate(userInputs): 
      screen.blit(text_surf, (10, (screen.get_rect().height/4)+30*y)) 

    # Update screen 
    pygame.display.update() 
    clock.tick(30) 

我不想你懶得多,但現在我有一個問題,更留下了我有麻煩的解決。一旦退出屏幕的下邊框,是否可以在第二列中顯示文本輸入?例如,如果用戶輸入了大量不合適的單詞,是否可以將下一個文本輸入移動到右側,並使其在第一個輸入旁邊開始(創建第二列以便說出)。感謝您的幫助,我真的很滿意。

+0

我在我的答案中添加了一個基本示例,向您展示如何繪製表格。 – skrx

+0

謝謝你的解決。我正在嘗試一些部門,但現在你提到模塊和地板部門,它變得清晰:) – Ivan