Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow receiving real-time keyboard events from Python #925

Closed
Ecco opened this issue Mar 17, 2019 · 7 comments
Closed

Allow receiving real-time keyboard events from Python #925

Ecco opened this issue Mar 17, 2019 · 7 comments
Labels
app-python Python application enhancement

Comments

@Ecco
Copy link
Contributor

Ecco commented Mar 17, 2019

Problem you'd like to fix

It's currently not possible to code an arcade-style game in Python because there's no way to get real-time keyboard state (the input function is blocking).

Describe the solution you'd like

Expose Ion::Keyboard::scan in Python. The code itself should be rather simple to write, but what's interesting is the API. What should we call the module? Is there any standard Python function we could piggyback on?

@boricj
Copy link
Contributor

boricj commented Mar 17, 2019

The naming issue here is probably deeper than expected. kandinsky is a source code directory inside epsilon that happens to contain code related to graphical operations and end-users are (rightfully) completely oblivious to that fact. For all they know, right now kandinsky is just a fancy module name for accessing NumWorks-specific platform APIs inside the Python app. Personally, I would turn it into a low-level, general purpose, platform-specific NumWorks Python API (that would've been called numworks, but it's a bit late for that). However, I do understand that putting everything inside the same module may not be desired.

Regarding the keyboard API, I don't think there are any standard Python APIs that can be piggybacked on (unless we do things like select.select([sys.stdin], [], [], 0) and sys.stdin.read(1)). There's pygame.key.get_pressed(), which returns a list of booleans to be indexed by keyboard constants. My PoC (#746) just returns the result of Ion::Keyboard::scan as an integer and bundles all keyboard constants to be used with bitwise operators, which is admittedly a bit too dirty and low-level.

Assuming we want a keyboard API suitable for beginners, we could return a set of strings representing currently-pressed keys (such as "UP", "SHIFT", "OK"...). It's self-describing, fairly easy to manipulate and reasonably future-proof. For good measure, I'd include a keys set variable holding all possible strings as an on-calc reference.

@Ecco
Copy link
Contributor Author

Ecco commented Nov 15, 2019

See #1201

@Ecco
Copy link
Contributor Author

Ecco commented Nov 15, 2019

In #1201, I made several choices:

  • I created a new ion module, to match Epsilon's code. We could indeed have created a single numworks module, but that's not what we started doing. Or we could artificially have moved the keyboard functions to kandinsky, but I quite didn't feel right. Anyway, one is free to create an extra abstraction layer on top of ion + kandinsky.
  • I used constants for the keys, which is more efficient
  • There's no "Keyboard::scan" at the moment, but given how fast "keydown" is anyway, I'm not sure it's even needed.

@mobluse
Copy link

mobluse commented Dec 11, 2019

Maybe one could be inspired by the button objects in Microbit:
https://microbit-micropython.readthedocs.io/en/latest/button.html
They have methods is_pressed(), was_pressed(), and get_presses().

@Ecco
Copy link
Contributor Author

Ecco commented Jan 29, 2020

This has been fixed by #1201

@Ecco Ecco closed this as completed Jan 29, 2020
@slabko
Copy link

slabko commented Mar 24, 2021

Are there any plans for a similar blocking keydown function? I can implement something that waits for a keypress while showing something with kandinsky. The only way around I found is scanning all the keys every 0.01 seconds, which seems very inefficient.

input is not an option, because it doesn't work with kandinsky, and it only gets triggered with KEY_EXE returning a string, and also it doesn't know about all the keys on the keyboard.

@artaxxx
Copy link
Collaborator

artaxxx commented Mar 24, 2021

A polling loop (as you mentioned) is exactly what we do with the ion module!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
app-python Python application enhancement
Projects
None yet
Development

No branches or pull requests

5 participants