Tower Defense Game Tutorial with JavaScript & HTML Canvas -

Tower Defense Game Tutorial with JavaScript & HTML Canvas

Chris Courses
Views: 78589
Like: 2170
Ready to create amazing games? Join to learn, grow and thrive from over 100 videos, quizzes and code challenges:

Here you’ll learn how to create your very first tower defense game with JavaScript and HTML canvas. We’ll start by creating a game map using a map editor called Tiled. Then we’ll code the basics of a tower defense game using nothing but rudimentary shapes. Finally, we’ll replace our shapes with sprites to give our game a professional look.

Google Drive Assets:

Finished Demo:
Source Code:

Tiled Map Editor Download:
Stone Tower Assets:
Desert Tileset:
Orc Sprite Assets:
Font Awesome:

0:00 Introduction
0:51 Game Assets and Downloads
5:40 Create a Path
23:53 Map Details
31:42 Project Setup
48:31 Pathfinding
1:28:55 Building Placement
2:12:03 Shooting Projectiles
2:50:40 Health Bars
3:02:46 Waves
3:09:43 Game Over
3:39:13 Resources
4:01:12 Sprites – Projectile
4:16:09 Sprites – Enemy
4:34:15 Sprites – Building
4:55:25 Sprites – Explosions
5:04:50 Launch

