Jumping in Panda3D[Solved]

Just an algorithm where the floor level is zero.

from direct.showbase.ShowBase import ShowBase
from direct.task import Task

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.disableMouse()
        self.camera.setPos(0, -10.0, 0)
        self.box = self.loader.loadModel("box")
        self.box.reparentTo(self.render)
        self.jump_speed = 0
        self.gravity_force = 9.8
        self.jump_status = False
        self.accept("space", self.set_jump)
        self.taskMgr.add(self.gravity, "gravity")
        
    def set_jump(self):
        if self.jump_status == False:
            self.jump_speed = 4
            self.jump_status = True

    def gravity(self, task):
        self.box.setZ(self.box.getZ()+self.jump_speed*globalClock.getDt())
        if self.box.getZ() > 0:
            self.jump_speed = self.jump_speed - self.gravity_force*globalClock.getDt()
        if self.box.getZ() < 0:
            self.box.setZ(0)
            self.jump_speed = 0
            self.jump_status = False
        return task.cont

app = MyApp()
app.run()
1 Like

If I’m not correct I believe that currently the code has implemented gravity and the upwards/downwards bit, what do you think I should do next?

Thanks!:yum:

Well, I think that the next thing might be detection of hitting the ground, and thus ending the jump.

Ah ok, and I’m guessing that’s the last step. So how would I do that exactly?

Thanks!

To quote myself above:

[edit]
Depending on what you’ve added to your code since last you posted it, the above may not be quite the last step. You still want to prevent the player from jumping indefinitely while mid-jump, and last I saw, your task wouldn’t have worked properly (as it lacked an appropriate return-value). However, let’s worry about those things once we’ve dealt with the hitting the ground and ending the jump!

Ok so I tested the code and all it does is that if you press the space bar it will slowly lift the panda. It didn’t go down at all? Or do we have to put that in?

I just tried using your solution and it worked perfectly! Thank you so much, you’re a life saver! If it’s not too much, could possibly explain each part of the code?

Thank you my dude!:blush:

1 Like

I think it would be better if you indicated which part of the code you do not understand.

 def set_jump(self):
        if self.jump_status == False:
            self.jump_speed = 4
            self.jump_status = True

    def gravity(self, task):
        self.box.setZ(self.box.getZ()+self.jump_speed*globalClock.getDt())
        if self.box.getZ() > 0:
            self.jump_speed = self.jump_speed - self.gravity_force*globalClock.getDt()
        if self.box.getZ() < 0:
            self.box.setZ(0)
            self.jump_speed = 0
            self.jump_status = False
        return task.cont

I think we will start with the function of gravity. The first line is the calculation of the jump momentum. which causing each game frame, but for this multiplication by zero gives zero, the character does not fly anywhere.

self.box.setZ(0+0*globalClock.getDt()) 

However, now back to the set_jump function, which reports acceleration, and multiplication now gives a positive result. We also set the status that we are in a jump:

self.jump_status = True
self.box.setZ(0+4*globalClock.getDt())

Now we are rising above zero. Then we begin to consider the fall of boxing, after the condition:

if self.box.getZ() > 0:
            self.jump_speed = self.jump_speed - self.gravity_force*globalClock.getDt()

Where self.gravity_force is the force of gravity. I we gradually reduce the strength of the jump.

self.jump_speed = 4 - 9.8 *globalClock.getDt()

After reaching the floor level, that is, Z = 0. We set the jump status to False and zero the positioning error and jump speed.

It is worth mentioning the condition in the function: set_jump,

if self.jump_status == False:

it prohibits jumping if we have already jumped and have not yet completed the jump.

Very simplified form of recording:

from direct.showbase.ShowBase import ShowBase
from direct.task import Task

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        self.jump_speed = 0
        self.accept("space", self.set_jump)
        self.taskMgr.add(self.gravity, "gravity")
        self.Z = 0
        
    def set_jump(self):
            self.jump_speed = 4
            
    def gravity(self, task):
        self.Z = self.Z+self.jump_speed*globalClock.getDt()
        if self.Z >= 0:
            self.jump_speed = self.jump_speed - 9.8*globalClock.getDt()
        print ("Z =", self.Z)
        return task.cont

app = MyApp()
app.run()

Press the space bar while minus to see how it works.

1 Like