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...

Комментарии • 99

  • @TropicalMelonMan
    @TropicalMelonMan 7 лет назад +37

    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!

    • @meth-method
      @meth-method  7 лет назад +2

      Thank you, it makes me very happy to hear that. :)
      Glad to have you follow along.

    • @TropicalMelonMan
      @TropicalMelonMan 7 лет назад

      The series popped up in my suggestion feed, so I feel rather lucky to have discovered it!

    • @iamchets
      @iamchets 5 лет назад

      @@TropicalMelonMan So how did it go for you?

  • @akwright
    @akwright 7 лет назад +28

    I love love love how you constantly refactor as you go. This is such a great series! I look forward to each one 🙂

    • @meth-method
      @meth-method  7 лет назад +8

      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.

    • @SimionChis
      @SimionChis 7 лет назад +1

      I lost you after you made the first refactor, when you have replaced "Hello world" with a canvas but I am still here. ;)

    • @jeffwells641
      @jeffwells641 6 лет назад

      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!

  • @tmate88-j8y
    @tmate88-j8y 2 месяца назад

    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!

    • @tmate88-j8y
      @tmate88-j8y 2 месяца назад

      @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!

  • @SamVsCode
    @SamVsCode 7 лет назад +9

    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

  • @WiBla
    @WiBla 7 лет назад +6

    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!

  • @souzaramon9522
    @souzaramon9522 Год назад

    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!

  • @Wobling
    @Wobling 7 лет назад +3

    Absolutely loving this, especially seeing how you refactor.

  • @Jnxen
    @Jnxen 7 лет назад +1

    Love this serie. As a developer I remember the "DHTML-time" back in the days :D

  • @sebastianluzian459
    @sebastianluzian459 5 лет назад

    by far the best tutorial on canvas and game coding i have ever seen. keep on creating! 10/10!

  • @meth-method
    @meth-method  4 года назад

    Need help? Visit the Discord chat discord.gg/ZAP8wVr

  • @wotomy
    @wotomy 5 лет назад

    This is totally different from other JS tutorial. It gives me a tons of new information. Really really thank you! from Korea

  • @MrHminer
    @MrHminer 7 лет назад +6

    "It's time to do some clean up!"

  • @olelek
    @olelek 7 лет назад

    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.

  • @uyohn
    @uyohn 7 лет назад +16

    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.

    • @meth-method
      @meth-method  7 лет назад +3

      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.

    • @uyohn
      @uyohn 7 лет назад +4

      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.

    • @timoman6
      @timoman6 7 лет назад +3

      Yeah, someone needs to make a crash course for ES6, or at the very least, make a video for transitioning from ES5 to 6

    • @medoxxxxx
      @medoxxxxx 7 лет назад +3

      same here, at first it looked quite easy. But now its overhelming.

    • @oldbootz
      @oldbootz 7 лет назад +1

      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!

  • @ethanbarrieau2417
    @ethanbarrieau2417 7 лет назад

    These videos are great! Glad you're back at it again.

  • @chrizzzly_hh
    @chrizzzly_hh 7 лет назад

    Awesome. Can't wait for the next. Very good tutorial, also the cleaning and moduleising..

  • @escapiststupor
    @escapiststupor 4 года назад

    DA BEST CANVAS TUTORIAL I'VE EVER SEEN ON RUclips!

  • @thatchipmunksings
    @thatchipmunksings 4 года назад

    You should call yourself code janitor. You're the best at cleaning code!

  • @johnjones8330
    @johnjones8330 7 лет назад +6

    Your velocity should be updated in proportion to deltaTime (scaled by gravity / acceleration) just as your position is.

    • @meth-method
      @meth-method  7 лет назад +3

      You are correct. Thanks, I missed this. Will do some house cleaning in the intro of next episode to rectify that.

  • @sjmarel
    @sjmarel 7 лет назад

    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!

    • @meth-method
      @meth-method  7 лет назад

      Yes, everything in the game world will share the same timing.

  • @Pi7on
    @Pi7on 5 лет назад

    This series is so damn comfy

  • @MrTrevolta
    @MrTrevolta 7 лет назад +2

    Отличный канал. Отличное видео.

  • @junka3
    @junka3 7 лет назад

    Yes! new episode! Love it!

  • @arthurkids237
    @arthurkids237 3 года назад

    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.

  • @hackedxd2813
    @hackedxd2813 4 года назад

    Awesome Series!!!!!!!!!!!!

  • @collinvisser7108
    @collinvisser7108 7 лет назад

    Well done thanks for making this. It has helped me so much

  • @jessejburton
    @jessejburton 5 лет назад +1

    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?

    • @andrewlodge241
      @andrewlodge241 4 года назад +1

      Jesse Burton I got the same issue

    • @finnmcnamara9899
      @finnmcnamara9899 4 года назад

      the same

    • @meth-method
      @meth-method  4 года назад +1

      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.

  • @jsonkody
    @jsonkody 7 лет назад

    The Master is back! :)

  • @ggc_5655
    @ggc_5655 5 лет назад +1

    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)

    • @ShaneClaussen
      @ShaneClaussen Год назад

      I have the same question... makes no sense to me (I removed it from my code).

  • @takashikisaku605
    @takashikisaku605 2 года назад

    --- TOC ---
    What is this video 0:05
    To start writing code 1:10
    --- My memo ---
    What is velocity? 1:13
    Weeeeeeeeeee 1:45

  • @yannrolland4193
    @yannrolland4193 7 лет назад

    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 !

    • @meth-method
      @meth-method  7 лет назад

      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.

  • @tetrastrider
    @tetrastrider 2 года назад

    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

  • @shurmaniko7893
    @shurmaniko7893 7 лет назад

    Esperando ansiosamente el siguiente capitulo de la serie, y los demás... Saludos desde España, y gracias por tu trabajo.

  • @lightsam
    @lightsam 4 года назад

    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!?

  • @reginahilt
    @reginahilt 7 лет назад

    Awesome job.

  • @cyri11e
    @cyri11e 7 лет назад

    Brilliant ! Bravo

  • @Mr_cl0wn
    @Mr_cl0wn 7 лет назад +2

    turn on the subtitle option please.

    • @meth-method
      @meth-method  7 лет назад

      Mr. Clown I don't know what this means even. Please specify and I'll do it

    • @Mr_cl0wn
      @Mr_cl0wn 7 лет назад

      Meth Meth Method there is no CC option in this video means no auto English subtitle. Other video were fine.

    • @meth-method
      @meth-method  7 лет назад

      Sorry, I can't find anything on my end to enable that. Maybe it's an auto thing and it dismisses my voice.

    • @benclarke4075
      @benclarke4075 4 года назад

      click the cog button

  • @rhadnum
    @rhadnum 6 лет назад

    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!

    • @kris10an64
      @kris10an64 4 года назад

      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.

  • @blasttrash
    @blasttrash 5 лет назад +4

    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).

  • @dakshgupta7285
    @dakshgupta7285 4 года назад

    I MEAN SMART

  • @cachaconegro6295
    @cachaconegro6295 6 лет назад

    you be best, in the canvas y javascript

  • @Alex-wh6rj
    @Alex-wh6rj 7 лет назад

    Thank you very much. Can you do a match 3 type game please?

  • @tetrastrider
    @tetrastrider 2 года назад

    Timer.update = function update(deltatime) wath the hell is that called

  • @Marionaise
    @Marionaise 7 лет назад

    Is there a reason why you name some .js-Files with an uppercase letter?

    • @meth-method
      @meth-method  7 лет назад +2

      Marionaise yes, when they export one main class as default.

  • @vado4003
    @vado4003 4 года назад

    This video makes me feel like programming is not for me even though I'm already intermediate.

  • @ivantsybulin8328
    @ivantsybulin8328 6 лет назад

    nice) thx a lot ..

  • @amanibenazzouz5480
    @amanibenazzouz5480 6 лет назад

    Thank you for your efforts, great tutorial :)

  • @cyrill7143
    @cyrill7143 7 лет назад

    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 !

    • @meth-method
      @meth-method  7 лет назад +2

      Apotheose Fr to make the code, and stack traces more readable in case of error.

    • @RogRamming
      @RogRamming 7 лет назад

      And i love you for that. So simple -> So helpful

  • @Seedzification
    @Seedzification 7 лет назад +1

    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

    • @Seedzification
      @Seedzification 7 лет назад +2

      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.

    • @oldbootz
      @oldbootz 7 лет назад

      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

  • @solanopalacio8124
    @solanopalacio8124 7 лет назад

    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?

    • @solanopalacio8124
      @solanopalacio8124 7 лет назад +1

      Problem was solved by the author a few seconds after xD.

    • @meth-method
      @meth-method  7 лет назад

      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.

    • @solanopalacio8124
      @solanopalacio8124 7 лет назад

      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 ?

    • @meth-method
      @meth-method  7 лет назад

      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.

    • @solanopalacio8124
      @solanopalacio8124 7 лет назад

      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)

  • @shawnmacburnie381
    @shawnmacburnie381 6 лет назад

    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

  • @dakshgupta7285
    @dakshgupta7285 4 года назад

    I AM SMAT

  • @JasimGamer
    @JasimGamer 5 лет назад

    you doing things not necessary🤔

  • @curated6706
    @curated6706 7 лет назад +3

    At this point, your series lost the brilliance and clarity that first two episodes had. Maybe you should redo these.

    • @oldbootz
      @oldbootz 7 лет назад +4

      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.

    • @blasttrash
      @blasttrash 5 лет назад

      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.

    • @julk2701
      @julk2701 5 лет назад

      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.