9

I want to take input from the user in the game (e.g. their name), then put it on the screen.

I tried modules (including InputBox), but none of them are working. They just displayed my text on screen.

I want to save that input to a variable. Is there any way to do this?

Example:

font1 = pygame.font.SysFont("None", 30)
score = 0
text = font1.render("{}".format(score), True,(255,255,255))
...
...
if sneakeattheapple:
    score += 1
    text = font1.render("{}".format(score), True,(255,255,255))
...
...
screen.blit(text,(275,6))

This is going to put the score variable on the screen. But score is already defined, I want to do this with a variable given by user.

EDIT: Let me be more clear. In Python we can do this:

x = input("Do you want to do this? (y/n): ")
if x == "y":
    #do something
if x == "n":
    #do something

This is what I want to do in Pygame.

lpd11
  • 133
  • 1
  • 7
GLHF
  • 3,835
  • 10
  • 38
  • 83
  • Have you tried using `input()` – Anthony Pham Dec 30 '14 at 23:51
  • 8
    @PythonMaster Seriously.... I want to take that input from pygame screen not Python shell.. – GLHF Dec 30 '14 at 23:52
  • 2
    @PythonMaster No, not a duplicate. I already check all of questions in SO. – GLHF Dec 31 '14 at 01:28
  • I would really like to help you, but I still do not understand your question. What is it that you are trying to accomplish? The links that you have provided already store user input in a variable. – Bartlomiej Lewandowski Jan 01 '15 at 23:27
  • No, if you keep pressing the keys that values will always going to change.This is why I put that links. They are catching keyboard events. – GLHF Jan 01 '15 at 23:30
  • What if I want to take input from user middle of the game like a question? – GLHF Jan 01 '15 at 23:43
  • 5
    _"I tried InputBox etc. but it's not working actually"_ - what is not working? "Not working" is not a problem statement. You didn't post any errors you received or anything. – Burhan Khalid Jan 15 '15 at 06:23
  • 2
    Do you want the user to type a ***variable name*** and then print the value of that variable? I'm struggling to understand what you need help with otherwise. – J Richard Snape Jan 26 '15 at 13:23
  • @JRichardSnape I don't know how can I be more specific. Question is clear – GLHF Jan 26 '15 at 22:02

4 Answers4

5

There's nothing baked into Pygame for this. You will either need to use a 3rd-party GUI library, or build it yourself. Example: if the textbox has focus, take all keydown events, and append to a string. Each frame, draw a box, then draw the string on top.

Building a simple one shouldn't be that hard, but if you want a more full-featured one, it will likely be easier to use a library.

user3757614
  • 1,776
  • 12
  • 10
5

I am currently assuming this function worked with your program is successful and raises no errors. Here is a function in the link you gave us:

def ask(screen, question):
    "ask(screen, question) -> answer"
    pygame.font.init()
    current_string = []
    display_box(screen, question + ": " + string.join(current_string,""))
    while 1:
      inkey = get_key()
      if inkey == K_BACKSPACE:
        current_string = current_string[0:-1]
      elif inkey == K_RETURN:
        break
      elif inkey == K_MINUS:
        current_string.append("_")
      elif inkey <= 127:
        current_string.append(chr(inkey))
      display_box(screen, question + ": " + string.join(current_string,""))
    return string.join(current_string,"")

It looks like this is how you get input from a user with a pygame screen right? Let's look at line 4 of this function:

current_string = []

The stuff the user types in is stored in this list. Assuming you know how to take a string and put it on the screen, you could save the string like this:

string_input = ''.join(current_string)

If you can make a similar function (if this one doesn't work), you can do the same thing! Just save the first item in the list holding the string in a variable as shown above. If you have any problems, please comment so I can edit my answer.
To the next part now. You can simply activate this function at any time. You might want to activate when something happens. An example is when the snake eats the apple. You probaly have a function for that I believe. You can make a variable like this :

Eat = 0

And put in that function. When that variable is equal to 0. Nothing really activate the other function. When the snake eats the apple, reset the variable to 1 and then activate the function like this:

if Eat = 0:
    someclassname.ask()

You do this with many other occasions. I hope this is clearer and more helpful!

Anthony Pham
  • 3,096
  • 5
  • 29
  • 38
  • Looks promising. I suggest using `return ''.join(current_string)` (it's seldom necessary to use the `string` module any more). Also, at the end of your answer, wouldn't `string_input = current_string[0]` just put one character into `string_input`? If so, then it's unclear what you're saying there. – martineau Jan 14 '15 at 09:44
  • Why do you put the string in line two? – Casey Jul 11 '18 at 04:57
3

Have you tried getting key event's and then putting them together to form something? You could put something like this inside of your main game loop.

input = ''
for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                playing = False
            if event.key == pygame.K_w:
                input = input + "w"
            if event.key == pygame.K_s:
                input = input + "s"
            if event.key == pygame.K_a:
                input = input + "a"

Then you can check for when the user is done with input(button/enter key), and finalize the variable. With this you might run into a problem where the key is held longer so you get 3 w's for only pressing the button once. If this is the case you can either 1. not allow another input until a certain time has passed(.25 s maybe?) or 2. use pygame.KEYUP instead of pygame.KEYDOWN and exclusively check for strokes.

johnidel127
  • 179
  • 1
  • 1
  • 8
2

Here is a possible solution, it may be really useful for future visitors that are also suffering with this problem like me. Which is;

First making a text-render function

def text1(word,x,y):
    font = pygame.font.SysFont(None, 25)
    text = font.render("{}".format(word), True, RED)
    return screen.blit(text,(x,y))

Then a function works like input;

def inpt():
    word=""
    text1("Please enter your name: ",300,400) #example asking name
    pygame.display.flip()
    done = True
    while done:
        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:
                    word+=str(chr(event.key))
                if event.key == pygame.K_b:
                    word+=chr(event.key)
                if event.key == pygame.K_c:
                    word+=chr(event.key)
                if event.key == pygame.K_d:
                    word+=chr(event.key)
                if event.key == pygame.K_RETURN:
                    done=False
                #events...
    return text1(word,700,30)

As you see, this function catching keyboard events, it has its own while loop also, it's important. I break the loop when pressing Enter button which is if event.key == pygame.K_RETURN: done=False . Then returning our word with text1 function, displaying. Other events can be set of course opinion-based, like space button for a gap etc.

Then, actually we have to make an intro function and we will ask the user's name in there for example, when intro function is done, name goes to set on the screen until game is over.

def game_intro():
intro=True

while intro:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            pygame.quit()
            quit()
        if event.type==pygame.KEYDOWN:
            if event.key==pygame.K_RETURN:
                intro=False
    inpt() #Here we are calling our function
    screen.fill(white)

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

See that we break this loop with the Enter button again. So we will ask the user our question in intro, then we will set it on the screen, top-right corner for example.

GLHF
  • 3,835
  • 10
  • 38
  • 83