A little bit of python help for a little bit of a Python noob!

Hey folks.

Decided to try and teach myself some Python, I want to finally get out of the “Logic Brick” way of thinking, and Python seems much more powerful, even for simple games.

TestFile1.blend (404 KB)

I’ve got this little file going in 2.56 beta, and it works nicely… except for the direction? The sensors work (cube moves when the keys are pressed) but it moves only one way, so I think it’s something to do with my last if statement. If anyone can tell me why it’s not working, you’d be a bit of a hero. (I can’t find any documentation, but maybe I’m just not looking in the right place)

And yeah, I know the code is needlessly large. I’m learning, so I like to leave myself comments to remind myself what does what.

Cheers!

Alex

P.S. ooh also… is there any way of getting key presses without using keyboard actuators? That’d be mega neat and tidy…

You have enabled on the first keyboard sensor (LeftArrow) the All Keys button. If you want to stop the motion,when no key is pressed, you must set the force to zerrow.


#No key pressed stop 
else:
    PlayerForce.force = [0,  0, 0]

Yes you can read the keyboard events and also set a motion on your object without motion actuator.


from bge import logic as G
from bge import events
cont = G.getCurrentController()          
obj = cont.owner                               
speed = 0.2 
keyboard = G.keyboard.events
if keyboard[events.WKEY]:
  obj.applyMovement([0,speed, 0], True)
if keyboard[events.SKEY]:
  obj.applyMovement([0,-speed, 0], True)
if keyboard[events.AKEY]:
  obj.applyMovement([-speed,0,0], True)
if keyboard[events.DKEY]:
  obj.applyMovement([speed,0,0], True)

http://www.blender.org/documentation/250PythonDoc/

firstly, you were using allkeys, which automatically makes it move in only one direction
secondly you need to set force to 0 when not pressing keys.
i can make keys into python.

add an always true pulse to the script, remove all key sensors and add this:

import bge

# Just shortening names here
keyboard = bge.logic.keyboard
lastinput = bge.logic.KX_INPUT_JUST_ACTIVATED

#set the required statement to be true for each motion
forward = keyboard.events[bge.events.WKEY] == lastinput
backward = keyboard.events[bge.events.SKEY] == lastinput
left = keyboard.events[bge.events.AKEY] == lastinput
right = keyboard.events[bge.events.DKEY] == lastinput


##############################################################

cont = bge.logic.getCurrentController()           # Gets the current controller (Run)
obj = cont.owner                                  # Gets the object the controller is on



### Sorting Actuators
#####################

PlayerForce = cont.actuators["PlayerForce"]



### Player Movement events handling
###################################

if forward:
    PlayerForce.force = [0, 10, 0]
    cont.activate(PlayerForce)
elif backward:
    PlayerForce.force = [0, -10, 0]
    cont.activate(PlayerForce)
elif left:
    PlayerForce.force = [-10, 0, 0]
    cont.activate(PlayerForce)
elif right:
    PlayerForce.force = [10, 0, 0]
    cont.activate(PlayerForce)
else:
    PlayerForce.force = [0, 0, 0]
    cont.deactivate(PlayerForce)












Wow that’s awesome, thanks a lot guys. I’ve learnt a lot already!

I didn’t notice I had the All Keys set, I must have knocked it. Doh for not double checking!

agoose77, that script is awesome, except the cube doesn’t stop once you let go of a key? But thanks for taking the time to write that out, I’ve learned a load from it already.

There is nothing wrong with the Sensor-actuator-concept. I recommend to use it as much as possible. If you use it right, you set up logic with less overhead as possible. An always True pulse sensor triggering an Python controller is not performant.

I suggest to use a combination of HG1’s solution (the keyboard sensor) and agoose77’s solution (seting up an actuator).
With that the Python controller is executed on keyboard changes only. Which is much more efficient than executing the controller with every single frame.

The motion actuator runs until you deactivate it, even without executing the python controller.


if #motion key pressed:
  cont.activate(PlayerForce)
else:
  cont.deactivate(PlayerForce)

The motion actuator you configure with the script, does not need to get the same values assigned with each frame. The setup needs an update on keyboard change.

Thanks Monster! Yeah I figured that the script would be running needlessly all the time if it was set on an always sensor, which would be slower than only having it fire when the relevant keys are pressed. Thanks for that example though, I’ve implemented it and it works a lot better. I didn’t realise you could de-activate an actuator once it was running.

Next python question (I don’t want to make a new thread, so I guess asking it in here is OK), what would be the best way to set up a jump/doublejump system? I’ve tried a few logic brick ways, but what which would be the best performance wise? And how would I go about coding it in Python? I assume it’d be adding a Space (or whatever) actuator and running a similar setup to the movement in the script, but with a +z force instead. But how would be the most resource friendly way to do a double-jump system?

A jump is usually just a short additional force along -Z.
Apply the force and let the physics do the rest.

Double jump (which is physical nonsense :wink: ) can be done with states:

state 1 = no jump
state 2 = jump
state 3 = double jump

transition from state 1 -> 2: collision with ground + whatever you choose (e.g. press a key)
transition from state 2 -> 1: collision with ground
transition from state 2 -> 3: whatever makes the double jump (e.g. press the key again)
transition from state 3 -> 1: collision with ground

There are other ways. Have a search for jump. I think this is asked a lot.

I hope it helps

Yeah it’s the mechanics of it that confuses me. Like I say I made one out of logic bricks (complete with double jump) but I want to see if I can code one in Python. I’ll have a crack at it when I get back from work, and I’ll post the results!

One thing that confuses me - how would I, say, add a “Ground Pound” feature? Something along these lines: http://www.youtube.com/watch?v=dA5PisjvxFo

Notice that the jump movement halts and he hovers in the air for a moment before hitting the ground. How would I go about creating something like this? Sorry for all the questions!

updated script to stop cube and deactivate servo.
you could use a timer and an upwords force of 9.8, to counter gravity, enabling it for 1/2 seconds then disabling it