Reputation: 514
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
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:
input()
to handle the keypress (let's assume player.y = 0
)velocity = 3
. Move player up by 3
. Decrement velocity. player.y = 3
velocity = 2
. Move player up by 2
. Decrement velocity. player.y = 5
player.y
is 0
againWhen 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
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