silly question: why is it not moving diagonally?

ok, I wanted to make a game, but I didn’t want to make a web of logic bricks for it. I decided to try out python. I followed a couple of tutorials, and what you see in the provided blend file is as far as I got. As you can see, I have a problem. The cube is not moving diagonally! You’re probably laughing, or at least grinning right now.

anyways, that’s my question. I would also like to mention, however, that I’m probably going to use what I did in the file, instead of calling the sensors and actuators from the script, because I don’t know how to do that. It’s too complicated for my brain. If you can guide me to a tutorial about that, that would be greatly appreciated!

movement.blend (701 KB)

The problem is with this:

    if right.positive:        move.dLoc = [speed, 0.0, 0.0]
        cont.activate(move)
    elif left.positive:
        move.dLoc = [-speed, 0.0, 0.0]
        cont.activate(move)
    elif up.positive:
        move.dLoc = [0.0, speed, 0.0]
        cont.activate(move)
    elif down.positive:
        move.dLoc = [0.0, -speed, 0.0]
        cont.activate(move)
    else:
        cont.deactivate(move)

If right is positive, you set the x speed to speed, and the y speed to zero.
You need to add them. If you replace it with (untested)


move_vect = mathutils.Vector([0,0,0])
if right.positive:
    move_vec += mathutils.Vector([speed,0,0])
if left.positive:
    move_vec += mathutils.Vector([-speed,0,0])
...
.

Then the keys will add, so you will be able to move diagonally.

I’d recommend against using dLoc, it tend to make things warp into each other. Instead, use a dynamic object, the servo motion actuator, and move.linV = move_vec.

A further suggestion is not to disable the actuator when you want it off, but to set the velocity to zero, thus creating a ‘holding force’ that will try keep the object stationary if it’s not moving.

Finally, checking keys from inside the script isn’t hard:


import bge

