2019-04-18 20:53:42

As the title suggests, I want to get input in python. Now, wait. You could say that I made the topic for it a bit ago. You're right, I did. I could have revived it but decided against it do to some bad blood with necromancy. So, Here's my issue:
I want to get input with python.
The thing you're thinking about must be about using the raw_input or just input. However, there's a problem: Windows.
When I use pygame and input(), the function works... in a strange way. It asks me for input, but it does so in a different window. Let's say I have a game.py file and I run it through the command line. My game window will be generated, but when I ask for input, my input will be expected in the command line itself rather than inside the game.
One suggestion I got in my last topic about this issue is using unicode. That works great... for all lowercase letters. I can't enter capitals no matter how hard I try, and that is do to me using for event in pygame.event.get() as my loop. As far as I understood, there is no such thing as capital unicode, so there won't be any point in re-coding the function to look like this:

def input():
 keylist=pygame.key.get_pressed()

If I do re-code the function to look like that, how would I move forward? How can I test if a key has been pressed, if it's in the unicode table, and if it has shift pressed with it, all of that without having to write dozens of if statements for every single button on the keyboard?
I do hope there is an easier solution to this. I know that you can combine WX with pygame, but WX is complicated from what I've seen.

2019-04-18 21:48:16

Hi,
I think if you have a key number, like 65 for a, if you add 32 to it it always becomes a capital.
This has something to do with the chr and ord functions.
Hope that helps.

2019-04-18 22:25:41 (edited by Lucas1 2019-04-18 22:26:21)

The builtin input function will always expect input from the command line, that's what it's intended for. As for input in pygame, I'm not particularly sure. You could always use wxpython dialogs:

def input_box(parent,caption,message,text="",password=False,type=wx.ICON_INFORMATION):
    #Maybe I should change this to a dictionary with result and value keys.
    dlg=wx.TextEntryDialog(parent,message,caption,text,wx.OK|wx.CANCEL|type|(wx.TE_PASSWORD if password else 0))
    return (dlg.ShowModal(),dlg.GetValue())

2019-04-19 00:24:02

oo yay! I'm the first to offer a technical explanation for once. Squeeee!
OK so, here goes:
There are two types of program, GUI and command line.
command line programs are programs that run, you guessed it, in yhe command line. This is that funny window that has the name "c:\windows\bla bla bla"
A GUI program is a program that has a graphical user interface, or, a separate window, with all those wonderful buttons and key press events and stuff!

So:
raw_input(), this is a command line function. It is designed to get input from the command line, and is what is called a blocking function. This means that if you have a loop like this:
n=0
while(n<10):
if(n==5):
  print("tell me something!");
  print(raw_input())
n=n+1

the loop will run super fast until n=5, then when n=5, it will stop while it waits for the user to finish writing, and as soon as the player hits enter, it will continue.

Simulating this in an audio game, however, is difficult. Or at least, more difficult than simply writing: raw_input().

Pygame, to the best of my knowledge, has no text box or similar.
Sure, you could gut your program, move to wx python, and have a lot of trouble with sound, but why!
Pygame gives you everything you need for an audio game right there, and with only a few tweaks, we can give it our own text box.
I'm not a fan of writing peoples code for them, so the below is just seudo code, meaning, it is not real and just outlines things:
textfield=""
in_text_field=0
def key_pressed(event):
if(key is enter):
   in_text_field=2
else:
  textfield=textfield+event.letter

don't use event.letter, that's not a thing.
then, in your game loop:
if(in_text_field==1)
do nothing because we're waiting for text to be finished.
elif(in_text_field==2):
aha! we have some text, and a text box was recently closed! do something with it, such as:
speak("Mua ha ha ha ha! I know what you typed! you typed: "+textfield+". Clever!")
textfield=""
in_text_field=0

then in your pygame event loop, simply put a call to game_loop, and make sure not to include while loops in that game loop because otherwise it sticks, and besides the event loop is already a game loop.

