How do I call keyboard setup from another python script?

I’d like to set up things like keyboard buttons in one script that would save everything to memory and call it in other scripts.
What I have tried and what worked was storing variables like integer and string.

bge.logic.VariableINT = 99
bge.logic.VariableSTR = "text"

Another thing that worked was storing audio files in memory.
Then I would just call it in another script.

But this for some reason doesn’t work with keys.

keyboard = bge.logic.keyboard
eKey = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.EKEY]
bge.logic.BUTTON_1 = eKey

If I do this and call the bge.logic.BUTTON_1 in another script, it simply doesn’t work.

when you say

eKey = bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.EKEY]

you are storing the result of that into eKey…so it would only either be true or false that is getting stored. What are you trying to store - a mapping from BUTTON_1 to EKEY ?

I see. That would make sense from what it did.
What I’d like is to, for example, map any key in this case the EKEY to BUTTON_1.
I guess it would have to be a function that can be called in other scripts from memory.

Does anyone know how can I map keyboard presets in one script and call them in another?
I know how to call variables stored in memory.

bge.logic.VariableINT = 99

Something like that, but for the keyboard.

You could initialize BUTTON_1 to false, change it to true when the key is pressed…

keyboard = bge.logic.keyboard
if not hasattr(bge.logic, 'BUTTON_1'):
    bge.logic.BUTTON_1 = False # initialize BUTTON_1 in logic
else:
    if bge.logic.KX_INPUT_ACTIVE == keyboard.events[bge.events.EKEY]:
        bge.logic.BUTTON_1 = True

…and only set it back to false when it has been ‘registered’ by the other script:

if bge.logic.BUTTON_1:
    # do things
    logic.BUTTON_1 = False

Maybe not the most elegant solution, but it works.

1 Like

This tutorial may be useful:

1 Like

I take it you guys don’t know this trick?

from bge import events;
from bge.logic import keyboard;

KEYS={

  'BUTTON_0':'EKEY',
  'BUTTON_1':'WKEY',

};

def getActive(key):
  return keyboard.inputs[key].active;

s="";
for key,value in KEYS.items():
  s=s+f"{key}=lambda:"\
    f"getActive(events.{value});\n";

exec(s);
if BUTTON_1():print(1);

Oof, nasty. Let me explain:

  1. Write a dictionary with the format varname:keyid. varname is what you want to call the key, internally. keyid is some key name from bge.events
  2. Write a function to fetch the state of a key.
  3. For every key, generate a key-specific wrapper for that function. This means, basically, you assign a name to “calling this function with these args”.
  4. exec the generated string. Yes. You can write python code as a string and then execute it. It’s an interpreted language, people.
  5. Call the generated function whenever you want to get the state of the key. So it’s BUTTON_1() or whatever you name varname, with the parens, not without.

Here in the example I’m being lazy and assigning the function to a local. You could import script and then script.varname, and perhaps that’s what you should do rather than saving it to bge.logic.

But if you *must* save it to an already existing module, then

KEYS={

  'bge.logic.BUTTON_0':'EKEY',
  'bge.logic.BUTTON_1':'WKEY',

};

And that’s that, you’re done.

BTW my code here could be improved a whole lot, I didn’t give it much thought to be honest. With some retweaks I could enable key remaps and probably get rid of the exec altogether. Eh, ping me enough times and maybe I’ll do it.

1 Like