Alright, everyone. Here’s the problem: When I hold space down, it jumps again when I hit the ground. I have the collision sensor for the ground, and a force actuator that goes up on the global z-axis. Is there any way that the sensor only activates when I PRESS space instead of holding it so I don’t jump again when I hit the ground?
the state can have 1 delay sensor that sets an upward force for a period, once thats over a NAND controller can be attached to the same sensor that switches this state off.
...
space = cont.getSensor("space")
jump = 0
if space.isPositive():
jump += .1
up = 150
if jump > 1
up = 0
if not space.isPositive():
jump = 0
move.setForce(0.0, 0.0, up, 1)
GameLogic.addActiveActuator(move, 1)
...
This way, when space is being held, “jump” goes up .1 every logic tic. If “jump” is greater than 1, you can’t jump, and when you let go of space, jump goes back to 0. And of course, this only happens when the player is touching the ground, too (just haven’t coded that yet).
IronShield, something like this works but having to run a python script every logic tick to increment a value seems overkill to me. this is why the delay sensor with states is so useful.
Hi ideasman,
the use of state is good to avoid the ‘flying’ issue but I am not sure that IronShield can achieve his result if he doesn’t use an additional property that is modified when the jump key is released.
so I don’t jump again when I hit the ground?
Keeping the jump button pressed would just activate the jump state again as soon as he touches the floor, and jump again. And this is not what he wants.
He should add a condition to enable the jump state or not.
I guess? What do you think?
IronShield
if you want to use a script, you should try to use that “jump” property that I told you before, to check if you should setForce or not.
If you make sure that the Level button on the keyboard sensor is off (as it is by default) and you use states, then when you switch states (such as going back to your original state), it doesn’t check for keys already pressed down until they’re pressed again. This can be used to avoid this problem.
For other keys (such as movement keys) where you want it to detect them if they’re held down after a state change just switch on Level.
The state actuator. In the actuators dropdown you can use “copy” with that states button selected to turn it on. You can also turn the state on with “Inv” which toggles it’s state between on and off each time you call the actuator.
In which version of blender? I’m asking because I ran some tests in 2.48, and switching states didn’t change the fact that the collision sensor was still “refreshing” the keyboard sensor. Could you make an example .blend that shows this setup?
However, even if that worked, using states to accomplish what the OP wants is still fairly convoluted for just trying to detect when a key is “hit” as opposed to “held” (this is something that True level triggering was supposed to solve).
I think making a fix for this on the system level would be more useful for everyone:
When true level trigger pulse mode is disabled (default setting), and you hit the relevant key, that keyboard sensor should register as “positive” only once, and as “negative” on every subsequent pulse, regardless of whether the key is still held, or there is another active sensor going into the same controller.
ideasman42 - is there a reason keyboard sensors don’t work like that now?
Anyway, I think that Cray really understood the issue properly: you need to know when the space bar is released, and only then allow the “key and collision” combo to activate the actuator.
So, a “reasonable” python script would look like this:
import GameLogic as GL
cont = GL.getCurrentController()
own = cont.getOwner()
# Sen
sen_key_space = cont.getSensor("space")
sen_col_ground = cont.getSensor("ground")
# Act
act_motion_move = cont.getActuator("move")
# Process
if sen_key_space.isPositive() and sen_col_ground.isPositive():
if own.toggle:
GL.addActiveActuator(act_motion_move, 1)
own.toggle = 0
if not sen_key_space.isPositive():
own.toggle = 1
if not sen_col_ground.isPositive():
GL.addActiveActuator(act_motion_move, 0)
That should work fine, given that you have a boolean property named “toggle”.
In which version of blender? I’m asking because I ran some tests in 2.48, and switching states didn’t change the fact that the collision sensor was still “refreshing” the keyboard sensor. Could you make an example .blend that shows this setup?
[/quote]
Not sure I follow here. Anyway, there’s a blend attached of what I mean, remembering the state can be used for a bunch of things if desired (EG different movement / animation / collision detection / whatever when jumping). It’s made and tested on 2.48 (haven’t tried it on 2.49).
However, even if that worked, using states to accomplish what the OP wants is still fairly convoluted for just trying to detect when a key is “hit” as opposed to “held” (this is something that True level triggering was supposed to solve).
I think making a fix for this on the system level would be more useful for everyone:
I’ll always be in favour of improving Blender to make things more usable / useful! Until then, whatever gets the job done. Python / bricks / voodoo / improving Blender’s underlying code. It’s all good. (ok, maybe not the voodoo, but hey…).
i was just thinking about the delay thing. it’s cool that even of you press space when it’s in the air, it’s not going to jump as soon as it hits the ground. Both examples are great.
So, two additional states, just to detect if a key is “hit” as opposed to “held”? I know you’re busy, but could you please address the points I bring up in my previous post.
Thanks.
@ ironShield
“if own.toggle:” means you’re checking if the value is anything but 0, in which case the expression equates to true, and the block below is executed.
So, in short, no; you don’t need to include “== 1”.
Also, I recommend that you look at the example posted by ideasman before you simply use my script. Maybe dealing with multiple states and more bricks is easier for you than using four bricks and one python controller? Well, it is for some people…
Anyway, since everyone has posted a .blend example, I feel I should do the same: .blend is attached.
PS: After looking at the example by ideasman, I realized that there was something which my script didn’t account for. I slightly modified the python code in this example to make everything behave properly.
@Social, the key holding wasnt a problem with 2 states.
I just found the “Level” option only works with 1 sensor connected to the controller.
When more then 1 are, the sensors act like level is pressed.
A few times I thought I found bugs in the keyboard sensor but when looking into it I found it worked as it should (Like the issue when multiple keys are held down and key-ups pulse a positive event).
Sounds like your asking for a “Tap” option for the key sensor so it pulses True then False right away no matter if the user holds or not. (releasing would give no event).
This would be very useful and is easy to add, its probably a good introduction to BGE C++ logic too, Id recommend you take a look at it - Otherwise Im busy with some other BGE dev stuff but could look into it later.
PS, Tap fits pretty nice after the all keys button!
Hey there I talked to Ben and we agree’d it was too hard to make jump work as you’d want,
Benoit just added “Tap” into svn (and yes this will be in 2.49)!
Rather then make this a keyboard option this is available for every sensor like “Level” http://markmail.org/message/oj2z25vsanhdezl6
Thanks IronShield for pointing out this deficiency in the BGE.