BGE Python- Calling a function?

Hello Blender Artists!

I’ve dabbled in python a bit and want to get serious with python in the BGE.

My issue is my script is ignoring the def function. Everything inside it is not happening.
I’m following SolarLunes tutorial here


This is my script:

#move.py

from bge import logic
from bge import events

print("move.py initialized")

def Player():
    print("Def Player initialized")
    cont = logic.getCurrentController()
    obj = cont.owner
    motion = cont.actuators['Motion']
    key = logic.keyboard.events
    kbleft = key[evetns.LEFTARROWKEY]
    kbright = key[events.RIGHTARROWKEY]
    mx = 0.0
    my = 0.0
    
    if kbleft > 0:
        mx = -0.1
        print("Left")
    elif kbright > 0:
        mx = 0.1
        print("Right")
    motion.dLoc = [mx, my, 0.0]
    cont.activate(motion)

Now it’s hooked up to an Always sensor and Motion actuator, but when i check the console it only shows the debug text “move.py initialized”. This means it is not actually activating the Player function.

So dear internet, where am i going astray?

At the bottom of the script add a line

Player()

That will call the function, making the execution of the code ‘jump’ to the “def Player()” line and once all the code inside the player function has executed the code will jump back to where you called it.

You have to explicitly call a function to make the code run inside it.

I had a hunch… I was just following the tutorial, seems i forgot to think for myself.
Thanks for your help, i appreciate it.

No worries,

also, you can use the Python actuator and set it from script to module and you can call the function directly from the logic brick:


There is a typo, “evetns”.

That is a great thing to know, thank you!

(Also i found the typo, thanks Equip)

I suggest going with the module way - great illustration andrew-101!

One advantage is that the controller is sent as a parameter to the function so You can write:

def player(cont):

And then get rid of the line “cont = logic.getCurrentController()” as You already have cont.

(I change name of Player to player to follow python naming standard - Player is a name for a class)

Another advantage is that the modules global scope (outside any functions) will exist through the whole game. It is called once before the function run the first time and then never again but keep it’s memory. So You can use it to do initialization and storing data.

One more advantage with module is that the modules can be in separate files - You can use any editor You like to edit them and they are easy to use from different blends.

But that also lead to some kinks, If BGE finds a file it chose that over Your Text buffer - even if it’s a python standard module - so make sure to give modules a unique enough name. And if You change the file in the blender editor make sure to save the file - else BGE might use the old file from the file-system.

When using external files You also have to make sure they in ‘python-path’ so python can find them on import.

I’m chiming in because I’m also on a precipice (but speaking about myself, quite ignorant).

I couldn’t figure out what kbleft and kbright might return, and why mx and my have been set at 0.0.

Solarlune will be here soon.

I assumed mx (movement x?) is just declared as 0.

The player is always moving at mx (i think), and it’s just set to 0.1 to make him move in game space.

kb i assume is keyboard, and they return 0 (not pressed) and 1 (pressed)?

edit: e.g if keyboard left > 0 then its one, which means it’s pressed. So it sets mx and moved that much 'till you release it.

Just speculating.

I don’t want to distract you so I’ll wait and watch from now. For myself I’m yet to experiment properly with events.

It’s all a mystery to me…

It’s the blender input api:

bge.logic.keyboard.events - a list (i think - might be a dictonary) holding the status of all keys on the keybord.
bge.events.LEFTARROWKEY - The id for left arrow key in above list, so:

bge.logic.keyboard.events[bge.events.LEFTARROWKEY]

Give the status for the left arrow key, it can have 4 status: none, just activated, active, just released. none happens to be 0 so ‘key > 0’ is true for active, just activated and just released. That is - it is true when the key is pressed and one frame more. just released is 3 so if You write ‘0 < key < 3’ it is true only when the key is pressed.

But it is bad code in one sense - The numbers (or even the order) of the status codes should not be relied on - they may change in future blender releases. There is named constants available in the api. One clean way to write it is:


PRESSED = (bge.logic.KX_INPUT_JUST_ACTIVATED, bge.logic.KX_INPUT_ACTIVE)

if bge.logic.keyboard.events[bge.events.RIGHTARROWKEY] in PRESSED:
    # The key is currently pressed

I’m middle aged, male, enjoy long walks on the beach…

Edited to add:
I’m taking the piss, there are no mysteries, they’re only things we don’t know.

Whap - Did someone say my name? LOL

Just messing around. :stuck_out_tongue:

LaH explained it correctly. Mx and My are movement speed variables, and key is the keyboard events dictionary. Kbleft and kbright get the value from the dictionary to see if the left and right keys (left arrow and right arrow keys). If either’s above 0 (just pressed, being pressed, or just released, which isn’t when you would want to move, but it’s only for a game frame), then you move about.

I don’t see why numbers shouldn’t be relied on, as I think standard SDL (which might be the input handling code) might be the same. But in any case, I should go back and rewrite it, both to be easier to read, and correct. :stuck_out_tongue:

Thanks for the tutorial and clarifying SolarLune!
Much appreciated.

My 5 cents:

Here is a very very basic tutorial on module mode in the BGE

maybe it can be changed
3
to
-1

but 0 1 2 is much clear and clean
is much better than
bge.logic.KX_INPUT_JUST_ACTIVATED
:wink:

Yes - bge.logic.KX_INPUT_JUST_ACTIVATED is ugly - but also describing. If You use it to define a tuple with a describing name as in my code (PRESSED) the ugliness don’t clutter the code much - And it only need to be done once each file!

update: if bge.logic.KX_INPUT_JUST_RELEASED should change it is to 4 so we can use bit-vice logic on them - That’s kind of what You expect from an api like this.

If you see “KX_INPUT_JUST_ACTIVATED” you can easily guess

  • it belongs to Ketji “KX” (the game engine)
  • it means an “input” is “just” “activated”.
    I think this is pretty clear and pretty clean.

Even experienced programmer have a problem to link a “1” to this information.

  • To increase the readability of the code you would need to add a comment. Comments are usually maintained really badly and do not necessary tell the truth.
  • As LaH wrote if the internal implementation of an input state changes your code will become incorrect.
  • You can’t search for input states as you can’t distinguish “1” from another “1”.
  • Short names easily produce ambiguous meanings.

(Some programming languages use enumerations for situations like this.)