2017-08-15 5 views
1

ユーザーが画面に入力したテキストをblitします。ユーザーがReturnキーを押すたびに、入力されたテキストを画面に合わせる必要があります。テキスト入力の場合は、この[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キーを押すたびにクリアされません。

キーを押すたびに再描画し、Returnキーを押すたびにテキストを下に表示する方法があります。

ありがとうございました。

答えて

1

私が正しく理解していれば、入力フィールドのテキストをクリアして、画面のメインエリアにblitする必要があります。ユーザーがenterを押した後、入力フィールドをクリアするために新しいpygame_textinput.TextInput()インスタンスを作成すると、テキストをuser_input変数に割り当てます。

コードを単純化しようとしました。なぜなら、2つのwhileループはちょっと混乱していて、その目的が分からないからです。通常、ゲーム中にループが1つしかないはずです。

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() 

編集:このバージョンでは、レンダリングされたテキストサーフェスをリストに追加し、それらをオフセットでブリットします。

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() 

Edit2:テーブルを取得するには、列のオフセットと行のオフセットにモジュロを使用できます。この例の問題は、幅が広すぎるとテキストサーフェスが重なり合う可能性があることです。

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

ありがとうございました。ユーザーがReturnを押すと新しいインスタンスを作成することは、それを解決するための素晴らしい方法です。しかし、私は十分に私の質問を特定しなかったと思う。私が最初のwhileループとスクリーンにレンダリングする関数を持つ理由は次のとおりです:ユーザ入力を(実装したように)下に表示したいが、ユーザが別のタイプを入力してReturnキーを押すと、その入力はすでに表示されている入力の下に表示されるべきです。このプロセスは、タイマーがなくなるまで続けられます(最初のwhileループ)。 – Ivan

+0

その場合、私はおそらくテキストの表面をレンダリングし、それをリストに追加します。次に、このサーフェスのリストを反復して、メインループのオフセットを使ってblitします。 – 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) 

私はずっとあなたを気にする必要はありませんが、今、私はもう一つの問題は、私はトラブルの解決を持っていますことを左に持っています。画面の下の境界線を抜けると、テキスト入力を2番目の列に表示することは可能ですか?たとえば、ユーザーが多くの単語を入力した場合、それが互いに適合しない場合、次のテキスト入力を右に移動し、最初の入力の隣で開始することができます(言い換えると、2番目の列を作成します)。これまでのおかげで、本当にありがたく思っています。

+0

私は、私の答えにテーブルの描画方法を示す初歩的な例を追加しました。 – skrx

+0

それを解決していただきありがとうございます。私はいくつかのディビジョンを試していましたが、今度はモジュロとフロアディビジョンについて言及しています。 – Ivan

関連する問題