Trying to use bge.logic.joysticks[0]

I managed to get this to work once (a long time ago) but now no matter what it throws this error: ‘NoneType’ object has no attribute ‘activeButtons’

Here’s the specific lines that i used:

joystick = bge.logic.joysticks[0]
btns = joystick.activeButtons
if 0 in btns and len(btns) == 1:
    cont.activate(walk)

All it should do is activate an animation when A is pressed.
I try to refer to the api documentation but i cant make any sense of it…

If the joystick is not detected, its value will be None, so this error will happen. Try to print bge.logic.joysticks to see if there’s any joystick object available in the list.

joystick = bge.logic.joysticks[0]

if joystick is not None:
    btns = joystick.activeButtons
    if 0 in btns and len(btns) == 1:
        cont.activate(walk)

else:
    print("Joystick not detected")
1 Like

Just because you’ve only plugged in a single joystick doesn’t necessarily mean it’ll be at the first slot. You need to walk through the list first.

size = len(bge.logic.joysticks);
joy  = None;

for index in range(size):
    joy = bge.logic.joysticks[index];
    if joy != None: break;

if joy != None:
    #your logic here

else:
    #no joystick found, throw an error
1 Like

so the number after .joysticks[(this one)] was my problem. Ill try now thanks. no where i looked mentioned this. thanks

Quick question. Using if abs(left_analog_y) > 0.2 activates for both positive and negative stick. i assume its possible to get positive and negative separated. Any ideas on it?

More of a general logical issue. With two different results branching out of a single condition, you need two additional checks.

if abs(value) > threshold:
    if value < 0: #negative
    else:         #positive

Or, you could set a flag if you’d rather perform the evaluation later on:

isNegative = False;
if abs(value) > threshold: isNegative = value < 0;

I don’t think you can make it shorter.

Also, for movement one generally multiplies the axis value from the stick times speed.
Say, move_vec = [speed_x * joy_axis_x, speed_y * joy_axis_y, jump || gravity]

But sometimes I keep a direction vector on top of the one I use for the movement calculation, when I want to trigger different animations for instance. It’s not really faster or slower, but I find it more readable to do something like

isNegative = [isNegative_x, isNegative_y] or if isNegative.x || isNegative.y

Though that’s just personal taste to be honest. One might as well keep it as two separate variables. A single greater or less than check doesn’t sound like the biggest bottleneck to me.

i used if abs(left_analog_y) > 0.2: cont.activate(walk)
but this activates both forward and backwards.
i thought i understood python but i’m not too sure now

Of course it’ll activate for both. abs() is for absolute value. abs(-1) == 1 and abs(1) == 1.

You want to perform this check, because your threshold is non-zero, and your values can be both positive and negative. Instead of checking (value < -threshold) or (value > threshold), you get the absolute value and do only one comparison instead.

In other words,

isMoving         = abs(value) > threshold;
isWalkingBack    = isMoving and (value < 0) #negative y
isWalkingForward = isMoving and (value > 0) #positive y

if   isWalkingForward: cont.activate(walk)
elif isWalkingBack:    cont.activate(walkbackwards)

This is just a more verbose way to do the exact same thing. If you are moving, and y isn’t negative, then it’s forward. Again, skipping an evaluation or two is good in theory but unless you’re doing an expensive check the difference tends to be negligible.