Jumping Mechanics Again

So, I’ve asked this question before and had it answered. I guess I’ve decided to advance the mechanics of it, but there are always flaws. Now, instead of the player playing one consistent jumping animation, I thought of adding segments to it.

Like the player jumping off the ground, the player falling from midair, then the player landing on the ground. Since the amount of time in the air might vary, I thought it would a considerable idea.

Now problems consist of:

  • The player not doing the landing animation but resetting to its idle animation when landed.

  • When the player jumps without walking, it jumps, but it remains suspended in midair until you move.


from bge import logic, events


scene = logic.getCurrentScene()
cont = logic.getCurrentController()
own = logic.getCurrentController().owner


armature = scene.objects['PlayerRig']
JumpSensor = scene.objects['PlayerJumpSensor']

##Keys##


key_none = logic.KX_INPUT_NONE
key_tap = logic.KX_INPUT_JUST_ACTIVATED
key_active = logic.KX_INPUT_ACTIVE


SPACEKEY = logic.keyboard.events[events.SPACEKEY]
UPARROWKEY = logic.keyboard.events[events.UPARROWKEY]


##Properties##


JumpForce = 10


##Jumps while standing##


if JumpSensor["Grounded"] == True:
    if SPACEKEY == key_tap:
        armature.playAction("PlayerJump", 0, 5, 1, 1, 0, 0)
        own.localLinearVelocity[2] = JumpForce
        own.localLinearVelocity[1] = JumpForce*-1

##Run and Jump ##


if own["RUN"] == True:
    if SPACEKEY and UPARROWKEY == key_active:
        armature.playAction("PlayerJump", 15, 19, 0, 0, 5, 0)
        own.localLinearVelocity[2] = JumpForce
        own.localLinearVelocity[1] = JumpForce*-1
        if JumpSensor["Grounded"] == True:
            armature.playAction("PlayerJump", 19, 25, 1, 1, 0, 1)

##Animation when player is in midair##
if JumpSensor["Grounded"] == False:
    armature.playAction("PlayerJump", 5, 5, 1, 1, 5, 1)

Well, I guess it took time and experience to solve this myself…

Either way, here’s the code:


from bge import logic, events


scene = logic.getCurrentScene()
cont = logic.getCurrentController()
own = logic.getCurrentController().owner


armature = scene.objects['PlayerRig']
JumpSensor = scene.objects['PlayerJumpSensor']
##Keys##


key_none = logic.KX_INPUT_NONE
key_tap = logic.KX_INPUT_JUST_ACTIVATED
key_active = logic.KX_INPUT_ACTIVE


SPACEKEY = logic.keyboard.events[events.SPACEKEY]
UPARROWKEY = logic.keyboard.events[events.UPARROWKEY]


##Properties##


JumpForce = 4
ForwardForce = -1


if own["RUN"] == True:
    JumpForce *= 2
    ForwardForce *= 5


if own["RUN"] == False:
    JumpForce *= 2
    ForwardForce *= 2
    
##Jumping##


if JumpSensor["Grounded"] == True:
    if SPACEKEY == key_tap:
        #Jump action here
        own.localLinearVelocity[2] = JumpForce
        own.localLinearVelocity[1] = ForwardForce


if own["RUN"] == True:
    if SPACEKEY == key_tap and UPARROWKEY == key_active:
        #Jump and run action here
        own.localLinearVelocity[2] = JumpForce
        own.localLinearVelocity[1] = ForwardForce


if JumpSensor["Grounded"] == False:
    if own["RUN"] == True:
       #Midair while in running state action
        if JumpSensor["Grounded"] == False:
            #Landing state action
    if own["RUN"] == False:
        #Midair after jumping action
        if JumpSensor["Grounded"] == False:
           #Landing action
    if own["Armed_Primary"] == False:
        #Arm animation when jumping, while unarmed

By the way, instead of

own = logic.getCurrentController().owner

you could just do

own = cont.owner

since

logic.getCurrentController()

is already assigned to cont.

As Nicholas said and in addition to that, ive changed i tiny bit of your code.


from bge import logic, events


cont = logic.getCurrentController()
own = cont.owner
scene = own.scene


armature = scene.objects['PlayerRig']
JumpSensor = scene.objects['PlayerJumpSensor']


##Keys##
key_none = logic.KX_INPUT_NONE
key_tap = logic.KX_INPUT_JUST_ACTIVATED
key_active = logic.KX_INPUT_ACTIVE


SPACEKEY = logic.keyboard.events[events.SPACEKEY]
UPARROWKEY = logic.keyboard.events[events.UPARROWKEY]




##Properties##
JumpForce = 4
ForwardForce = -1




if own["RUN"]:
    JumpForce *= 2
    ForwardForce *= 5
else:
    JumpForce *= 2
    ForwardForce *= 2
    
##Jumping##
if JumpSensor["Grounded"]:
    
    if SPACEKEY == key_tap:
        #Jump action here
        own.localLinearVelocity[2] = JumpForce
        own.localLinearVelocity[1] = ForwardForce




    if own["RUN"]:
        if SPACEKEY == key_tap and UPARROWKEY == key_active:
            #Jump and run action here
            own.localLinearVelocity[2] = JumpForce
            own.localLinearVelocity[1] = ForwardForce


else:
    
    if own["RUN"]:
       #Midair while in running state action
        #Landing state action
    else:
        #Midair after jumping action
        #Landing action  
         
    if not own["Armed_Primary"]:
        #Arm animation when jumping, while unarmed

You used checks to check if the check is not checked but if the check is already not checked then why check for it again?

anyway you can check statements without using == true or false, using == true creates a double check.

if something:

this already returns true if something holds some kind of data. then you can check the false state by doing

if not something:

the checks i was talking about?


if JumpSensor["Grounded"] == False:
    if own["RUN"] == True:
       #Midair while in running state action
        if JumpSensor["Grounded"] == False:
            #Landing state action
    if own["RUN"] == False:
        #Midair after jumping action
        if JumpSensor["Grounded"] == False:
           #Landing action
    if own["Armed_Primary"] == False:
        #Arm animation when jumping, while unarmed

The very first line checks if it is False, so the other 2 times are not needed because that property is False already.
Also you check if true then after it you check if false, you can handle that with an else statement.


if something: # so this return true if it holds data (or if it is a boolean at true state)
    #code for True
else: #this is the False safety net
    #code for False

So, I should perhaps fix it then? Alright, thanks!