Music by Joe Gallagher:


  1. You have changed my perspective on game dev!!

  2. make a 3d game using cvs.getContext('webgl2')
    no threejs

  3. this is a superb tutorial – first rate explanation – great teacher

  4. We need to get this legend to 1M subscribers at all cost!

  5. Chris thanks for your courses words can't describe how they have improved my game development skills, I even got my first paid project with the knowledge of my game dev 🚀🚀

  6. Commenting to reference you, thank you so much for your videos, they're top quality and extremely helpful !!

  7. Yes!!! I've been waiting for this video since you announced the video!

    I'm really glad I found your channel. You explain things SO well and I didn't even realize you could create games with only JavaScript. Keep up the great work!

  8. Thank you very much Chris, your tutorials are fantastic!

  9. oh I am thanking you very much… can you make next something 3D by using the canvas.getContext("2d")? I am so excited for that video… thanks

  10. Thank you so much, Chris, my son really adores your channel! He claims that you inspired him to become a "Front End Developer." Your hard work means a lot for me as much as it does for my son. Keep up the great work!

  11. Great video! Could you please also make a video on how we could monetize these games built with Javascript? Maybe also release them on Android or IOS? I am really thinking of this as a full time job.

  12. In YouTube there are not many tutorial on Canvas. Thanks for it.

  13. 100% Im feeling the next one is going to be a lovely RPG game with basic sprite sheets, teleport from one place to another, basic inventory and some juicy cool extra shenanigans things, im looking towards it. I love your work and patience to explain everything, keep the energy and vibes all the way up !!

  14. Great 👍 tutorial thank you 😊
    Hello Chris how are u? I have a question. I want to make app like webflow So should i use canvas to make that kinda project or not

  15. Chris, hi from Brazil!

    Can you make a javascript tutorial on how to display a div on a button click, the div being always attached to the button by the ID, and show above/bottom or left/right of the button when this button is positioned at top, bottom, left, right of the window? I'm bangging my head against the wall trying to do this!

  16. Thank you for your work i like how you doing videos

  17. Very cool. I watched first mins of showcase then coded everything in my own way. Thanks for inspiration, assets, and I love your canvas videos!

  18. I'm gonna buy your courses man! it's amazing!
    Thank you a lot!!

  19. Awesome, did you use any specific program to actually make the tileset.png? I would like to build a game based of this tutorial but not sure how I would merge the assets together to one file. Perhaps that's not really necessary?

  20. Hi, how to convert .fla to .png, or fla to something else to use in Unity?

  21. How to create tower.png with different tower. Your resource have rock tower. I need to create more tower with png. Thank you so much.

  22. Hey, look over t-here —————–> now look right t-here <———-. T-you know t-what I'm t-saying, right? t-cheers

  23. Maahnn this video is fire!!!!….🔥🔥🔥

  24. hey man please built brick breaker type game

  25. 1:27:00 I don't give an intial x and y position with my constructor, since this information is in the waypoints array anyway. When changing the initial x position after going through the initialisation array, the code always writes the x position for the last element to all elements in the array. Can anyone explain why this could be? I guess it has something to do with how js refers to objects, but I am not well versed in this language. My intuition tells me this should work.

    const enemies = [];

    for (let i = 0; i < 10; i++) {

    enemies.push(new Enemy());


    for (let i = 0; i < 10; i++) {

    const xOffset = i * 150;

    enemies[i].position.x -= xOffset;



  26. You are amazing🙏🙇🙇🙇 thanks to you i will be able to make and develop my first game im currently grabbing assets and stuff now to make it thank you once again 🙇🙇🙇🙇

  27. when I use
    position: { x:waypoints[0].x, y:waypoints[0].y
    I got – "ReferenceError: can't access lexical declaration 'enemy' before initialization"

    and I have no idea why.

  28. at around 40 minutes in, there is a bug with the canvas getContext. the browser console says that is cannot read the property of null

  29. the moment i paste in the second svg everything goes black barring the newly pasted icon. Really confused can't seem to fix this either. Anyone have any idea what's happening/how i can fix this?

  30. Ive meticulously followed this up till 1:28:43

    I have gone over it and over it for hours and in my console i have zero syntax errors and it says everything is fine.
    Ive asked chatgpt and it tells me the const waypoints. So i added them manually like got told me too. The browser said no it was already there as it is with yours. I have scoured it and compared it to yours its the same. Ive rewatched and retyped. No errors but i have one stationary red block in my top corner and nothing moves with waypoint animation. My console is clean on multiple browsers, no problems why is mine not moving along my waypoints.
    I do have my folder set up the same as yours, waypoints.js and in a js folder, the waypoints.js file is const, i followed this in tandum and ideas other than chat gpts ideas? I see that others here have had success so i know its obviously my error if you could take a minute and identify my mistake id be grateful:
    const canvas = document.querySelector('canvas')
    const c = canvas.getContext('2d')

    canvas.width = 1280
    canvas.height = 768

    c.fillStyle = 'white'
    c.fillRect(0, 0, canvas.width, canvas.height)

    const image = new Image()

    image.onload = () => {
    image.src = 'img/gamemap.png'

    class Enemy {
    constructor({ position = { x: 0, y: 0 } }) {
    this.position = position
    this.width = 100
    this.height = 100
    this.waypointIndex = 0 = {
    x: this.position.x = this.width / 2,
    y: this.position.y = this.height / 2

    draw() {
    c.fillStyle = 'red'
    c.fillRect(this.position.x, this.position.y, this.width, this.height)

    update() {

    const waypoint = waypoints[this.waypointIndex]
    const yDistance = waypoint.y –
    const xDistance = waypoint.x –
    const angle = Math.atan2(yDistance, xDistance)
    this.position.x += Math.cos(angle)
    this.position.y += Math.sin(angle) = {
    x: this.position.x = this.width / 2,
    y: this.position.y = this.height / 2

    if (
    Math.round( === Math.round(waypoint.x) &&
    Math.round( === Math.round(waypoint.y) &&
    this.waypointIndex < waypoints.length -1
    ) {

    const enemies = []
    for (let i = 1; i < 10; i++) {
    const xOffset = i * 150
    new Enemy({
    position: { x: waypoints[0].x – xOffset, y: waypoints[0].y }

    function animate() {

    c.drawImage(image, 0, 0)
    enemies.forEach(enemy => {


  31. I fell asleep watching cube marching and woke up to this

  32. Wouldn't it be more sensible and robust to set objects in an array to null instead of splicing them out. And just check for a null (which you should always do anyways)? At least you don't need to worry about updating an array whilst looping through it.
    Either way this is easier than in C/C++ where you'd actually have to register which struct/object you want to free/delete.
    Also i noticed that projectile path is update every frame, so you have a "hear seeker" rock 😀

  33. In the near future when I will get a job , I promise I will donate money to your account, your tutorials are amazing and the way you explain is simple and straight to the point. I wish my college professors were teaching us the way you do. All the best <3

  34. All you had to do is used two inner corner pieces

Leave a Reply

Your email address will not be published.