This tutorial is the first in a short list of digestible content to show developers how to code a game with just Canvas, step-by-step. I remember a few years ago trying to find something like this on RUclips, and there was none to be found. So thank you for being a pioneer
Thank you for the amazing tutorial and code along experience! If someone wants to have the shrink animation without importing an external library, it is pretty easy: 1. You define a property "targetRadius" in your enemy's constructor 2. In the update method of Enemy, you check if targetRadius is bigger than radius and if so you shrink it by a constant value (for example: shrinkSpeed = 0.8) and you pay attention that if the substraction gets you a smaller radius than targetRadius, you set it with radius: if (this.targetRadius < this.radius) { this.radius = this.radius - this.shrinkSpeed < this.targetRadius ? this.targetRadius : this.radius - this.shrinkSpeed; } 3. In your game loop, instead of of using the library you just substract the value to enemy.targetRadius
If anyone is curious about what happend at 38:07. It's good to realize the difference between requestAnimationFrame and setInterval If you go to another tab your game pauses, because requestAnimationFrame only works if tab is active . setInterval is active regardless if you have the tab open or not. So it's gonna keep push enemies into the array of enemies every second. And that's why at 38:07 the screen was full of enemies. How you could avoid this: Your animate() function is called already as quick as possible by requestAnimationFrame(). Make a global variable called frames = 0. In animate() just do frames++ to count up the frames In spawnEnemies you just have to do some easy math to see when a second passed. Usally browsers run at 60FPS. so each 60 frames = 1 sec. If (frames % 60 === 0) { spawnEnemies() }
@@modernmage aCKSHUALLY 🤓☝ it's just a highly abstract representation of the electrons that do and don't flow through the circuits in your computer, not pURE gOLD 🙄🙄
That's a long one, just watched the intro, will save it for the weekend and code along. Thank you for sharing this Chris, I know it's a lot of hard work to produce content like this.
There's a lot of work in this video. From lighting, to cameras, to editing. I'm not even a 'programmer', but I'm interested in 'twine' with some javascript. (As well as streaming.) So, I'm actually as impressed more than you because he also has explanation style that's incredible.
как интересно, я постоянно встречаю ваши комментарии под самыми разными видео. Видимо мы интересуемся одним и тем же))) + + + how interesting, I constantly meet your comments under a variety of videos. Apparently we're interested in the same thing)))
Great Job!!! Chris I am a retired programmer and spent several years in the training department (25yrs ago!). I can honestly say you do a better job then I did. I think everyone would appreciate more advanced JS GRAPHICS. I don't do much coding any more but still try to stay up to date watching good tutorials - I wish you had more :)
Great tutorial. I have 3 retro games I wrote in C# and this give me the information I need to migrate to run in a browser. Couple of suggestions: 1) store the ID of the spawn setInterval and call clearInterval(id) when detect game over or multiple instances of the interval will run and more and more enemies will be created per second on each restart of the game. 2) Move setting the canvas.width and height and player x and y inside the init() function to adapt to changes in browser window size when restart game. Many thanks for the tutorial.
This was not only a very good Game Tutorial, it was also an excellent programming tutorial in general. Thank you for your time and dedication. I really appreciate it.
First off, thank you Chris for such a wonderful series of tutorials, they are all magnificent. Now, addressing a little issue. After you restart the game, the "spawnEnemies" interval remains set, therefore, executing it again will add an extra "spawner" each time, incrementing each time the amount of enemies per period. The possible fixes for this are simple: One would be to simply execute "spawnEnemies()" once and only once, outside of any recurrent block. Another solution takes into account that "window.setInterval()" returns an Id, which we can save in a variable at the top, say for example, "let spawnerId". Once we hit a game over, inside of the startGameBtn's event listener, we clear this old interval via "window.clearInterval(spawnerId)", and then we add the new one. Hope this helps anyone who falls into the same issue. Again, a most humble thank you for your efforts which are tremendously appreciated!
I started making canvas experiences in 2010, and I've seen many videos/tutorials since. This video is one of the best tuts I've seen out there. Your code is very clean, and in my opinion, your commentary is also very good and joyful to listen to. Keep up the great work.
I love the way you omit the html, head and body tags. I consider myself an intermediate front-end hobbyist and I completely missed that part of html5 until now. Mind blown.
I signed up for your newsletter. I am really impressed by your high quality course approach. I am looking forward to buying the rest of the course when it's ready. Thank you for your effort.
Thanks for watching 😉 Haven't had much time to keep everyone updated on the newsletter or produce the rest of the course yet, but it'll all be 100% ready by Oct. 31. Really appreciate your support and can't wait to help ya out some more.
You leave a lot to the automatic sorting of the browser, like just using the tag without putting it in the head, and not using semicolons in js. You are the first tutor to do this and I hear all the time how it's bad practice. But I respect that you have your own style and thank you for the very elaborate step-by-step.
such an amazing tutorial man! I coded along and did it, I'm teaching myself coding so it was a bit rough but was able to manage. the one thing Id appreciate it if you can make a video teaching us how to package the final product so we can share it with friends. thanks a lot.
Finally! After years of waiting! Thank you so much! I have learned the HTML canvas from you sir! And earned money using the things that you have taught. Thank you so much! Your canvas tutorials are great! I'm waiting for the tutorial of Collision Detections for other shape.
Good call on the setTimeout workaround for the missing array element in the loop! I usually solve this by looping through arrays in reverse-but I like this a lot because you can use forEach 🤙
As Ive progressed in my code learning, my thought is that this video should be shown to any new coder as required material. It introduces and explains with direct results key concepts not only for JavaScript, but all object oriented coding. As a new coder, being able to see direct results not only instills understanding but also confidence. This video is better than all of the tutorials Ive ever taken on JavaScript. 100% pure gold.
Wow, awesome comment... really appreciate this one. I too agree beginners should take this, wish I had it when I was first learning game dev! Anyways, thanks again, nice comments like this always make me feel great 😄
Very cool. I am a Brazillian VBA programmer who has just started teaching how to use OpenGL library graphics with VBA and I'd like to convert this code to VBA with your permission
This video is amazing. Always thought html canvas and js arent good enough for building games. Obviously i was wrong and just didnt know any better. Having tutorials like this available to everyone for free really makes me happy. Thank you again for sharing your skills, lessons and wisdom.
This is so amazing Chris. Seriously, you just saved me from stressing about my college assignment. I'm extracting these concepts into my MVC architecture-based app. Thank you very much!! :))
Very good tutorial, the learning material, the video, the sound, the explanation, everything is good. I know this tutorial could be more shorter but he does a lot of things in a purpose, and to make us understand every single of function or code. Great job. Very recommended 👊
I've just gone through a bunch of your youtube tutorials - absolutely hooked. You've got real talent as a teacher - signing up to your courses for more ^_^
Great to hear! I did that collision detection video with about 5 hours of work, so hoping I can just keep my head down and get stuff out more consistently. Need to stop trying to perfect everything and just go with what I'm quick at. Appreciate all the support and will be comin to support you in return with more vids 🙌
I added a few things to mine. Every 10 "kills", you go up one level. This makes enemies spawn faster and move quicker You start with 3 lives, and they go down each time you're hit. If you run out of lives, its game over Every 3 levels, you gain 1 extra life, up to a maximum of 5 lives at any one time And then just some visual things like the player flashing red when hit and things of that nature
@@sebastianrechtman3749 Its been a while at this point so I don't 100% remember, but I think I made an Enemy Speed variable and multiplied that on the x and y angles when an enemy is spawned. Then over time that variable increases so the enemies get faster
I was finding a tutorial to create a simple game with javascript, but look, what I found! A simple but professional looking amazing game with step by step explanation. Thanks
You are an amazing teacher. earning from you did not feel like learning at all and I had fun every minute! Thanks a bunch, may you and your generations remain blessed
Wow, I cannot thank you enough for 33:00 - 36:00, I have been building a similar game for a class project, and I couldn't for the life of me nail down the angle ratio! Also to answer your comment about why atan2 uses y over x is because it produces a slope m which equals rise over run or, (y0 - y1) / (x0 - x1), at least that is my understanding. Thanks again, great video!
This tutorial was by far the best I have seen, I loved the game and it was super simple. The camera and the lighting shows me how your course would be. IDK why people give credits to big entities when it is people like you who make true content. I wish I could enroll for the course but my family is not in the state buying the entire course, my sister and father had COVID-19 since 2020 and haven't recovered. I would be grateful if I could learn to make world class games from you. Anyways I LOVED your course and when I shared it with my friends on insta, They absolutely loved it. Lots of
Thank you Merlina, comments like this really motivate me to keep going. No matter what, I’ll always be producing a good chunk of tutorials for free, so don’t even worry about purchasing anything from me, my main purpose is to help people grow, not make money. Your support is awesome (saw your comment on the water bottle vid too), and I’m very happy to have you as a subscriber. Thanks for watching, thanks for sharing, and can’t wait to get you more videos in the future.
Chris, this the best beginner course I've come across for HTML5 Canvas game development. For me, what makes it so accessible is the easy peasy approach to Pythagoras' theorem and the setting of the velocity objects properties. Just as an aside, obviously you'll be aware that the code you've produced has a lot of duplicate functionality among you game pieces and that a single game piece class could be created from which all the others extend and specialize from. I was thrown by your introduction that this would be vanilla javascript and then you introduced a third party graphics engine for shrinking the enemies. Couldn't you have coded this yourself? But all in all this was top drawer, thanks again Chris.
Yeah man, I considered adding inheritance and imports to reduce the amount of code in the main file, but decided not to since it usually adds another layer of complexity and abstraction that makes things hard to change once your game gets bigger and bigger. I’m actually a programmer who leans more towards duplication than trying to abstract things consistently since it does have potential to affect so many parts of your game, app, whatever code you’re working on. Figured it would be easier for beginners too rather than have to delve into more strict OOP techniques. GSAP library not being vanilla makes sense though, I just hate animating with anything else hah. Really glad you enjoyed everything though, tried my hardest to make this one of the best 🥳
@@ChrisCourses Fair do's Chris. I've got a degree in computing and many of my fellow students really struggled with OOP although I had taught myself OOP before I went to university and found it a breeze. The caveat with inheritance is to try to avoid fragile base classes WHICH WILL break your code base. But used judicially and correctly it'll reduce code. I've been experimenting with HTML5 Canvas animation for the last few months and much prefer to build my own transition and transform modules but hey that's me. Cheers for your reply and I've subscribed and look forward to more animation content from you. Well done mate.
Holy shit.. that's simply the best tutorial I've ever seen in my entire life. I haven't even done any GUI before and after watching this playlist, I've made a game in few days. Thank you so much man!!
Really nice one - thanks. Just one remark: 1:47:41 spawnEnemies() should be called once (outside of the listener). Otherwise you will create always an additional interval by calling setInterval() --> enemies increase by each restart of the game.
Great tutorial! Just want to point out, modifying an array during iteration is a bad practice. What you do with setTimeout works, but a better approach would be to do array.slice().forEach(). slice() will create a copy of your original array, and fill-it with your original objects (e.g. projectiles). This means that when you remove a projectile (or enemy) with splice(), it will modify the original array, but not the copy you are iterating over. P.S. The "P" make all the difference - slice() vs splice().
That was a great suggestion, thank you. My projectiles were disappearing as soon as the 1st projectile went off the screen so my original array was being deleted and the rest of the projectiles would disappear before leaving the screen.
Thanks for the tutorial! Here is how I fix the bug where enemies keep spawning after game ends: - pullout the unamed function inside spawnEnemies, make that spawnEnemies instead - let spawnEnemiesInterval (global scope) - inside start button event listener funtion, spawnEnemiesInterval = setInterval(spawnEnemies, 1000) - inside game end condition, above cancelAnimationFrame, add: clearInterval(spawnEnemiesInterval)
Hi thank you for your explanation, I have tried what did you said but it did not work for me, If you don't mind, can you share with me the code to prevent enemies from spawning in the background
BUG ALERT! I think anyone who watched the video could spot the bug where when the game is stopped, the enemies KEEP SPAWNING so when you start again you just get a ton of enemies coming your way... Took me about half an hour to figure out i had to use clearInterval() inside the spawnEnemies function. And while we're at it, the window's event listener should be removed when the game is over and re-added when the game restarts so you wont be able to shoot projectiles when the modal is open. Hopes this helps someone ;)
Yeah i can help you! Firstly, in order for clearInterval to work, you need to give it an actual function reference (not an anonymous arrow function). I extracted the nameless function he used in the video - spawnEnemies, and made it into its own function and called it spawnEnemiesFunction. Then, i used const spawnEnemiesInterval = setInterval(spawnEnemiesFunction, 1000) to actually spawn enemies each second. Now, when the game ends (the player loses), i call my endGame() function, which is responsible for the cleanup. inside it, i use clearInterval(spawnEnemiesInterval), and i also remove the event listener from the window object via removeEventListener method. really hope this helps :) feel free to ask any more questions!
This is a common mistake for people making games in HTML5 That is why "requestAnimationFrame" is always better than "setInterval" or "setTimeout" to create game loops because it is only called when the window is active. Also, All events run in parallel to the base JS code, It's like they were different applications running at the same time as everything else, so you must be careful how you use them, else you might get into an unwanted state, and get errors or bugs from there.
Awesome tutorial. It's really a fully fledged-out game! For those that do not want to use any external library like me: You can go to tailwindcss' page and search for the class that Chris uses to see what's the equivalent in plain css. E.g. "items-center" is "align-items: center"
Anytime, glad it was helpful! There's a continuation over on chriscourses.com if you need it-also have a side scroller course on the way to satisfy any desires there 🙌
If you're having problems or perhaps using messed up equipment like me, you could just create a Player object instead of using class though using class makes it much easier
Thank you very much for the great video! I learned HTML, CSS and even javascript functions! I made my version of the game where you can move by the X axis. I used it for my project for school and my teacher was AMAZED! Thank you so so much for the great explanation! I also found the geometry in this video very useful and helpful!
1 final touch: add a spawnIntervalId for the setInterval and use clearInterval(spawnIntervalId) near cancelAnimationFrame to prevent spawning after the game ends.
Nice little tutorial, well paced instructions...i found when it came to looping over the enemies and then the projectiles the code was glitchy...sometimes projectiles would pass trough and enemies wouldnt remove properly....it simply replaced with a generic for loop for both and spliced within there and that fixed it...like the other users have said its generally not good practice to remove from an array while looping over it. Well done though, very good and reminds us how quickly JS/Canvas games can be pulled together.
Oh, I was slowly coming to the conclusion that you're gone for next 5 months and it was just messed up hard drive :D Anyway, looking forward to watch the tutorial, beacause I didn't see many canvas game tutorials on RUclips. I tried to make some, but it wasn't really good. Hope this will help. Keep up the great work!
I was legit so bummed when the hard drive got corrupted - so much work down the drain. Definitely a mood killer, but decided to get back at it eventually lol
i recommend using pythagoras' theorem to normalize the xy vectors instead because we can calculate the hypotenuse if we have the opposite and adjacent sides (and disregard the angle at which it is shot entirely unless we need it) using atan2 and then sin/cos to get a vector of magnitude=1 is slightly more tedious and likely more resource intensive than the other approach
for every ball shaped things (e.g. player/ projectile), we can use a Ball class with params and the draw function. then for example if we want to do the player, we can use class Player extends Ball to have the params (x,y,color...) and the draw function.
I made something like this for my final project in my web dev course, lol. Didn't even know there was a full-blown tutorial for the thing I was creating.
26:28 - better create getters of X and Y inside player class, so in case you plan to have a moveable player not a static one, so coordinates are calculated upon player but not unrelatively
Great job, very useful tutorial and really interesting game for the beginning. Thank you so much, keep going))) P.S. I recommend instead of copy-pasting classes make some parent class and then extend children classes
Im having a problem in which when I add an alpha value to the bacground to make it more transparent the desired effect happenes but I can see trails of the different colored shapes that were drawn
@@Lenny-nj8sc Ya man it's like teh tutorial !! Seriously, if u wan't to learn to program games, split it up. Learn javascript with focus on canvas, then learn basic math like sin/cos, vectors, and forget you ever saw this video.
I just discovered your channel and I find your videos very well done. However, it would be perfect if you used the inheritance to avoid copy and paste between objects that are very similar. For example, you could derive your class Projectile from Player or create a mother class and derive the Player class and the Projectile class from this mother class. What do you think about it?
This tutorial is the first in a short list of digestible content to show developers how to code a game with just Canvas, step-by-step. I remember a few years ago trying to find something like this on RUclips, and there was none to be found. So thank you for being a pioneer
Thank you for the amazing tutorial and code along experience!
If someone wants to have the shrink animation without importing an external library, it is pretty easy:
1. You define a property "targetRadius" in your enemy's constructor
2. In the update method of Enemy, you check if targetRadius is bigger than radius and if so you shrink it by a constant value (for example: shrinkSpeed = 0.8) and you pay attention that if the substraction gets you a smaller radius than targetRadius, you set it with radius:
if (this.targetRadius < this.radius) {
this.radius =
this.radius - this.shrinkSpeed < this.targetRadius
? this.targetRadius
: this.radius - this.shrinkSpeed;
}
3. In your game loop, instead of of using the library you just substract the value to enemy.targetRadius
If anyone is curious about what happend at 38:07.
It's good to realize the difference between requestAnimationFrame and setInterval
If you go to another tab your game pauses, because requestAnimationFrame only works if tab is active .
setInterval is active regardless if you have the tab open or not. So it's gonna keep push enemies into the array of enemies every second. And that's why at 38:07 the screen was full of enemies.
How you could avoid this: Your animate() function is called already as quick as possible by requestAnimationFrame().
Make a global variable called frames = 0.
In animate() just do frames++ to count up the frames
In spawnEnemies you just have to do some easy math to see when a second passed.
Usally browsers run at 60FPS. so each 60 frames = 1 sec.
If (frames % 60 === 0) { spawnEnemies() }
this comment is pure gold
@@modernmage aCKSHUALLY 🤓☝ it's just a highly abstract representation of the electrons that do and don't flow through the circuits in your computer, not pURE gOLD 🙄🙄
@@KingTMK you’re a highly abstract concept of ur dads sem…
i’m 5 minutes in and I already love how detailed you explain everything
That's a long one, just watched the intro, will save it for the weekend and code along. Thank you for sharing this Chris, I know it's a lot of hard work to produce content like this.
There's a lot of work in this video. From lighting, to cameras, to editing. I'm not even a 'programmer', but I'm interested in 'twine' with some javascript. (As well as streaming.) So, I'm actually as impressed more than you because he also has explanation style that's incredible.
как интересно, я постоянно встречаю ваши комментарии под самыми разными видео. Видимо мы интересуемся одним и тем же)))
+ + +
how interesting, I constantly meet your comments under a variety of videos. Apparently we're interested in the same thing)))
the real question is: did you do it?
or are you just here for traffic
@@WEBSTART-LIVE Я люблю Россию, я учился в Украине. это мой второй дом. Я надеюсь посетить Россию очень скоро
Since this came out on my birthday, I'll consider it a present. Thank you Chris you shouldn't have!
LOL
Came out a week before my birthday lol
Know this is late but happy birthday man!
I need to wait five more days
Great Job!!! Chris I am a retired programmer and spent several years in the training department (25yrs ago!). I can honestly say you do a better job then I did. I think everyone would appreciate more advanced JS GRAPHICS. I don't do much coding any more but still try to stay up to date watching good tutorials - I wish you had more :)
Great tutorial. I have 3 retro games I wrote in C# and this give me the information I need to migrate to run in a browser. Couple of suggestions:
1) store the ID of the spawn setInterval and call clearInterval(id) when detect game over or multiple instances of the interval will run and more and more enemies will be created per second on each restart of the game.
2) Move setting the canvas.width and height and player x and y inside the init() function to adapt to changes in browser window size when restart game.
Many thanks for the tutorial.
This was not only a very good Game Tutorial, it was also an excellent programming tutorial in general. Thank you for your time and dedication. I really appreciate it.
I know right!?
Chris, I watch these videos and feel inspired. Thank you for providing me with quality content. Don't listen to haters my dude.
First off, thank you Chris for such a wonderful series of tutorials, they are all magnificent.
Now, addressing a little issue. After you restart the game, the "spawnEnemies" interval remains set, therefore, executing it again will add an extra "spawner" each time, incrementing each time the amount of enemies per period. The possible fixes for this are simple:
One would be to simply execute "spawnEnemies()" once and only once, outside of any recurrent block. Another solution takes into account that "window.setInterval()" returns an Id, which we can save in a variable at the top, say for example, "let spawnerId". Once we hit a game over, inside of the startGameBtn's event listener, we clear this old interval via "window.clearInterval(spawnerId)", and then we add the new one. Hope this helps anyone who falls into the same issue.
Again, a most humble thank you for your efforts which are tremendously appreciated!
I started making canvas experiences in 2010, and I've seen many videos/tutorials since.
This video is one of the best tuts I've seen out there.
Your code is very clean, and in my opinion, your commentary is also very good and joyful to listen to.
Keep up the great work.
This game is fucking awesome, and the background music is amazing, this is definitely the best html canvas game tutorial !!!
I love the way you omit the html, head and body tags. I consider myself an intermediate front-end hobbyist and I completely missed that part of html5 until now. Mind blown.
I signed up for your newsletter. I am really impressed by your high quality course approach. I am looking forward to buying the rest of the course when it's ready. Thank you for your effort.
Thanks for watching 😉 Haven't had much time to keep everyone updated on the newsletter or produce the rest of the course yet, but it'll all be 100% ready by Oct. 31. Really appreciate your support and can't wait to help ya out some more.
You leave a lot to the automatic sorting of the browser, like just using the tag without putting it in the head, and not using semicolons in js. You are the first tutor to do this and I hear all the time how it's bad practice. But I respect that you have your own style and thank you for the very elaborate step-by-step.
such an amazing tutorial man! I coded along and did it, I'm teaching myself coding so it was a bit rough but was able to manage. the one thing Id appreciate it if you can make a video teaching us how to package the final product so we can share it with friends. thanks a lot.
The best programming tutorial I have ever seen
One of the best canvas tutorial ever
Great video style!
I like the lighting and the movement of the camera👍
Finally! After years of waiting! Thank you so much! I have learned the HTML canvas from you sir! And earned money using the things that you have taught.
Thank you so much! Your canvas tutorials are great!
I'm waiting for the tutorial of Collision Detections for other shape.
@Alexander Exis wed dev. Parts of my school mate's thesis that needs Canvas. I remember i sold 100lines for $50
Good call on the setTimeout workaround for the missing array element in the loop! I usually solve this by looping through arrays in reverse-but I like this a lot because you can use forEach 🤙
As Ive progressed in my code learning, my thought is that this video should be shown to any new coder as required material. It introduces and explains with direct results key concepts not only for JavaScript, but all object oriented coding. As a new coder, being able to see direct results not only instills understanding but also confidence. This video is better than all of the tutorials Ive ever taken on JavaScript. 100% pure gold.
Wow, awesome comment... really appreciate this one. I too agree beginners should take this, wish I had it when I was first learning game dev! Anyways, thanks again, nice comments like this always make me feel great 😄
Very cool. I am a Brazillian VBA programmer who has just started teaching how to use OpenGL library graphics with VBA and I'd like to convert this code to VBA with your permission
This video is amazing. Always thought html canvas and js arent good enough for building games. Obviously i was wrong and just didnt know any better.
Having tutorials like this available to everyone for free really makes me happy. Thank you again for sharing your skills, lessons and wisdom.
I am only 12 minutes in and I have learnt so much! Thank you!
man i was mind blown by the fade effect at 1:06:00, thanks for the great tutorial
Fantastic tutorial on canvas. Covers some important programming concepts. It's worth watching again. Thanks for putting this together for us.
Top quality video mate. I was stuck forever figuring out the angle and you explained it so well.
Pls help my enemys only spawn when i shoot a projectile and evrytime i shoot a projectile they get faster
Dude the accomplishment I felt after finishing the tutorial is amazing, dude u made this possible for me to learn gamedev on js, thank you
This is so amazing Chris. Seriously, you just saved me from stressing about my college assignment. I'm extracting these concepts into my MVC architecture-based app. Thank you very much!! :))
Great to hear! Coding tutorials helped me a ton in college as well, glad I could return the favor to someone else in return. Keep it up!
@@ChrisCourses Hello. Can I make this game little bit faster? It seems slower on my computer, projectiles even leave traces.
Very good tutorial, the learning material, the video, the sound, the explanation, everything is good. I know this tutorial could be more shorter but he does a lot of things in a purpose, and to make us understand every single of function or code. Great job. Very recommended 👊
The most useful video for a total newbie in game dev. Thank you.
I've just gone through a bunch of your youtube tutorials - absolutely hooked. You've got real talent as a teacher - signing up to your courses for more ^_^
Great to hear! I did that collision detection video with about 5 hours of work, so hoping I can just keep my head down and get stuff out more consistently. Need to stop trying to perfect everything and just go with what I'm quick at.
Appreciate all the support and will be comin to support you in return with more vids 🙌
I added a few things to mine.
Every 10 "kills", you go up one level. This makes enemies spawn faster and move quicker
You start with 3 lives, and they go down each time you're hit. If you run out of lives, its game over
Every 3 levels, you gain 1 extra life, up to a maximum of 5 lives at any one time
And then just some visual things like the player flashing red when hit and things of that nature
how do you make the enemies move quicker?
@@sebastianrechtman3749 Its been a while at this point so I don't 100% remember, but I think I made an Enemy Speed variable and multiplied that on the x and y angles when an enemy is spawned. Then over time that variable increases so the enemies get faster
@@isthereanexho can you share the code for this?
I was finding a tutorial to create a simple game with javascript, but look, what I found! A simple but professional looking amazing game with step by step explanation. Thanks
The best lesson to start learning JavaScript.
You are an amazing teacher. earning from you did not feel like learning at all and I had fun every minute! Thanks a bunch, may you and your generations remain blessed
Wow, I cannot thank you enough for 33:00 - 36:00, I have been building a similar game for a class project, and I couldn't for the life of me nail down the angle ratio! Also to answer your comment about why atan2 uses y over x is because it produces a slope m which equals rise over run or, (y0 - y1) / (x0 - x1), at least that is my understanding. Thanks again, great video!
This tutorial was by far the best I have seen, I loved the game and it was super simple. The camera and the lighting shows me how your course would be. IDK why people give credits to big entities when it is people like you who make true content. I wish I could enroll for the course but my family is not in the state buying the entire course, my sister and father had COVID-19 since 2020 and haven't recovered. I would be grateful if I could learn to make world class games from you. Anyways I LOVED your course and when I shared it with my friends on insta, They absolutely loved it. Lots of
Merlina is right, I loved the course in the same way, BTW Merlina was the one who brought me here. Lots of love from India
Thank you Merlina, comments like this really motivate me to keep going. No matter what, I’ll always be producing a good chunk of tutorials for free, so don’t even worry about purchasing anything from me, my main purpose is to help people grow, not make money. Your support is awesome (saw your comment on the water bottle vid too), and I’m very happy to have you as a subscriber. Thanks for watching, thanks for sharing, and can’t wait to get you more videos in the future.
idk how to thank you... the most amazing game dev tutorial on the earth
What a fantastic couple of hours. I also feel like I learn so much from your videos. I especially appreciated the collision detection explanation.
Chris, this the best beginner course I've come across for HTML5 Canvas game development.
For me, what makes it so accessible is the easy peasy approach to Pythagoras' theorem and the setting of the velocity objects properties.
Just as an aside, obviously you'll be aware that the code you've produced has a lot of duplicate functionality among you game pieces and that a single game piece class could be created from which all the others extend and specialize from.
I was thrown by your introduction that this would be vanilla javascript and then you introduced a third party graphics engine for shrinking the enemies. Couldn't you have coded this yourself?
But all in all this was top drawer, thanks again Chris.
Yeah man, I considered adding inheritance and imports to reduce the amount of code in the main file, but decided not to since it usually adds another layer of complexity and abstraction that makes things hard to change once your game gets bigger and bigger. I’m actually a programmer who leans more towards duplication than trying to abstract things consistently since it does have potential to affect so many parts of your game, app, whatever code you’re working on. Figured it would be easier for beginners too rather than have to delve into more strict OOP techniques. GSAP library not being vanilla makes sense though, I just hate animating with anything else hah. Really glad you enjoyed everything though, tried my hardest to make this one of the best 🥳
@@ChrisCourses
Fair do's Chris. I've got a degree in computing and many of my fellow students really struggled with OOP although I had taught myself OOP before I went to university and found it a breeze. The caveat with inheritance is to try to avoid fragile base classes WHICH WILL break your code base. But used judicially and correctly it'll reduce code.
I've been experimenting with HTML5 Canvas animation for the last few months and much prefer to build my own transition and transform modules but hey that's me.
Cheers for your reply and I've subscribed and look forward to more animation content from you. Well done mate.
You are gifted when it comes to explaining things
Thanks Chris for sharing a valuable knowledge so we can have a good fundamental on how to build a game using canvas and Javascript.
I’m Japanese so I can study Programming and English in this video.
Thank you very much.
Holy shit.. that's simply the best tutorial I've ever seen in my entire life. I haven't even done any GUI before and after watching this playlist, I've made a game in few days. Thank you so much man!!
broo i am from brasil and ai love your couse. i understand much better with you. dont stoping you work.
Your explanation is so deep and I love it despite I couldn't get the half of it :D
Really nice one - thanks. Just one remark: 1:47:41 spawnEnemies() should be called once (outside of the listener). Otherwise you will create always an additional interval by calling setInterval() --> enemies increase by each restart of the game.
Nice catch. I was noticing that one..
Thank You ... :)
Great tutorial!
Just want to point out, modifying an array during iteration is a bad practice. What you do with setTimeout works, but a better approach would be to do array.slice().forEach(). slice() will create a copy of your original array, and fill-it with your original objects (e.g. projectiles). This means that when you remove a projectile (or enemy) with splice(), it will modify the original array, but not the copy you are iterating over.
P.S. The "P" make all the difference - slice() vs splice().
That was a great suggestion, thank you. My projectiles were disappearing as soon as the 1st projectile went off the screen so my original array was being deleted and the rest of the projectiles would disappear before leaving the screen.
man you are great,
i even speak english very well and i can understand all you speak.
Thank you very much for your time
Hi from Brasil. :)
Eae carai🇧🇷
Thanks for the tutorial! Here is how I fix the bug where enemies keep spawning after game ends:
- pullout the unamed function inside spawnEnemies, make that spawnEnemies instead
- let spawnEnemiesInterval (global scope)
- inside start button event listener funtion, spawnEnemiesInterval = setInterval(spawnEnemies, 1000)
- inside game end condition, above cancelAnimationFrame, add:
clearInterval(spawnEnemiesInterval)
Hi thank you for your explanation, I have tried what did you said but it did not work for me,
If you don't mind, can you share with me the code to prevent enemies from spawning in the background
what unnamed function?
BUG ALERT!
I think anyone who watched the video could spot the bug where when the game is stopped, the enemies KEEP SPAWNING so when you start again you just get a ton of enemies coming your way...
Took me about half an hour to figure out i had to use clearInterval() inside the spawnEnemies function.
And while we're at it, the window's event listener should be removed when the game is over and re-added when the game restarts so you wont be able to shoot projectiles when the modal is open.
Hopes this helps someone ;)
yes, really.. bro can you help me with the clear Interval I don't manage to put it in the correct place, please I would really grateful for this...
Yeah i can help you!
Firstly, in order for clearInterval to work, you need to give it an actual function reference (not an anonymous arrow function). I extracted the nameless function he used in the video - spawnEnemies, and made it into its own function and called it spawnEnemiesFunction. Then, i used const spawnEnemiesInterval = setInterval(spawnEnemiesFunction, 1000) to actually spawn enemies each second.
Now, when the game ends (the player loses), i call my endGame() function, which is responsible for the cleanup.
inside it, i use clearInterval(spawnEnemiesInterval), and i also remove the event listener from the window object via removeEventListener method.
really hope this helps :)
feel free to ask any more questions!
@@dandandrorivolleyball wow thx
could you write down the code in the comments please? I can't really understand how I should input clearInterval() into my code.
This is a common mistake for people making games in HTML5
That is why "requestAnimationFrame" is always better than "setInterval" or "setTimeout" to create game loops because it is only called when the window is active.
Also, All events run in parallel to the base JS code, It's like they were different applications running at the same time as everything else, so you must be careful how you use them, else you might get into an unwanted state, and get errors or bugs from there.
Awesome tutorial. It's really a fully fledged-out game!
For those that do not want to use any external library like me:
You can go to tailwindcss' page and search for the class that Chris uses to see what's the equivalent
in plain css. E.g. "items-center" is "align-items: center"
Again, this is the best js game tutorial from scratch I've watched...
It is an amazing tutorial! Clear step for the coding and math concept, thanks Chris!
really appreciate it chris. the quality of your videos is another thing. please also make filming videos just like before. thank you
Great video Chris, I enjoyed it very much and I liked that you kept it very simple and avoided to refactor your code or make abstractions.
Very fast-paced and straight to the point! Great vid, learned loads of new tricks!
This is a *FANTASTIC* tutorial! Seriously, one of the best I've seen. Thank you so much for taking the time to make this. :)
Anytime, glad it was helpful! There's a continuation over on chriscourses.com if you need it-also have a side scroller course on the way to satisfy any desires there 🙌
This is really awesome, guy. Thank you so much for connecting the dots for beginners.
Amazing tutorial!
Very clear explained and simple to follow along
If you're having problems or perhaps using messed up equipment like me, you could just create a Player object instead of using class though using class makes it much easier
Thank you very much for the great video! I learned HTML, CSS and even javascript functions! I made my version of the game where you can move by the X axis. I used it for my project for school and my teacher was AMAZED! Thank you so so much for the great explanation! I also found the geometry in this video very useful and helpful!
Chris you are my best teacher
1 final touch: add a spawnIntervalId for the setInterval and use clearInterval(spawnIntervalId) near cancelAnimationFrame to prevent spawning after the game ends.
hey man, I'm not quite sure what to do about it. Can I reach you out?
Hi did you guys solve it if yes can you show me how throw code
Nice little tutorial, well paced instructions...i found when it came to looping over the enemies and then the projectiles the code was glitchy...sometimes projectiles would pass trough and enemies wouldnt remove properly....it simply replaced with a generic for loop for both and spliced within there and that fixed it...like the other users have said its generally not good practice to remove from an array while looping over it. Well done though, very good and reminds us how quickly JS/Canvas games can be pulled together.
Oh, I was slowly coming to the conclusion that you're gone for next 5 months and it was just messed up hard drive :D Anyway, looking forward to watch the tutorial, beacause I didn't see many canvas game tutorials on RUclips. I tried to make some, but it wasn't really good. Hope this will help. Keep up the great work!
I was legit so bummed when the hard drive got corrupted - so much work down the drain. Definitely a mood killer, but decided to get back at it eventually lol
@@ChrisCourses have more than one hdd! !
You have such an awesome video and sound quality :D and I also like the way you explain, especialy the fact that you explain in small steps :D
Great tutorial as allways! Really appriciate the effort you put into these!
I made this game completely.
Thank you very much and best wishes.
I want many more videos from you
Can You share me with the source code please
thanks I just finished this tutorial. Finished product came out good and I learned a good amount !
i recommend using pythagoras' theorem to normalize the xy vectors instead
because we can calculate the hypotenuse if we have the opposite and adjacent sides (and disregard the angle at which it is shot entirely unless we need it)
using atan2 and then sin/cos to get a vector of magnitude=1 is slightly more tedious and likely more resource intensive than the other approach
Hey thanks man. Had grid based game concept but didnt know Canvas all that well. This got me everything i needed to get started! Thanks.
Just a fantastic tutorial. Loved watching and following along!
Mans looking beefed up! Great tutorial man.
This is an excellent tutorial Chris. You explained the process very clearly and the end result is really cool. Nice work and thanks for sharing. :-)
for every ball shaped things (e.g. player/ projectile), we can use a Ball class with params and the draw function.
then for example if we want to do the player, we can use
class Player extends Ball to have the params (x,y,color...) and the draw function.
Btw your tutorial is amazing!
I made something like this for my final project in my web dev course, lol. Didn't even know there was a full-blown tutorial for the thing I was creating.
Great explanation and really good game. .
Especially the particle effect. Love it.
26:28 - better create getters of X and Y inside player class, so in case you plan to have a moveable player not a static one, so coordinates are calculated upon player but not unrelatively
Great job, very useful tutorial and really interesting game for the beginning. Thank you so much, keep going)))
P.S. I recommend instead of copy-pasting classes make some parent class and then extend children classes
That's my plan. Though I wished he would have done this initially I figure it will give me some practice in learning more about inheritance.
this is my second tutorial of yours. great work. where did you learn all this? can you reference some materials?
Man, I love this video! Thanks for taking the time to make it!
I'm done watching the tutorial, I learned a lot. Thanks Sir!
you are great programmer ❤❤❤❤❤♥♥💕 .............. love and salute from india
Hope there will be more tutorials like this
こんなにも質の高い動画を無料で出して頂き、ありがとうございます。説明がとても丁寧でわかりやすかったです。一通りゲームを作って、音楽を使いたいのですが、曲名が分からず困っています。教えていただけたら幸いです
I learned so much from this video, thank you for helping me improve my JavaScript skills!
you saved me from university assignment. thx bro
Im having a problem in which when I add an alpha value to the bacground to make it more transparent the desired effect happenes but I can see trails of the different colored shapes that were drawn
Define the alpha value on the canvas with the fillrect method, not the background color of the html page.
Awesome game tutorial with wonderful explanation.
Great tutorial! I love your way of explaining how things work. Great Job!
This tutorial is fucking perfect i watched like 10mins and now I am god in CSS, html, canvas and javascript
wait does it actually make you learn that much?
i am looking to follow this tutorial to make my first game so that's why I am asking lol
Watch a little longer, and u become a god of math also :)
@@evilspoon6833 lol
@@Lenny-nj8sc Ya man it's like teh tutorial !!
Seriously, if u wan't to learn to program games, split it up. Learn javascript with focus on canvas, then learn basic math like sin/cos, vectors, and forget you ever saw this video.
@@Lenny-nj8sc When u actually trying to learn he explains everything. Some obvious things for beginners that every1 assumes all know and omit them.
bro, your canvas tutorial and this video really helped me, thanks a lot
actually made this, great tutorial great explanations, learned a lot, keep it up!
this was awesome. really helped start my project. thank you. and thanks for being so great!
Good content, clear explanation. I dont even want to build games, but the overall knowledge will be helpful.
I just discovered your channel and I find your videos very well done. However, it would be perfect if you used the inheritance to avoid copy and paste between objects that are very similar.
For example, you could derive your class Projectile from Player or create a mother class and derive the Player class and the Projectile class from this mother class.
What do you think about it?