Quantum Sushi
Quantum Sushi

Reputation: 514

Simulating gravity/jump in game - issue

I'm using a game engine to make my own 3D game in python. I need to simulate a jump and/or gravity, but I'm running into an issue : either the calcul is immediate and my character isn't moving, like, there's no animation, instant blink, or either (if for exemple I had a bigger number in my for loop) it takes wayyyy more time, really slow, it lags and everything, struggling to calculate the jump. I got both extremes, and none works, so I'd like to find a way to make my jump. All I have at my disposition to do this is :

player.y +=
#can be -=, =, +=, etc.

So, do you got any ideas of ways to do this ? I'm not really asking a specific problem, I'd just like to gather some ideas ! And there's even no need to give predone examples, just throw your ideas, like : use this, try with this formula, this function, etc.

Adding some details : what I already tried.

Here is the main solution I tried, pretty basic :

velocity = 3
def input(key):
    global velocity
    if key == "space":
        for i in range(7):
            print(velocity)
            player.y += velocity
            velocity -= 1
        velocity = 3

Which is pretty cool, as you had to your height 3, then 2, then 1 (deceleration as your energy lowers), then you add -1, -2, -3 (acceleration due to gravity), and go back to your starting point. Perfect ! But, as said, instantly done. So if I try this :

velocity = 3
def input(key):
    global velocity
    if key == "space":
        for i in range(61):
            print(velocity)
            player.y += velocity
            velocity -= 0.1
        velocity = 3

Again, instantly done. And if I try higher and higher intervals, at some point I just get it to lag, no in-between where it's done correctly

Upvotes: 1

Views: 141

Answers (2)

pho
pho

Reputation: 25489

Slightly off-topic: You don't want to name your function input() because it shadows the inbuilt input() function.


The problem is that you change the velocity and then iteratively decrement it inside a loop! Because of the way python (or most programming languages, for that matter) works, the program execution moves on to the "draw on screen" step only after it's finished executing your input() function. So when you press a key, here's what your program is doing:

  • Draw a frame and listen for keypress
  • Key pressed! Call input() to handle the keypress (let's assume player.y = 0)
  • Is the key a space? Enter the loop
    • velocity = 3. Move player up by 3. Decrement velocity. player.y = 3
    • velocity = 2. Move player up by 2. Decrement velocity. player.y = 5
    • ... and so on until you exit the loop
    • player.y is 0 again
  • Draw another frame. Player is at the same place they started, so it looks like nothing happened.

When you add iterations to your loop, this process takes longer (so you see lag), but essentially the same thing happens.

To fix this, you need to add the effect of gravity inside the function that draws your frames. For example, you could set a flag when the jump key is pressed, and if you had a function step() that was called at each timestep of your simulation, you could check if the flag is set and then handle the situation

def user_input(key):
    global jump_velocity, is_player_jumping
    if key == "space":
        is_player_jumping = True
        jump_velocity = 3

def step():
    global jump_velocity, is_player_jumping
    if is_player_jumping:
        player.y += jump_velocity
        jump_velocity -= 0.1

        if player.y == 0: # Player is back on the ground
            is_player_jumping = False 

This way, you only change the player's location a little bit before the next frame is drawn, and you can actually see the animation.

Upvotes: 1

Apo
Apo

Reputation: 338

You first need to know what is the current time step because if you have 2 ms between your frames and 20 ms your need to adapt the amount you get into the player's y position each step.

then it would be great to have a player velocity variable somewhere in addition to its position. Then you would have to decide on a velocity to add instantly to the player when the jump occurs and each time step adds a bit of acceleration down due to gravity.

Upvotes: 0

Related Questions