Math for Game Developers - Jumping and Gravity (Time Delta, Game Loop)
HTML-код
- Опубликовано: 25 авг 2024
- Getting Mario to jump with gravity by using a game loop and a delta time to break the velocity vectors into small pieces and apply them over time.
Question? Leave a comment below, or ask me on Twitter: / vinobs
11 years old and still useful thank you ❤
Mathematician: "Parabola"
Jorge at 3:57: "Curvy thing"
I love it XD
Best thing about these videos is how you explain something, and then give an example of how it can be applied. This correlation is very important when it comes to learning and so many other guides and videos miss out on this.
Motivated examples are a core of this series, but my secret ulterior motive is to change the mind of anyone who thinks they are bad at or don't need to learn math.
@@JorgeVinoRodriguez I see i was one of them~~~~~~ now i need one ughgh haha
Exactly this lesson is like gold for game programmers. Awesome job man, God bless you.
Mh, this is not true actually. This kind of jumps feel very akward like on rubber band.
THIS IS WHAT I NEEDED! You are so beginner-friendly unlike those other articles and stuffs out there that I find complicated.
Thank you so much. :)
Haha, I lost it when you cracked up on step 3 of your game loop definition. Your personality really make these a pleasure to watch and learn from.
Nice logic explanation sir.
p.s. i see 1 dislike. ..I'm sure it was Luigi
I think it was Toad. Luigi usually jumps even higher.
One of the 14 dislikers here. My main reason for disliking the video was that it said "math for game developers" but was clearly targeted at people with no experience in game development (people who need to have the concept of a delta, the game loop, and a tick explained to them). A name like "math for aspiring game developers" would have kept me from clicking, and thus saved me time.
Hha
Nguyễn Tuấn and here comes along 6 grand kids
Good stuff bro - appreciate you contributing your knowledge to us learners. This is what makes the internet great to me.
This is not what I searched for, but man am I glad I found your channel
This video is so beginner-friendly that even i who just came upon this randomly understood it, and i don't even have alot of coding experience.
You don't need coding to learn this stuff, the language is only 20% of programming. The rest of good communication, problem solving, planning, methods, math, and etc.
I find your videos very illustrative and very vey useful, keep doing the goood work and showing noobs (like me) how to do the magic! Thanks
Starting in the very next video I upload all source codes for the video to GitHub. :)
Nobody talks about Mario's most impressive skill, his ability to demolish with his skull.
just wanted to say you have a really good teacher vibe. i'm catching on to these concepts a lot easier than some other videos that are full of content but super dry lol. thanks.
this video is pure gold to me. THANKS SOO MUCH!!
Although I'm learning Java game development and not C++, I found this video very useful so thanks a lot :)
Was wondering how you did this for Java
Helped me with creating realistic arrows for my game, thanks.
bro what an explanation, thanks so much
ultra mega awesome!! thank you very much!
no thank YOU!! You're very kind for pumping me up with all your kind comments
@@JorgeVinoRodriguez there are 100+ videos ahead that I intend to watch so I’ll go on pumping if you don’t mind👹
I've been looking for this kind of tutorials. thanku so much!!!!
Thank you! I need this for my Java Game :)
thanks for the help, this was confusing the crap out of me
Yes I am. In the next video I upload source code, so you can see what's going on better.
i was coding with low-fi music and forgot i left this video running, matched perfectly with the music. you guys should try it
Thank you so much for this. This is exactly what I needed.
VERY well explained, thanks!
You should have used lower-case g because Capital G is used for the gravitational constant(around 6.6 × 10^-11) and lower-case g is used for acceleration due to gravity(g= Gm/r^2) :).
*Here's the C# version (for Unity) that worked for me; you'll want to use a kinematic rigidbody instead of a dynamic one:*
public class jumpingAndGravity : MonoBehaviour {
private Camera cam;
public Transform mario;
public Rigidbody2D rbMario;
public BoxCollider2D boxMario;
private CamCoords camCoords2;
float prevTime;
float currTime;
Vector3 gravity;
// Use this for initialization
void Start ()
{
cam = Camera.main;
rbMario = mario.GetComponent();
boxMario = mario.GetComponent();
rbMario.position = new Vector2(0, 0);
rbMario.velocity = new Vector2(2f, 2f);
gravity = new Vector2(0, -2);
}
// Update is called once per frame
void Update ()
{
prevTime = currTime; //store the time from the last frame
currTime = Time.time;
float deltaTime = currTime - prevTime; //store the difference in frame times
//if deltaTime gets too big, lock it
if (deltaTime > 0.15f)
deltaTime = 0.15f;
}
public void FixedUpdate()
{
Vector3 camCoords = cam.ScreenToWorldPoint(new Vector3(cam.rect.xMin, cam.rect.yMin));
//if too far right
if (mario.position.x > Mathf.Abs(camCoords.x))
{
rbMario.velocity = new Vector3(-rbMario.velocity.x, rbMario.velocity.y);
}
//if too far left
if (mario.position.x < camCoords.x)
{
rbMario.velocity = new Vector3(-rbMario.velocity.x, rbMario.velocity.y);
}
//if too far up
if (mario.position.y > Mathf.Abs(camCoords.y))
{
rbMario.velocity = new Vector3(rbMario.velocity.x, -rbMario.velocity.y);
}
//if too far down
if (mario.position.y < camCoords.y)
{
rbMario.velocity = new Vector3(rbMario.velocity.x, -rbMario.velocity.y);
}
//change position based on old position + velocity and time diff between frames
mario.position = new Vector3(mario.position.x + rbMario.velocity.x * Time.deltaTime, mario.position.y + rbMario.velocity.y * Time.deltaTime);
//change the velocity based on old velocity + the gravity and time difference between frames
rbMario.velocity = new Vector3(rbMario.velocity.x + gravity.x * Time.deltaTime, rbMario.velocity.y + gravity.y * Time.deltaTime);
}
}
this is a nice explanation.
your awesone man
Thanks Sir. May God Bless You! This is the kind of Knowledge I'm seeking. Thanks once Again Sir!!!
Thank you Jorge
Hey man, thanks for these tutorials, they are very useful even 3 years after you made them. Can you show us what's in the KeppMarioWithinBorders function?
Sorry. It's something like:
if (pos.x > border_right || pos.x < border_left) velocity.x = -velocity.x;
if (pos.y < border_bottom) velocity.y = -velocity.y;
Not sure I still have the source code for that one lying around though.
Math is really cool when its actually used to create something..
PERFECT, JUST PERFECT
I don't understand why it's t' MINUS t
Sounds like I can use this to make a variant of Pong where the ball is actually affected by gravity, not always flying in straight lines. Tbh classic Pong is really more of an air hockey game than a ping pong game, I always thought it was weird how the ball always moves in a perfect straight path. Should be interesting to try out.
This helps more than school
Nice explanation thank you :)
Awesome work dude! I'm gonna subscribe. More videos :D
Thanks for the video. I got a question:
Currently, the way I'm making objects move in my games (as I explained in a comment to another video of yours), is like so: Every object has a dx variable and a dy variable. Every game-loop cycle, dx is added to the x position of the object and dy is added to the y position. When I want to make an object 'fly' or 'jump' in the shape of an arc, like you did, what I do is this: Create another variable named 'gravity', in the object I want to move. Then set it equal to some positive constant value. Every cycle of the game loop, I subtract this value from the dy value. So every cycle of the game loop, dy gets smaller and smaller, then 0, then negative, until the object hits the floor. dx stays constant.
This approach achieves exactly what your approach with vectors achieves. What I'm asking is: Would you recommend using the more mathematical vectors-approach? Will it be more beneficial in the long term? Or is my approach equally valid also in the long term?
Thanks a lot
As long as you understand how the mathematics behind your code works, and as long as your code reflects that mathematics properly, and as long as your code is clear and concise, the implementation isn't terribly important. :)
Your code actually is using Vectors, even you're not using a "Vector" class. Your x and y variables represent the x and y position of your object, which is a vector. Same with dx and dy, they represent the velocity of the object, which is a vector. A rose by any other name would smell as sweet.
Okay thanks :)
I love this magic ))
fuck so i do need math.
Game engines tend to hide the math from you so it's possible to make games without using math, but the more math you learn the more designs will open up to you. The math I present here is the most basic math that is always worth it to learn. Later in the series is advanced math that you may choose whether or not to learn based on your goals.
It's really easy to create simple platformer game or anything like that with no math skills whatsoever, because all modern game engines, frameworks offer their own built in physics system even more than that on some engines. But if you want to create really advance stuff like Procedural Map Generation, Maze Generator, and stuff like that will require you math abilities to do so but there are always dozens of dozen tutorials in google so you can learn it any time if you don't know math.
Hey really enjoying this series and finding it immensely helpful. Just a question though, are you resetting Mario's velocity somewhere? Each time he touches the ground he jumps again so was that code not shown in this video?
Why should I multiply DeltaTime to Gravity?
Very Helpful!
4:55 (functions)
great, thanks!
may some important notes: the most window-frames have the 0-point in the top left so updating the velocity of the player is negativ when there is no "jump-impuls": dy = dy - dt*dgravity
Best game loop and explanation i have found.
But is this using milliseconds or nano seconds?
qwer josh Generally in games when you see float the time is in seconds, and an integer value gives it in milliseconds. I've never seen nanoseconds in game frame code, only in profiling code, as game loops are in the order of milliseconds. (1/60 of a second is 16 milliseconds.)
Jorge Rodriguez So if your dealing with milliseconds you would just divide by 1000?
Im doing it in java and using System.getTimeMillis(). but my problem is that when i try to test it while dividing by 1000, i just get 0.0. I think this is just because its going so fast with nothing in the loop, so its so small that its beyond the precision of a double.
Anyway thanks for the help
System.getTimeMillis() returns an integer, make sure you cast it to a float before dividing by 1000. It could also be that less than 1 ms has passed since you called last - do a System.out.println to see the value directly, before you do the subtraction.
Jorge Rodriguez Thanks for the help, it does seem to be that less than a millisecond is passing, so it should be fine when i put a game in the loop.
you just coded every pc demo from the early 90's xD
😮 thanks
Hello, I am not sure about part of my game here. The physics has to be mathematically perfect, but the gravity seems to drift off.
If you think of the y position as a kind of compounding interest, it will fall faster the higher the fps
Thanks !
thank you
nice!
Yes that's true :3 I cover input in the next few videos.
Hey jorge, is this the video that i should be following right after dot product video?
I dont understand how Mario can go up because we apply a up vector of 2 and then gravity of 2 in the same frame. Mario should stay at y 0.
That's a great question! The gravity is an acceleration, so it doesn't apply immediately. It only applies a little bit every frame, so it doesn't cancel out the effects of the velocity.
Think about it like throwing a ball up in the air. Its acceleration in constant, it's always accelerating back towards the ground even immediately after you throw it up. It can accelerate down even while it's moving up, the result is that it moves up increasingly less fast as time goes by.
The formulas in the Update() method show you how the relationship between the position velocity and acceleration work out. Notice how acceleration (gravity) is multiplied by dt (a small number) before adding it to the acceleration.
thx for explanation :)
hey, i just jump in your code looking for tutorials, is correct to calculate the position before the velocity? 9:11
+alessandro Malusà I don't think position before velocity or velocity before position matters that much.
Why do you set velocity after using it to set the position?
For next time. On the next frame the game will do the same calculations again, using the new calculated velocity. Good question!
Why the timestep is changing ? isn't it supposed to be constant, like 1/60fps or 1/30fps ?
If it's constant, it means we are adding a constant amount of velocity and constant position vector every game loop.
Thanks.
For sure it's better to fix the timestep. I have it variable here because it's easier to do that way and I'm focusing on the math.
Ok thanks. Really great tutorials.
Nice
When he said we cut up the line, I thought he was talking about Calculus.
Old comment, but for anyone seeing this, I'd like to say that the method is calculus in disguise. (More specifically numerical integration.)
Thank you so much for this video! Btw, which graphic library did you use?
Hand-written OpenGL
@@JorgeVinoRodriguez I love this guy already!
Yes.
I wrote similar code. But my player is still falling more slowly if I wave the mouse. How can I fix it?
how can I keep that object within screen boundary?
Can you explain how to do this with fixed time step game loop?
You forgot step 0 of the game loop: Listen! Controller input is important too :)
Hi,
What exactly 'dt' is?
is it millisecond value of difference between two time?
I implemented jump by using fixed value 'dt' to make situation more simple and It seems fine to me...
Is it critical to make 'dt' varies??
btw, thanks, I really enjoy watching your video!
dt is seconds difference between the time of this frame and the time of last frame.
dt = this_frame_time - last_frame_time
dt often varies, but as you'll see in later videos, it is often better to use a fixed, non-varying dt. There are techniques to do this, outlined in the numerical analysis videos.
Now if only I can figure out how to implement this in 6502.
good job , would you upload the complete code ?
is there anyway Jorge we could see the whole code for this project I just want to know how you made this work with OpenGL.
Thanks, very helpful. I just have one question: how did you create the "update" function?
while (true) { update(); render(); }
hi i cant seem to figure it out could anyone please help me thanks.
where can i find the source code? (for this session)
mic00110 Sorry it's not available for this one, but the same gravity code is available in later ones.
can you tell me which tool you are using for demonstrating this?
Wouldn't this have the same effect as just making gravity and velocity lower than what it currently is, finding it hard to see the point in having delta T
+Unknown a Think of it in terms of units. Velocity is in meters per second. There are sixty simulation frames per second. If you add the entire velocity into the position in every frame, you will add it sixty times per second. But you're supposed to add it in only one time per second. So you need to multiply it times the amount of time being covered so that the contribution of velocity gets spread over the whole second.
Awesome! Where's the actual jump code? I mean the code after the video is just continuous jumping, where's the one where you actually press a button and then jump straight upwards? (Assuming that only jump is pressed and not move right or left)
I omitted the code that processes button presses for simplicity. In later videos I share the code for a more complex example that includes the button press code.
What is the difference between Vector and Point in your implementation? I guess Point has less methods, anything else?
Because a vector can be used to represent a point there's no difference between the two. In fact, all game engines I've seen use vectors to represent points and have no point class. I just wrote a point class to help scaffold the idea until later videos when I explain that points and vectors are the same.
Are you using operator overload? Becouse I cant get it to work
So is this kinda like mimicking a flipbook?
Yup all video games are a glorified interactive flipbook
@@JorgeVinoRodriguez That was very poetic of you, Nice video btw.
thinking in terms of traditional/ cel animation frames helped me get a better understanding too.
Unity/C#'s Monobehavior has a lot built-in like position and (if a rigidbody is added) velocity, but I'm trying to do things your way, "from scratch" (albeit in unity and c#). In the script, is Mario a class and are position, velocity, gravity properties(correct word?) of the Mario class? (I've never taken a programming class but I'm reading various sources to try to learn.)
edit: I can't seem to create Mario as a new class because I get the "Object reference not set to an instance of an object" error.
Unity already has a game loop. You won't have to create one unless you're building a game from scratch. (You probably shouldn't build a game from scratch these days, since it's hard.) I don't know how Unity works, but there's probably some sort of Update() method where you can write code that describes how an object's position changes over time. That would be the place for you to start, but bear in mind that Unity is very powerful and you can add objects to Unity's physics simulations to have them do this work for you.
Hey, thanks for responding. :) Yeah I'm familiar with Unity's Update method and how to change positions and velocity over time, but I didn't want to "cheat" when trying to learn the math here, so if there was a way to do it "from scratch" here, albiet in Unity/C#, I wanted to try to do it that way.
bloody heck I actually got it working in Unity. (I didn't think I would) :p Cheers.
I have a question. Does video tutorial belong to khanacademy?
Nah. Sal's videos are way better than mine.
Hi, quick question. Whats the tool you use for the illustration?
At different times I've used either Photoshop or Mischief.
@@JorgeVinoRodriguez Thanx you, its honestly impossible to google this subject for some reason
Do you recommend applying all these concepts in a language like C? I'm trying my hand at unity and a lot of the thing are basically built into the API. I'd like to start with something like C and code everything myself for better understanding. What do you recommend?
Thanks!
This is math, it doesn't matter what programming language you apply it in. The concepts don't change. Coding it up in whatever language is a great way to get a better understanding of it.
Thanks for your reply :)
And i'd also like to thank you for your videos! Probably the best source of math for game development on the web. I'd probably be lost in boring textbooks that I downloaded, before I came across your videos. Keep up the awesome work, man!
Thanks! :)
3:30 Of course...
Why mario.gravity(0,-2). I am using visual studio c#, in that case my mario goes up
In some packages gravity is considered opposite, where positive values make things up down. The math works out the same in the end. :)
Why do you use float, not double?
Bogdan Zhuvak float has 7-8 decimal digits of precision, which is enough for any computation a game needs to do, except maybe those involving time. Since float is half the size of double you pay half on memory transfer operations, eg loading a buffer of float data from disk, or sending a triangle mesh to the GPU.
@@JorgeVinoRodriguez Thanks
I love you.
I recognized delta time from Unity - Time.deltaTime. :)
Is the delta t in seconds?
I think it's one of the typical game loops. Another game loop is
while(true )
while(true)
kill all rest time
handleEvents()
update()
render()
its more stable than the first one
You're right, this is typically better. Some notes on this: I typically write the inner loop as a for loop. This is useful for physics simulations since physics algorithms tend to require a fixed time step for stability. For non-physics applications I would suggest not using the inner loop, since it's more processor-intensive, and most gameplay systems don't need fixed timesteps.
So no matter what your frame rate (lol watching amazing world of gumball and gb is trying to turn into a super Saipan...)is you are not getting any advantage in game if i am correct because the velocity of Mario is in proportion to the dt.
+fun Tertain These days, yes. Old games used to lock dt to the framerate, so if you ran a faster frame rate the game would run faster. But not anymore.
LJorge Rodriguez ok thanks just wanted to clarify on why we were even applying dt to the equation.
I don't understand something:
If Velocity is 2 and gravity is -2, won't these cancel each other out during addition? Shouldn't this result in the character only moving horizontally?
Gravity is multiplied by the timestep (delta t) a small value, so it's really 2 + -2 * a small number, so they don't really cancel out.
but if you are applying a force of 2,2 every frame (keeping in mind this has its own delta time applied) the force you are applying is always bigger than the force you are taking away from it, what is stopping it from from flying upwards and never coming back down.
I am struggling to see why this is not happening as -2 * delta time (assuming 30fps) is -0.06, multiplying it again when it goes through the velocity*delta time part brings it out to -0.0018.
So this makes the Final Vector 0.06, 0.06 + (-0.0018) which is equal to (0.06, 0.0582). This is still a positive number.
Let's do a practice run. I'll consider only the up dimension. It starts at position 0 with a velocity of 2 and a gravity of -2 at 30 fps.
Frame 1. m: 0, v: 2
apply m = m + dt * v => 0 + 1/30 * 2 = 0.066
apply v = v + dt * g => 2 + 1/30 * -2 = 1.933
Frame 2. m: 0.066 v: 1.933
apply formulas again:
m = 0.066 + 1/30 * 1.933 = 0.1311
v = 1.933 + 1/30 * -2 = 1.866
Frame 3. m: 0.1311 v: 1.866
m = 0.1311 + 1/30 * 1.866 = .1933
v = 1.866 + 1/30 * -2 = 1.8
etc etc.
Ah, Many thanks for explaining this i think i understand now!
One last question on that however, if it is decreasing and it will eventually get into negative territory (meaning the character will start to fall). Why does the character bounce?
I'm assuming this must mean his velocity is reset back to 2, but other than that being handled in the window checking code I'm not sure where this is happening
Yes. I put special code in to make the character bounce, so I was cheating. Otherwise it would fall forever and it wouldn't make a very good demonstration. :)
I just still do not understand this what so ever and I have watched this several times now. I am using Visual Studio 2012 trying to get a simple gravity code into the game but I cannot find it anything telling me where I need to put what part of the code. As for your Void main() function it needs to be declared in the MyGame.h file in order to actually use it. Thus there is no postion command only a SetPosition (in my Visual Studio program). Also is the Void Main () function the same as void CMyGame::OnInitialize() function? I have no clue what so ever.
I was hoping to find a clear answer on the net showing me what code to put into the MyGame.cpp file with the void CMyGame::OnInitialize() function and void CMyGame::OnUpdate() function and the void CMyGame::OnDraw() function and what to add to the MyGame.h file.
I'm just lost...
ZwergMeister M After a few videos I start uploading the source code. You can download it and step through the source code with the visual studio debugger, that may help you to understand what's going on.
void main() gets called when the program starts up. Inside of it I implement a simple game loop. For your CMyGame class it looks like you need to split that functionality into a few different places, some into OnInitialize() (the mario.position etc stuff goes in there) and then a the other stuff into OnUpdate and OnDraw().
Take a look at the sample code and if that doesn't help shoot me an email at bs.vino@gmail.com and I'll try to answer any questions.
Jorge Rodriguez My main problem is that your video makes sense, I just have no clue how to write the code in C++ on Visual Studio 2012. Also it seems like in my project I don't have a void main() at all so do I just use OnInitialize() instead?
I do assume some level of knowledge of C++ especially in the later videos. There are many resources to learn and improve your C++ though, they should be easy to find on the internet. I learned it just by reading game engine source code.
As far as where you put your code, it depends on what engine you're using. OnInitialize() sounds like a function that gets called once before the game loop begins. You should put setup code in there but don't put a game loop in there. If you're using an engine then it most likely already has a game loop and does this time step business for you, so you won't need to worry about it. If you're writing your own then you need to make one, it'll be just like the one I made in this video.
So..I'm normally horrified of math, but i want to be a game programmer...YIKES!
But this is very easy to understand. you sir have dstroyed my fear of math!
Btw what field of mathematics is this? Is this trig?
Jake Belmont Most videos until now have been linear algebra, this video is actually Euler integration disguised as something simpler so it falls under numerical analysis. Linear algebra is usually a lower division engineering course and numerical analysis is an upper division applied math course.
So good job.
ahh. well see, i've never taken any of those..but this makes so much sense
I did have algebra and trig in high school but i forgot so much of it, which is why i found this..brilliant job explaining it to dummies like me :D the reson i sucked so bad at math was beacuse i had nothing to apply it to. but this shows it rght there clear as day.
Photoshop, screen recording software, and a tablet.
pls do it for java eclipse
The math for game making always discouraged me , I’m terrible at math and never got to study a lot of it in high school ( I failed one for too long lol) advice mates ?
Old comment but look into Unity (or Godot) and C#. It's a lot simpler than making your own engine (especially with Unity's built-in physics system) and there are tons of tutorials. Still, some of these "math for game devs" tutorials are helpful, like dot product is used in Unity. Other options (arguably even simpler) are Gamemaker and Clickteam Fusion. (Five Nights at Freddy's was made with Clickteam Fusion) But Unity allows for more flexibility.
I can't find the GetCurrentTime() in c#, can you please explain that? The video was awesome >.< btw.
Every code environment has a different way to get the time. You need to find one in your environment that has enough precision (at least milliseconds).
In Unity it's "Time.time" but you can also already get the deltaTime via "Time.deltaTime" (not that me responding probably matters 1 year later :P)