if bge.events.WKEY in bge.logic.keyboard.active_events():
    '''W key is pressed''

You could do it with applyMovement

As Sdfgeoff already wrote, ensure the event evaluation on the different axis are not exclusive.

I prefer to use the keyboars sensor to setup the key binding. This way the python code does not include configuration data. It even works if you replace the sensor with something completely different (message sensor) without touching the already working code.

can you guys make a blend file with the correct script? I tried what Sdfgeoff said, but it didn’t work. it said it couldn’t recognize the “right” thing in right.positive, even though it was already referenced before (right = cont.sensors[‘right’]). Probably did it wrong. As I said earlier, I’m new to the whole python scripting thing.

Here is one solution, it uses applyMovement() method.


import bge
cont=bge.logic.getCurrentController()
obj=cont.owner

def move():
    speed=0.1
    keys=bge.logic.keyboard.events
    xvec=0
    yvec=0
    if keys[bge.events.UPARROWKEY]==2:
        yvec=speed
    if keys[bge.events.DOWNARROWKEY]==2:
        yvec=-speed
    if keys[bge.events.RIGHTARROWKEY]==2:
        xvec=speed
    if keys[bge.events.LEFTARROWKEY]==2:
        xvec=-speed
    obj.applyMovement([xvec,yvec,0])


Just insert with logic:

Always (With true pulse) ---- Python (module, just yourtextname.move) ---- (no need to connect enything)
Remember that: Textname must end with .py suffix, example objectmover.py

EDiT:
May be image shows it better:



I made it module mode, with is faster than script mode and it good to learn too…

awesooooome! thanks a bunch, pohjan!!!
I tried it out, and it works just fine. I have a few questions, however.
1- why the 2 in “if {key press}==2”?
2- you didn’t include a “move()” at the end of the script. Is it not necessary?

again, thank you. Here (move_light-color.blend (705 KB)) is what I ended up with from the help I got here. I just wanna say that other than the help I got here, none of the modified stuff were from tutorials. I just wrote it and hoped it worked. and it did! I’m proud of my self :stuck_out_tongue: Still need to learn a lot more though

EDIT: actually, as I was playing around with it, something weird happened. As you can see from the attached file, I added a jump button (the space key). I can jump while moving in any direction EXCEPT for north west direction (pressing up and left arrow simultaneously) No idea why.

Order of things is actually important. Make sure your jump button is listed first, or if it’s logic bricks, make sure they’re above all the others.

1- why the 2 in “if {key press}==2”?
Actually better use blender constant type.

bge.logic.KX_INPUT_JUST_ACTIVATED
bge.logic.KX_INPUT_ACTIVE (is equalent of 2)
bge.logic.KX_INPUT_JUST_RELEASED

Keys return 1 just pressed, 2 press continuosly, 3 just realesed
So it equalent to (if {key press}==bge.logic.KX_INPUT_ACTIVE)

2- you didn’t include a “move()” at the end of the script. Is it not necessary?
Thats why we call it module controller, its equalent to:
import move from movescript

Modules idea is preventing continuosly bge importing.
All outside of move() executed once when game starts and inside of move() executed every tick.

‘I can jump while moving in any direction EXCEPT for north west direction (pressing up and left arrow simultaneously) No idea why.’

Jeah, most keyboards has impossible to detect all arrows and spacebar simultaneously due to electrical wiring. Expensive ‘game’ keyboard works better and can count more simultanous keys.
Just move jump to shift or Ctrl (they should work)

thanks for the explanations! though I’m apparently not done with asking questions, as I just tried to fix my new problem with no success. Sorry :frowning:
I would like my character to jump only once when the jump key is held, yet the height of which it ascends by is determined by how long the jump key is pressed. Basically I want a super mario bros jump :stuck_out_tongue:

You’ve stumbled upon what is know as key jamming which is a side effect of the way most keyboards send user input to your computer. You’ll notice that if you open up a program like Notepad and try to press the same key combination, the space bar won’t work there either.

The best solution is just to change your game’s controls so that keys that will often be pressed simultaneously do not conflict. You could also get an N-key rollover keyboard which doesn’t suffer from this issue, but of course anyone else who plays your game on a normal keyboard will still have the same problem.

As for the jump height, right now you’re moving the cube vertically when the spacebar is held down. What you want to do is give the cube an initial vertical velocity when the keyboard is pressed and the cube is on the ground. You can do that will something like this:

if keys[bge.events.SPACEKEY] == 1 and obj.groundSensor.positive:
    obj.worldLinearVelocity.z = 10

where groundSensor would of course refer to a collision sensor that looks for a property that is unique to objects you want to be able to jump on.

it’s not working, it’s giving me an error :frowning:

You have to create and attach the ground sensor to the controller and define it in your script.

groundSensor = obj.sensors['NameOfCollisionSensor']
...
if keys[bge.events.SPACEKEY] == 1 and groundSensor.positive:
    obj.worldLinearVelocity.z = 10

The errors displayed in the console tell you what is wrong. You should try to learn to understand them.

I already did that. The error was about the obj portion in obj.worldLinearVelocity.z = 10 (it had an arrow under the j)

What did the error say?

You must set object type to (dynamic) if you add physical forces. Mobius example works, perhaps you missed something.
Ok see the


picture.

I’m doing it correctly as far as I know. I have it on dynamic and I have the collision sensor connected to the script. This is the error it’s giving me:

    obj.worldLinearVelocity.z = 10
      ^
IndentationError: expected an indented block
Python module can't be imported - object 'Lamp', controller 'Python':
SystemError: NULL result without error in PyObject_Call

the code for the cube and the lamp are separate, though in the same file.
move_light-color.blend (712 KB)

Simple indentation error…Just insert 4 spaces begin that row, just another if 's have.
<4space more> obj.worldLinearVelocity.z = 10

Little error with:
obj.applyMovement([xvec,yvec,zvec], local)

If you want accees local coordinates it will be:
obj.applyMovement([xvec,yvec,zvec], True)

wow. That is one silly error.
the local thing isn’t an error. At least it’s not on my setup. I have a boolean property set up that I can check or uncheck as the local variable

the cube isn’t jumping higher when I hold the jump button like in Super Mario Bros, but I guess it’s close enough :stuck_out_tongue: