the best way to understand oop is with developing projects . keep adding those useful videos
@Frankslaboratory3 жыл бұрын
Hi Sami, yes I agree, I'm trying to make the projects visual and memorable and I'm adding a new technique each time to improve our skills step by step, hope it helps.
@hudy723 жыл бұрын
Thanks Frank! Great tutorial! I was coding with you (although with loads of pauses at my end :) and now i need to watch it again to fully understand what is really going on here. keep up the good work mate!!!
@Frankslaboratory3 жыл бұрын
Hi Irek! Nice to meet you. Congratulations on completing the course!
@Mainman00113 жыл бұрын
I'm lovin this man, nice upgrades on your code setup :)
@Frankslaboratory3 жыл бұрын
Thanks Johnathan, I try to do something new in every video, always learning :)
@granumuse78473 жыл бұрын
You finally did it!!!! Game class and inheritance and polymorphism!!!! You know, you can build Game class only for static properties, so you don't need to instantiate Game for only one canvas and call at the same time all the algorithms you need for update and draw! It can serve the app even million times faster on that way (speaking of microseconds time scale), as no instantiated Game object exists in RAM. On that way, Game class works as a controller ( == a mechanism) for all created objects during runtime. Just a suggestion 😉 Epic work Frank!!!!! Awesome 🆒
@agent-333 жыл бұрын
Do you have tutorials to better understand what you mean?
@Frankslaboratory3 жыл бұрын
Hi, thank you for suggesting improvements, if you have an example of how you would structure the code let me know. Since you say game would handle static properties only, I guess we would need another handle function for drawing and updating the game. In the current code structure you can pass as many different canvases as arguments, I can have enemy canvas, player canvas etc and update them only when necessary. I'm still learning about some of these optimisation techniques so I appreciate your comment, thank you
@agustinlavalla88923 жыл бұрын
This is pure gold. Thanks so much. Appreciate your contribution
@Frankslaboratory3 жыл бұрын
Hi Augustin, I'm here to help, will be using techniques from this video for the next upcoming full game projec
@goffyfoot823 жыл бұрын
Hello I have one question, You have left the DOMContentLoaded eventListener in your code and mentioned for us to remove it and switch it to only load.(6:52) If I do that I fail to receive the console.log(); message in the console. I though something was screwy after I replaced the cut code back in. I have double checked it and even added a console.log(canvas.width) directly below the animate() call. My console has nothing, BUT as soon as I add BACK the DOMContentLoaded. I now see the error message lastTime is not defined, and adding it to the code. I see the canvas.width value flash and the deltaTime loop starts. It make life confusing for those of use who are still green to this. Great de-bug lesson but I can see it frustrating some others down the road. I heard your explanations why to use load, but using it here I get no console message or deltaTime loop? See how it can confuse a beginner to JavaScript??
@Frankslaboratory3 жыл бұрын
Hi Will, I can see you messaged me on Twitter as well, I will respond there
@Guztawh3 жыл бұрын
@@Frankslaboratory I have the same problem
@nicorithner7862 жыл бұрын
same problem
@fonysony40512 жыл бұрын
@@nicorithner786 Attempt with window.addEventListener('load') instead, due to document apparently being unreliable.
@bevouliindesign77773 жыл бұрын
This is so awesome!! Great tutorial video!
@Frankslaboratory3 жыл бұрын
Hi, your art made it much better, thank you :)
@Radu3 жыл бұрын
Really funny intro 😃 And a nice application of inheritance. It was fun to watch. One comment though... Sorting the enemies like that, from top to down, only really makes sense if the game gives a sense of perspective. Yours does not because all enemies are the same size. I get where you're going with this, though.
@Frankslaboratory3 жыл бұрын
I learn that sort trick from you :D yes you are right, ideally enemies that are behind should be smaller, if you play 2d games like plants vs zombies, they do layering like this but everything is the same size, it 's a very flat looking '3D' effect ha. Next time I will tweak the size.
@Radu3 жыл бұрын
@@Frankslaboratory Yes, but then sorting in the opposite order is also fine. Sorting in the opposite order is also fine with 3D perspective if your worms walk on the ceiling, for example. I think you can play around with that in the future (floor creatures sorted / sized one way, and ceiling creatures in the opposite way).
@Frankslaboratory3 жыл бұрын
@@Radu Now you are giving me ideas for future videos, I will do it :D
@Radu3 жыл бұрын
@@Frankslaboratory Can't wait to see it :-)
@JUNGELMAN2012 Жыл бұрын
at 6:48 window.addEventListener('load', function (){} does work, but not the document.addEventListener version. Because then you are waiting in a loop. Thus waiting for the eventlistener to load too. The cleanest version I know is "onload = () => {}"
@samehzaky3 жыл бұрын
Hi Franks, really you are my hero, I wrote with you line by line, really you taught me a lot. I have small comments may be I am wrong 1-document.addEventListener('load') doesn't work it should be window not document. 2-I think it will be good not to use game class, then instantiate an object from it, and use an object directly, I tried it and it worked just like you class game={ deltaTime : 0, constructor:function(ctx,width,height){ this.ctx = ctx; this.width=width; this.height = height; this.enemies = []; this.enemyInterval = 500; this.enemyTimer = 0; this.enemyTypes = ['worm','ghost','spider']; }, update:function(){ if(this.enemyTimer> this.enemyInterval){ this.addNewEnemy(); this.enemyTimer = 0; this.enemies = this.enemies.filter(object => !object.markedForDeletion); }else{ this.enemyTimer += this.deltaTime; } this.enemies.forEach(object => object.update()); }, draw:function(){ this.enemies.forEach(object => object.draw()); }, addNewEnemy:function(){ const randomEnemy = this.enemyTypes[Math.floor(Math.random() * this.enemyTypes.length)]; if (randomEnemy == 'worm') this.enemies.push(new Worm(this)); else if (randomEnemy == 'ghost') this.enemies.push(new Ghost(this)); else if (randomEnemy == 'spider') this.enemies.push(new Spider(this)); /*this.enemies.sort(function(a,b){ return a.y-b.y; })*/ } } thank you very much for your experience and time
@Frankslaboratory3 жыл бұрын
Hi Alex, you are right load event should be on window object. Creating class vs creating object is just a creative choice I guess, both will work the same, I usually create class even for objects that will have one instance (player object) just so that my code is uniform. Declaring object directly will save you 1 line of code, feel free to choose whatever you prefer.
@samehzaky3 жыл бұрын
@@Frankslaboratory thank you for your prompt reply, so I mean that it good to use object just in the game, but sure we have to use classes after that with worm 🐛 and spider 🕷️ as you mentioned in the video. Again all best wishes
@WyzrdCat2 жыл бұрын
Really enjoying your videos lately! I notice you do everything with vanilla -- is that the way you like it? Or are frameworks like Phaser worth considering after you understand the fundamentals?
@philippedevezeaud50293 жыл бұрын
Thanks for the feedback, I will review each part. Anyway, thanks for sharing. See you soon.
@Frankslaboratory3 жыл бұрын
Happy to help Philippe
@karlkoch334511 ай бұрын
Another great one! These videos are great!
@Frankslaboratory11 ай бұрын
Thanks Karl
@cofuncio12 жыл бұрын
Awesome tutorial as always. You are an amazing teacher, thanks for sharing your vast knowledge!
@Frankslaboratory2 жыл бұрын
Hi Alberto, glad you found it useful, I'm here to help :)
@andriimanoilov75132 жыл бұрын
Hi, good tutorial! I want mention that we can simplify the creation of different enemies by prefilling the array with references to the corresponding classes. It will looks like this: class Game { constructor(...) { ... *this.enemyClasses = [Ghost, Worm, Spider];* this._addNewEnemy(); } ... _addNewEnemy() { const randomEnemyIndex = Math.random() * this.enemyClasses.length | 0; *const RandomEnemyClass = this.enemyClasses[randomEnemyIndex];* this.enemies.push(new RandomEnemyClass(this)); } }
@AK243RDC3 жыл бұрын
Thank you very much for clarifying the inheritance concept!
@Frankslaboratory3 жыл бұрын
Hi Tshitolo. The same technique can also be used for particle systems. Will make a video on that soon
@AK243RDC3 жыл бұрын
@@Frankslaboratory THANK YOU! I'll be waiting for it . I am trying to set up a Javascript course for kids in a community center and your videos inspired me a lot. they offer very simple but efficient ways through game to teach programming to children . Thanks again
@Frankslaboratory3 жыл бұрын
@@AK243RDC Nice, good luck with your project Tshitolo, I can see how kids could find visual/game coding projects interesting. Let me know how it goes
@iracimariadelira61893 жыл бұрын
I'm from Brazil, I love your content
@Frankslaboratory3 жыл бұрын
Hi Iraci. Thank you. Greetings to Brazil
@eslarchive67642 жыл бұрын
I started coding games to learn about classes and canvas in depth and your videos saved me thanks a lot. I want to ask could I use Map instead of Array in this tutorial? I also wanted to kindly ask you to do tutorials where you use non array objects which hold values as well. thanks again
@emanuelkokovics3 жыл бұрын
10:00, deltaTime shouldn't be a let variable, since it is changing or var? For some reason none of the times console log for me, if I use 'load' instead of "DOMContentLoaded"! I am using VScode live server. 35:00 It is so bizarre, when I use the deltaTime in the formula this.x, to make worms move to the left, worms are created, i see in console, but they do not show on the screen; if i leave the old formula they appear on the canvas. It doesn't seems to make a difference what I put in this.vx = Math.random() * 0.1 + 0.1;, big/small numbers, nothing appears on the screen. Is anyone else having this problem with random speed? I did other projects using random movements and never had this; well I will just decrement x by one (leave it as before random speed), for now! I hope to find the issue! OK! FOUND THE PROBLEM, my deltaTime is UNDEFINED, the one from ENEMY class! Makes sense now!
@Frankslaboratory3 жыл бұрын
Hi Emanuel, deltaTime can be const, because let and const are block scoped, it means they only exist within the nearest set of curly brackets. You think i'm reasigning the same const variable but what is really happening is i'm creating new delta time variables, and I can do that since each loop is different block, different scope, they don't see each other. Scopes are complex, I need to explain it better next time. Also glad you fixed the bug, debugging can be frustrating but it gets easier
@YoctoGamer2 жыл бұрын
Hi, excellent videos and tutorials! One question, the document.addEventListener('load', function is not working for me, it's like the event never happens. Using DOMContentLoad works fine. I found online that I could also use window.addEventListener and with window it works fine. Any idea why this happens? Thanks!
@Billy_983 жыл бұрын
Maan,amazing work! Thank you so much!
@Frankslaboratory3 жыл бұрын
Glad you like it Ken !
@christobongende8932 жыл бұрын
I love your videos, they are great! thanks to you!
@imluctor59973 жыл бұрын
Great video! Learned a lot of new things
@Frankslaboratory3 жыл бұрын
Hi Luctor, thank you, glad you found the course useful, keep learning
@gaurav561crazy53 жыл бұрын
Lovely monsters😱😱 I will check
@Frankslaboratory3 жыл бұрын
Halloween is coming, best time to talk about monsters haha
@cgh20xx3 жыл бұрын
This video is awesome, it's very useful to me, thank you!
@Frankslaboratory3 жыл бұрын
Glad you found some value Hank
@jaikanojia41683 жыл бұрын
How you protect you browser based js games ? People can see and copy js very easily
@iconicworld88803 жыл бұрын
I always wait for your videos
@Frankslaboratory3 жыл бұрын
Thanks for waiting :)
@Adrian00213 Жыл бұрын
This is great tutorial. Im following along. i was wondering. the z index. is it possible to set the Z index to Y value in canvas? since each element is in certain x,y position. all we need to do is set Z index to Y once we instantiate enemy object.. this way we should get more or less the correct look and cheaper then sorting array when creating object.. I'm new to this so not sure. :)
@Frankslaboratory Жыл бұрын
Hi Adrian, this is a 2D plane, z index in CSS is just a helper property, behind the scenes CSS has to sort draw order for you as well, there is no Z axis. With canvas we often have to do manually what CSS does for you automatically behind the scenes. In CSS, a lot of these calculations and algorithms have been extracted into simple keywords and properties, but the same work has to be done behind the scenes, if you know what I mean.
@WEBSTART-LIVE3 жыл бұрын
Супер !
@soniamaklouf11783 жыл бұрын
Hi Frank I'm new to programmation and I wonder if I can put addeventlistener in the constructor if I want my spider to be clickable ?
@Frankslaboratory3 жыл бұрын
Hi Sonia, addEventListener can be added to a html element, spiders are canvas drawings, to make spiders clickable is relatively easy, you would do it by creating a class method that checks collision between mouse and each spider.
@sagar-tt4ub3 жыл бұрын
Another great one
@Frankslaboratory3 жыл бұрын
Thank you Sagar ❤
@gibstock76233 жыл бұрын
I've been loving all of your videos, thank you! What do you do when you're done designing a game? Is there a way to get them on to the play store or are they strictly best for web playing? I'm most comfortable with js and it would be cool if there was a way to make them apps. Unless it's just best to learn another one of the gaming languages.
@Frankslaboratory3 жыл бұрын
Hi, JavaScript games like this can be played in a web browser or you can use React Native to convert them into a native Android and iOS apps. I haven't learned React Native yet so I don't have much experience to share on that topic. Also my games are just a collection of common programming principles, every language has functions and for loops so it would be easy to convert them to a different programming language that supports native apps.
@philippedevezeaud50293 жыл бұрын
hello francks,I understood the idea of requestAnimation... but there is one thing he doesn't like: let lastTime = 1; function animate(timeStamp){ ctx.clearRect(0, 0, canvas.width, canvas.height); const deltaTime = timeStamp - lastTime; lastTime = timeStamp; console.log(deltaTime); requestAnimationFrame(animate); }; animate(); }); the console.log(returns absolutely nothing, I don't even have an error message) I'm having a hard time seeing the error in the code, it all seems logical in its construction If you have an idea of research axis ! Thanks
@Frankslaboratory3 жыл бұрын
Hi Phillippe, just do the usual console log routine to see where the problem is, console log other things from inside animate, just to check if it's running at all, even just a text that says 'aaa'. If it doesn't run then problem is outside, I can see too many brackets, I assume that's from load event listener. Just put console log in each level and you will find the problem. Debugging is important skill to have, takes a while to learn how to do it fast.
@h989l2 жыл бұрын
when i am calling animate() 2 times,why request animation frame serving frame faster than before?
@Frankslaboratory2 жыл бұрын
Request animation frame can be called many times independently. If you have two separate loops you are calling request animation frame more often. I'm not exactly sure what you mean though. Why do you call animate two times?
@piersonlippard29113 жыл бұрын
Hey there Frank, thanks for another fantastic tutorial
@Frankslaboratory3 жыл бұрын
Pierson! Thank you ❤
@ra1games793 жыл бұрын
Super cool video ! :)
@Frankslaboratory3 жыл бұрын
Thank you
@학생1-r5o3 жыл бұрын
Thank you for the great video!! Can I just follow the "Game Development with Vanilla JavaScript" playlist in order? I'm the very beginner of game programming
@Frankslaboratory3 жыл бұрын
Hi, I just restructured my Game Development playlist based on difficulty. Each video is a standalone project so it's possible to jump around, but now it's sorted from easiest to more complex projects. If you still find these videos too advanced you should consider doing a well structured complete beginner JavaScript course and then come back to project tutorials, it will make your learning process faster from my experience. have fun :)
@carltone3 жыл бұрын
Frank The scary part of this video is, I’m starting to really understand JS. I’ve employed a screenshot tool to capture snapshots of the code and print it off. With your explanations still in my mind I can pencil in some comments for further review. Plus messing with some codepen snippets . Works for me. I always read the comments in instructional videos for those little eureka comments like Mike’s regarding the global nature of ID’s. Like you I was taken by surprise when he added his comment. I thought the way you acknowledged his tip and incorporated into your code was awesome. as well as the other suggestion on the ghost transparency. Being a microcontroller guy, memory is a precious resource so if hosting a webpage on a small controller you are acutely aware of how fat JS and associated code really are. The ability to assume association of an id without making a 25byte call is a big deal! Thanks for pointing out the purpose and use of super, ! and #. Of course the overall thank-you for creating your polished video format ,sharing your knowledge and expertise is implied!
@Frankslaboratory3 жыл бұрын
Hi Carl, I used to have a notepad with stickers and I was writing important code blocks in it just to remember them better, glad you found a good way to organise the things you learn. I try to make people feel like their comments have impact so if I remember useful tip while recording, I will use it and credit the person. I hope it will encourage people sharing their tips with me, as I'm a student as well. Thank you for your kind feedback Carl, it sounds like you are a very motivated and goal driven person, I wish you a lot of success.
@arturneufeld15163 жыл бұрын
mh quick question: If each enemy class has acces to the game variable and the game variable holds all enemies, does this not lead to an infinite dependency loop? I could inspect the Game object > Enemies > Enemy0 > Game > Enemies > Enemy0 and so on. Is this something to worry about or does it not matter?
@Frankslaboratory3 жыл бұрын
Hi Artur, nice to meet you, this is a good question, I didn't think of that. This questions goes a bit deep and maybe someone else could answer better, but as far as I understand it this is not something to be concerned about, since it looks like we are creating infinite layers of objects, but it actually points to one slot in memory. If I learn more about this I will update this comment
@arturneufeld15163 жыл бұрын
@@Frankslaboratory thanks for the response, let me know if you find more about this in the future, I am really curious, because I encountered this as well in one of my projects, and I was concerned that doing it this way is a bad practice. The idea with the same slot in memory makes sense though - but confirmation would be great. thanks for your videos btw!
@Frankslaboratory3 жыл бұрын
@@arturneufeld1516 It's good to raise questions like this, I will research it, well done on noticing this btw, you have great attention to detail, prime quality for programmers
@TheSpr0gz3 жыл бұрын
It doesn't matter. Yes, if you wrote a loop to inspect Game object > Enemies > Enemy0 > Game > Enemies > Enemy0 and so on then you would of course loop infinitely but that situation should not arise unless you deliberately choose to do it; why would you?! lol Resource-wise it's not an issue. The array of enemies in Game will simply contain a memory reference to each Enemy instance and each enemy instance would have a property with the memory location reference back to the (single/same) Game instance. There's no recursion because they're of course not copies; Game isn't copied within each Enemy, only a reference to the Game instance. Think of it like your mobile phone and a friend's mobile phone. You have their number (not their actual phone 😂) stored in your phone and they have your number (not your actual phone 😂) stored in their phone. No problem. They can call you. You can call them. Same situation with Game referencing an Enemy instance and that Enemy instance referencing the Game instance.
@milaloup2 жыл бұрын
can anyone explain why deltatime for me is 16 in firefox and 33 in chrome (both vanilla).
@Frankslaboratory2 жыл бұрын
Hi Mila, that's interesting. Probably it's down to implementation some of the canvas API methods we are using in particular browser. Never noticed this before but in theory differences like this are possible.
@milaloup2 жыл бұрын
@@Frankslaboratory Ah, thanks for the answer! I just retested it and now - I did some updates to my computer and browsers meanwhile - firefox is still at 16 and chrome changed to 13. well … :)
@soussousalahiddine59333 жыл бұрын
I love your content 💖
@Frankslaboratory3 жыл бұрын
Thanks Soussou ❤💪
@manparido4 ай бұрын
That was great, super easy (parent easy)
@Frankslaboratory3 ай бұрын
Glad to hear
@АнгелинаПАПА-в3э3 жыл бұрын
What IDE do you use?
@Frankslaboratory3 жыл бұрын
Hi Ангелина, I use VS code editor, with Live server plugin
@mattmovesmountains14433 жыл бұрын
Another great one.. lots of concepts implemented so well for teaching purposes. Plus my daughter is going to enjoy the Halloween theme. Any suggestions for smoothing out deltaTime on my raspberry pi, which mostly returns 16ms, but randomly throws in 33ms?
@Frankslaboratory3 жыл бұрын
Hi Matt. Halloween is my favourite time of year haha. I dont think there's an issue with irregular delta time. It will still reach target interval in specified amount of milliseconds. Do you see any performance lags? Shouldn't be caused by deltatime unless your system is really struggling with the code
@mattmovesmountains14433 жыл бұрын
@@Frankslaboratory same! Big October and Halloween fan. Yeah there were some quirks with the spider movements when using deltaTime - they'd get stuck at the bottom, whereas a hard-coded 16ms was fine, but I'm not too worried, understanding the pi can be quirky with that stuff. I at least understood the main concepts which is my goal. Also the graphic illustrations you sometimes use are super helpful.. like showing how you index the animation frames
@Frankslaboratory3 жыл бұрын
@@mattmovesmountains1443 Oh, I see, looks like you discovered bug in my code. I can see it now. Irregular delta time should be handled on the line where I revert spider speed to a negative number. If delta time is high enough and it moves more than one step further, the reset check will lock it in endless loop. Thanks for bringing it to my attention. will fix for the final game tutorial. Glad to hear the visuals help. I try to do more of them these days, need to learn Adobe after effects when I have time so I can do them properly :D
@mattmovesmountains14433 жыл бұрын
@@Frankslaboratory fitting, I suppose, that the spider caught the bug in the code
@Frankslaboratory3 жыл бұрын
@@mattmovesmountains1443 ahahaha, well said Matt :D
@gamerpotato66673 жыл бұрын
very attracting opening to bring 'extends' and 'super' to live
@Frankslaboratory3 жыл бұрын
I try to make coding more fun :)
@ApexGaara3 жыл бұрын
Can you make a Video about Javascript Canvas Game development and how to make your game responsive so that you can play it on any device(mobile, tablet, desktop)
@Frankslaboratory3 жыл бұрын
Hi, I am working on some mobile specific game tutorials yes
@iconicworld88803 жыл бұрын
So thanks for the video
@Frankslaboratory3 жыл бұрын
Happy to help, hope you find some value
@Vann_immortal2 жыл бұрын
Bro bagaimana caranya agar codingan game dijadikan aplikasi?
@bunveasna293 жыл бұрын
Thank you so much for tip 😍🤩😘🥰
@Frankslaboratory3 жыл бұрын
I'm here to help :)
@noormohammadsiddiqui77373 жыл бұрын
Thanks for the video sir ❤️
@Frankslaboratory3 жыл бұрын
Hi Mohammad, I'm here to help 😅❤
@marufhasan213 жыл бұрын
💚💚💚
@Frankslaboratory3 жыл бұрын
Hi Maruf
@marufhasan213 жыл бұрын
Hi @@Frankslaboratory. I was waiting for this tutorial from i have created the walk,running...Dog from your spritesheet.
@marufhasan213 жыл бұрын
@@Frankslaboratory thanks
@unknown-bx8my3 жыл бұрын
👍👍👍👍👍
@Frankslaboratory3 жыл бұрын
❤💪
@_GOUTHAM3 жыл бұрын
Frank can you make a video on sorting visualizer just like your canvas projects
@Frankslaboratory3 жыл бұрын
Hi, sorting visualizer? Hmm, interesting, yes that could be a fun project, I will add it on my list, thank you for another great suggestion
@_GOUTHAM3 жыл бұрын
@@Frankslaboratory it would be better for begginners like me to learn data structures through visualization in canvas i hope i soon see sorting visualizer in your play list
@hfe18333 жыл бұрын
Nice
@Frankslaboratory3 жыл бұрын
🙏
@Frankslaboratory3 жыл бұрын
Sorry if you're scared of spiders but... Happy Halloween :D :D
@mra26043 жыл бұрын
hey please bit me i want to be franks spiderman :D
@mra26043 жыл бұрын
great work !!!
@Frankslaboratory3 жыл бұрын
@@mra2604 Thank you
@Frankslaboratory3 жыл бұрын
@@mra2604 Hahaha, LOL
@gamerpotato66673 жыл бұрын
lol
@OchirBFolo3 жыл бұрын
Welcome back after a month 😅
@Frankslaboratory3 жыл бұрын
It's been a while :D I had to return to the office, no more working from home so need to come up with a new routine to make videos
@CodeAProgram3 жыл бұрын
:} 👍
@Vann_immortal2 жыл бұрын
Bro bagaimana caranya agar codingan game dijadikan aplikasi?