Code Super Mario in JS (Ep 3) - Timing Accuracy
HTML-код
- Опубликовано: 12 сен 2024
- In this third episode of writing a Super Mario game in JavaScript, I show how to get the timing mechanism right. It's a little boring but oh so important.
We will look at
* Basic simulation.
* Using requestAnimationFrame with timestamp.
* Faking requestAnimationFrame with setTimeout.
* Attaching functions to classes to create methods.
Since we are writing modern JS this code might not run on all browsers yet. I was running Chrome 61 when I wrote this and if you wish to follow I recommend you do too.
Twitter:
/ pomle
Source code with step-by-step commits:
github.com/met...
Music:
Demoscene Time Machine
demoscenetimema...
This is the first time I've seen any tutorial in JS that is this comprehensive and well explained at the same time. My mind is honestly blown. I don't understand everything yet, but I'm hoping to reiterate a couple times on each episode, I've already learnt so much! I find it very entertaining to see the project turning into a game :) 10/10!
Thank you, it makes me very happy to hear that. :)
Glad to have you follow along.
The series popped up in my suggestion feed, so I feel rather lucky to have discovered it!
@@TropicalMelonMan So how did it go for you?
I love love love how you constantly refactor as you go. This is such a great series! I look forward to each one 🙂
I'm very happy you appreciate it!
It's in my opinion one of the most important things when you write code.
Thanks for watching.
I lost you after you made the first refactor, when you have replaced "Hello world" with a canvas but I am still here. ;)
It reminds me a lot of Casey Muratori's "compression oriented programming", where you get code working first, then clean it up and make it easier to use. Even the way you design your classes is the same (writing out how you'd like to call it before writing the class). I like it a lot!
I love how thorough this series is! I'm especially enjoying seeing your workflow and how frequently you refactor. This might be my favorite JS gaming series so far and by far! Thanks for sharing your wisdom with us!
@27:24 Okay no. You even have a stable Timer.js class 😭🙏. This series was made for me. I managed to make my own in Unity, but I've been struggling to make one in JS for 2D physics. This is great!
Perfect. Just perfect. I was having a problem understanding this game loop version before. This video helped me a lot. Eagerly waiting for the next episode. Thanks a ton
For now I'm watching each episode and trying to understand what you're doing, but by the end of the series I'll definitely be coding along to recreate it myself!
I hope you don't mind if I'm putting the end result on my website when that's done (I won't forget to credit your work).
Mario is such a classic and seeing the logic behind it makes me respect the developers even more. Thank you for this series!
Feels amazing coming back to this series after +4 years as a js developer and also amazing me how this series aged well!
Great work, wish you the best!
Absolutely loving this, especially seeing how you refactor.
Love this serie. As a developer I remember the "DHTML-time" back in the days :D
by far the best tutorial on canvas and game coding i have ever seen. keep on creating! 10/10!
Need help? Visit the Discord chat discord.gg/ZAP8wVr
This is totally different from other JS tutorial. It gives me a tons of new information. Really really thank you! from Korea
"It's time to do some clean up!"
Great job! I am impressed of your programming skills and how you keep everything in order. One thing: i think the original mario uses different parabolas on the jump and fall - to make that great game feeling.
1. part - okay, easy enough
2. part - what? oh I see..
3. part - WTH???
I'm starting to get lost in all of this code. Don't get me wrong, you are great teacher, I just don't have enough experience.
Is there anything in particular in part 3 that you found difficult to grasp? Perhaps I can focus more on similar parts in the future.
Well, It's just too much code and I can't remember all the functions, objects, variables, scopes, modules... And the new syntax doesn't help me orientate either.
Yeah, someone needs to make a crash course for ES6, or at the very least, make a video for transitioning from ES5 to 6
same here, at first it looked quite easy. But now its overhelming.
I followed along fine, great tutorial and I love the accumulator pattern. Seeing ES6 to me now seems normal I dont even remember its different to old syntax. Arrow functions are the best!
These videos are great! Glad you're back at it again.
Awesome. Can't wait for the next. Very good tutorial, also the cleaning and moduleising..
DA BEST CANVAS TUTORIAL I'VE EVER SEEN ON RUclips!
You should call yourself code janitor. You're the best at cleaning code!
Your velocity should be updated in proportion to deltaTime (scaled by gravity / acceleration) just as your position is.
You are correct. Thanks, I missed this. Will do some house cleaning in the intro of next episode to rectify that.
Nice! Decoupling the game frame rate from the clock frame rate is a helpful big detail that will totally pay off further on the project. Now, I believe you will call several entities for NPCs and the like, so I presume you will make them all share the same game frame rate? Maybe I'm wrong but, if all the entities are on different time frames, will it be hard to program the collision function due to inconsistencies on the time stamp?
Looking forward for the next episode! Thanks!
Yes, everything in the game world will share the same timing.
This series is so damn comfy
Отличный канал. Отличное видео.
Thanks, appreciate it!
Yes! new episode! Love it!
hi congratulations on the videos, you are a very experienced and kind person, you could add subtitles to the video, I saw here from the playlist most of the videos are without subtitles, I don't know your language and I watch by legenga. thank you.
Awesome Series!!!!!!!!!!!!
Well done thanks for making this. It has helped me so much
Great tutorial! Well explained. I have been able to follow along no problem but when I get to the end of this section my mario seems to jump really fast at first, so fast you don't even see the animation looking like he is halfway jumped by the time the page is loaded. I have downloaded your code and ran it and have the same issue. Thoughts?
Jesse Burton I got the same issue
the same
It will go away in later episodes. It happens because your computer is slower. Can be fixed by starting the game on user click for example so that everything is loaded before the game loop starts running.
The Master is back! :)
Great tutorial Meth! However, I have one question left. If our delta time is a constant number then why do we multiply every variable with it? (if we change the delta time, maximum height, Mario's speed and etc. will change)
I have the same question... makes no sense to me (I removed it from my code).
--- TOC ---
What is this video 0:05
To start writing code 1:10
--- My memo ---
What is velocity? 1:13
Weeeeeeeeeee 1:45
Part 1 was very interesting
Part 2 was useful for the game but not as interesting
Part 3 is very very nice :)
But I didn't understand what the cause of the parabola height problem was neither how added lines fixed it.
Anyway, you successfully explained how to decouple internal time from game time, something that I didn't feel at ease before !
Hmm, perhaps I missed explaining the cause of the problem properly. I was struggling a little to get that episode together. Anyway, the cause is that the deltaTime has a slightly different value on each update loop. In worst case, if the browser drops frames, it gets multiplied. Now if we simulate in the beginning of the jump when the velocity is the highest, and we get a deltaTime 4 times bigger for one update cycle, that frame will move Mario four times further before the velocity starts to drop, compared to a stable frame.
Hello meth wat is that you do asign a función to a method that is calling inside the class the one in timer hoy call inside the constructor and asign outsider to a function
Esperando ansiosamente el siguiente capitulo de la serie, y los demás... Saludos desde España, y gracias por tu trabajo.
Isn't the 2 function mario.draw and mario.update should be an anonoymous inner function considering those two are assigned to a function variable!?
Awesome job.
Brilliant ! Bravo
turn on the subtitle option please.
Mr. Clown I don't know what this means even. Please specify and I'll do it
Meth Meth Method there is no CC option in this video means no auto English subtitle. Other video were fine.
Sorry, I can't find anything on my end to enable that. Maybe it's an auto thing and it dismisses my voice.
click the cog button
I understand everything here except from the line
accumulatedTime -= deltaTime;
What is the point of this as I don't understand what it's purpose is it to actually be there.
Any help greatly appreciated!
If you were to not subtract deltatime the while loop would go on forever. The point is to update the amount of times it should have since last call. If the accumulated time (time since last call) is less than the frequency of which the update function should be callrd nothing happens, but if it is more, it will call the update function until it has updated the amount of times it should have in an ideal world. It does this until the value of accumulatedTime is less than the deltaTime variable and therefore also the update function has been called enough times.
Hope this makes sense.
This is a great series. However I feel it doesnt work well for teaching. Too much refactoring and its easy to get lost and loose the flow of control and forget what exactly is happening. This kind of thing is great if you are probably programming in real life, but the series feels unstructured with too much refactoring that its almost hard to follow why things are happening the way they are supposed to.
Or it could just be me who has trouble understanding all this. Good program though, but not a good tutorial series to follow even for intermediate programmers(since they may have no idea about game programming but might have other experience).
I MEAN SMART
you be best, in the canvas y javascript
Thank you very much. Can you do a match 3 type game please?
Timer.update = function update(deltatime) wath the hell is that called
Is there a reason why you name some .js-Files with an uppercase letter?
Marionaise yes, when they export one main class as default.
This video makes me feel like programming is not for me even though I'm already intermediate.
nice) thx a lot ..
Thank you for your efforts, great tutorial :)
Why do you always put a name when assigning a function / method to a variable ? You could just do mario.update = function() {}; Anyway awesome serie, keep it going !
Apotheose Fr to make the code, and stack traces more readable in case of error.
And i love you for that. So simple -> So helpful
Your mainloop is interesting but there is more robust versions of it already done on the web, for anyone that is interested you can checkout this heavily documented github github.com/IceCreamYou/MainLoop.js
For example; in this video version, if the user tabs out, the browser ins't gonna call requestAnimation frame. If the user tabs in, the accumulator is going to try to catch up and throw the loop into a kind of "Panic" state, which is very similar to an infinite loop.
You could code in a "pause game" function for when the user is tabbed out. Quite simple. You could also do it by running the physics on a server and updating the client, with the client doing some predictions like agar.io
I'm having a problem in minute 19:34. I can't get the same outcome, and I can't seem to get it to work
My problem is that the parabola of Mario's jump is very high, and he leaves the screen. Also, mario sprite is drawn only two times before he gets to the higher point in the parabola and starts falling.
I've noticed that in the first iteration of the update function, the value of deltaTime is significantly bigger than in the rest of iterations. This happens the same way no matter if I call the update function using requestAnimationFrame or setTimeout. Does this mean that the problem is pc performance (it takes too long to render a new frame and so in the first iteration pos is updated by mario.vel times a *high* deltaTime)?
Is anyone else experiencing this difficulty? any ideas on how to solve?
Problem was solved by the author a few seconds after xD.
Was it the startup slowness? :)
When we start finishing up the game we will not bootstrap from time 0, but use the time from when the timer was started instead.
Yes, it was. With the corrections made with the Timer class it got better for a while, but now it's broken again. The parabola seems ok now (and it's shape is stable) but it's working really really slow now. Especially when I uncomment the drawBackgroundLayer part. I guess I am making something wrong in the layers functions to make them to slow ?
Can you show your code? There's a plethora of things that could possibly be wrong. Source code for the project is in the description if you want to compare it to yours.
If making this tutorial is not enough generosity for you, and you can check the code, then here it is:
github.com/solanoepalacio/supermario/tree/master/public
Yo are rocking awesome! I'm learning to code mostly online. People like you are giving me this chance... I will be forever thankful. I looking forward to giving back to the community when the time comes (when I'm experienced enough)
Great videos, Normally I see a lot of bad programming practices and styles in youtube tutorials but yours are the best that I have seen. I do have one recommendation thought which is to use inheritance for your Mario class. Check out the code: gist.github.com/anonymous/773e5517043bd93d062419927e92d9d8
I AM SMAT
you doing things not necessary🤔
At this point, your series lost the brilliance and clarity that first two episodes had. Maybe you should redo these.
As something gets more built up it also gets more complicated. There is no way to avoid this (sometimes hard to remember) complexity if you also want to show us cool projects. There are a million people doing videos of how promises work or how ES6 works and they take each item and can do a clear explanation because its just an example and not tied up in a complex program.
I think the reason this series is complex is because of so much game theory(is that what it is called?) involved. The promises or higher order functions part is pretty fine. Its the abstractions of game programming that make it more complex.
I disagree on the brilliance part. This series is a stellar example of factoring and making code concise. I agree that is lacks clarity though. A lot. Doing so much refactoring is good if you actually let people understand what's going on. I feel like this video should've been twice as long at least.