well, ive been working off and on on an fps just like everyone and their uncle lately. I decided to go with z3r0 d’s movement script from his fps controls blend for my movement. I got it working with bullet pretty good. Its just that when i jump, i can just hold the space bar and keep hopping. I want it so that you press the jump button and you jump, but you have to releas the button and press it again to jump again. just like any fps out there. I was wondering if there was a way to modify this script in order to achieve this…
# this script simply sums up the motions
# I want to go on this frame
#
# I do this because multiple motion actuators
# on one object at a time don't work perfect
# also to make combined strafe and walk no
# faster than one or the other
speed = 6.0
jspeed = 6.0
sqrt2over2 = 0.70710678
cont = GameLogic.getCurrentController()
obj = cont.getOwner()
act = cont.getActuator("move")
onGround = cont.getSensor("onGround")
if onGround.isPositive():
jump = cont.getSensor("jump")
fwd = cont.getSensor("fwd")
back = cont.getSensor("back")
slft = cont.getSensor("slft")
srght = cont.getSensor("srght")
fspeed = speed * (fwd.isPositive() - back.isPositive())
sspeed = speed * (srght.isPositive() - slft.isPositive())
if fspeed and sspeed:
fspeed *= sqrt2over2
sspeed *= sqrt2over2
jump = jspeed * (jump.isPositive())
act.setLinearVelocity(sspeed, fspeed, jump, 1)
if [sspeed,fspeed, jump] == [0.0, 0.0, 0.0]:
GameLogic.addActiveActuator(act,0)
else:
GameLogic.addActiveActuator(act, 1)
else:
GameLogic.addActiveActuator(act,0)
again, i want to so that i cant just hold the space bar and keep hopping. i want it so that i press it and i jump, but i have to release it and press it agian before i jump again.
Well I don’t have the .blend to test it, but I would do it with a time property:
t = own.time #Timer property
if jump.isPositive() and t < 2: #After 2 seconds jump will not be active-
jump = jspeed #until the jump key is let go, and time rese-
#ts to 0.
else:
own.time = 0
jump = 0
Have an integer property jumping that is initially 0.
modify the script as follow:
# this script simply sums up the motions
# I want to go on this frame
#
# I do this because multiple motion actuators
# on one object at a time don't work perfect
# also to make combined strafe and walk no
# faster than one or the other
speed = 6.0
jspeed = 6.0
sqrt2over2 = 0.70710678
cont = GameLogic.getCurrentController()
obj = cont.getOwner()
act = cont.getActuator("move")
<b>jump = cont.getSensor("jump")</b>
<b>if not jump.isPositive():</b>
<b>obj.jumping = 0</b>
onGround = cont.getSensor("onGround")
if onGround.isPositive():
fwd = cont.getSensor("fwd")
back = cont.getSensor("back")
slft = cont.getSensor("slft")
srght = cont.getSensor("srght")
fspeed = speed * (fwd.isPositive() - back.isPositive())
sspeed = speed * (srght.isPositive() - slft.isPositive())
if fspeed and sspeed:
fspeed *= sqrt2over2
sspeed *= sqrt2over2
<b>if jumping == 0 and jump.isPositive():</b>
<b>obj.jumping = 1</b>
<b>jump = jspeed</b>
act.setLinearVelocity(sspeed, fspeed, jump, 1)
if [sspeed,fspeed, jump] == [0.0, 0.0, 0.0]:
GameLogic.addActiveActuator(act,0)
else:
GameLogic.addActiveActuator(act, 1)
else:
GameLogic.addActiveActuator(act,0)
Jumping should become 1, if you press space and you are jumping. As long jumping remains 1 no jump is possible. If you release space jumping becomes 0 again.
[edit] I haven’t tested this. Let me know if it works.
cont is the controller. [GameLogic.getCurrentController()]
own is not present. Here it is obj. It is the owner of the controller (the object).[obj = cont.getOwner()]
hey … i’m feeling like a fool , please tell me what is meant by
cont
own
Those are just variable names to store the return value of the functions that are called from GameLogic. They could be named anything, and you see people using different names, but good naming will help make code understandable. Although slight abbreviations, these are still understandable. cont just stands for the current controller that was called by the script. Own stands for the owner object of the controller. In other words, the object that is calling and using the script. That might be an armature in this case.
This was an interesting discussion, everyone. I have trouble understanding how it would work without a timed delay, myself.
It’s very simple, in a sense that jump can only be active when obj.jump == 0. Since activating jump changes the value to 1, jump can not be executed until not jump.isPositive, which switches the obj.jump prop to 0 again.
But I don’t see where jump speed is decreasing, so it looks like it’s either on or off. If it’s off, no lift. So how does it go up? Would there be enough speed for that instant in time that it was pressed to make it go up that far? I haven’t done any jumping myself with games so I guess I don’t have any experience with it. I suppose though, if the speed was high enough, it would work. I think I’d still prefer to stretch it out a bit with a delay.
Also, not jump.isPositive() is triggered when the jump key is released. Meaning that holding down the key would keep the velocity going until it was released, or maybe not. I guess I didn’t look at the code that much. Stella will have to tell us how it worked out I guess.
He is using the bullet engine so the velocity after the initial jump is left solely to the physics engine. (Gravity and such other forces take over.)
Also remember that when a pulse goes over the script, it runs through the met conditions at least once, so if you change the condition after it is met, then it will only be recognized at the next pulse pass, meaning that jump = jumpspeed is ran for that one pulse where the conditions were met, which makes it jump. Changing the condition status after it has been met will only influence things at the next pulse pass.
monster>
I think I found a mistake in your modification:
if <b>obj.</b>jumping == 0 and jump.isPositive():
obj.jumping = 1
jump = jspeed
Having just “jumping” would work only if “jumping = obj.jumping”, right?
im using monsters modification. His only works with the correction that you made to it. But, yeah thats the one im using. I couldnt get yours to work. Im sure it works, but im so python illiterate that i couldnt figure it out
oh yeah, errors
PYTHON SCRIPT ERROR:
Traceback (most recent call last):
File “fps_controls.py”, line 43, in ?
TypeError: a float is required
I know what float and int and some other types are, but that doesnt help me here …
When multiplied by a floating point value, an integer will become a floating point, jump itself
will remain an integer. I’m only guessing that that line is 43.
Social:
you are right, jumping must be obj.jumping as this would be a different (local) variable.
To snapshot your timer you need a property because local values only exist as long the script runs (once per frame). You can’t store data for the next frame with local variables anymore (since v2.41).
property int snapshot -1
if own.snapshot == -1:
own.snapshot = own.time
Own.snapshot will not change as long own.snapshot is not -1. You could combine this with other conditions. The assumption is that own.time should never become -1.
I’m sure there are other ways. It depends on what you want.