Few! ok this got a lot more wordy than I meant it to, and the code is only seudo code, but that's the basic idea.
I'll probably end up covering something like this in my next batch of tutorials, but I hope that helps!

Nathan Smith
Managing Director of Nathan Tech
It's not disability
It's ability!

2019-04-19 00:59:31

You get input with Pygame through pygame.globals.keys. The pygame documentation explains key input -- check it for the answers you seek.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2019-04-19 03:45:43

I could be wrong, but I think that you can use wxpython and pygame in the same project. It may require some magic though, I've not tried it as of yet.

2019-04-19 05:22:33

I generally recommend against attempting to mix standard GUI systems with gaming libraries. Generally its not a good idea unless your game uses a standard GUI library like TDV does.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2019-04-19 15:46:20

Thank you all for your input. I'll respond to posts one by one.
@3: What are the parent, caption, and message in your function? What would I pass along to each?
@4: You kind of didn't help my problem. I had input in a way you described, but your input is limited. It will not detect capitals, the hole point of this topic. Lol
@5: I looked around on the docs for pygame, and from what memory serves, I found a function called get_mods() which returns an integer of the mod keys like shift, alt, and ctrl. Is that what you intended for me to find? If so, would I just add in the if statement checking for the shift key being pressed and appending an uppercase letter to the string if it's the case? Can that type of input raise an exception? Would it be efficient?

2019-04-19 16:58:27 (edited by Lucas1 2019-04-19 16:59:35)

#3:
Parent is a parent window, caption is the title of the dialog, and message is the contents of the dialog (not the default text inside the edit field, that's text). What I had failed to take into consideration is that if you're using pygame, you might not be able to use wx dialogs, at least not without some effort. I have seen some games do it though (Undead Assault), but I don't know how much effort it took those.

2019-04-19 18:14:07

I had no issues mixing pygame and wxpython in my projects. All you have to do is creating the application before you show the window, and calling its MainLoop after showing the window so it works all fine. Then you can use wxpython's text entry dialog. Please note that if you are showing the game's window at fullscreen then you should remove the fullscreen flag before you call a text entry dialog and then re-add it after getting the input. It was what I did in one of my projects.

---
Co-founder of Sonorous Arts.
Check out Sonorous Arts on github: https://github.com/sonorous-arts/
my Discord: kianoosh.shakeri2#2988

2019-04-19 19:34:19

@8, yep, that's perfectly fine.
@9-10, still wouldn't do it. Write your own input text handling functions (SDL2 has helpers). This stuff is easily finadable on the web, and can be easily (or most of the time, easily) translatable from C. Its good to learn these things and to not rely on classic GUIs for your text input; that's what immediate-mode GUIs are for.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2019-04-19 20:03:43

I don't see the reason to not use a tool that is already there. Sure, for learning it's fine, but why would you spend effort coding a text entry dialog that can do all the things a wx dialog can?

2019-04-19 20:40:24

@12, because unlike a WX dialog, which will block your game since you can't do that on any other thread than the main one, a dialog that is coded by hand is not only a good learning tool to teach you how all of this works under the hood, but you cna run it on any thread you want, so it won't actually block your game.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2019-04-19 22:15:26

Here is a function that uses only Pygame and gets the input from the game window.
The downside of this approach is that you'll need to implement the cursor keys yourself, but it works with capital letters and accents.
def pygame_get_input():
    result = []
    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_BACKSPACE: # Delete letter
                    result = result[:-1]
                elif event.key == pygame.K_RETURN: # User entered all the text
                    done = True
                    break
                elif hasattr(event, "unicode"): # User tiped a letter
                    result.append(event.unicode)
        pygame.time.wait(10)
    return "".join(result)

2019-04-19 23:29:27

@13:
Then run a function in a different thread. Shouldn't be too difficult if you code it right.

2019-04-20 01:48:46

@15, that's quite impractical. Unless you like carting all of your game logic off to another thread that is... and I do mean all of it.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github