How to Program Games: Tile Classics in JS for HTML5 Canvas
4.8 (769 ratings)
Instead of using a simple lifetime average, Udemy calculates a course's star rating by considering a number of different factors such as the number of ratings, the age of ratings, and the likelihood of fraudulent ratings.
3,984 students enrolled
Wishlisted Wishlist

Please confirm that you want to add How to Program Games: Tile Classics in JS for HTML5 Canvas to your Wishlist.

Add to Wishlist

How to Program Games: Tile Classics in JS for HTML5 Canvas

Learn to code tile-based worlds and related core gameplay for genres like arcade, overhead racing, and puzzle adventure.
4.8 (769 ratings)
Instead of using a simple lifetime average, Udemy calculates a course's star rating by considering a number of different factors such as the number of ratings, the age of ratings, and the likelihood of fraudulent ratings.
3,984 students enrolled
Created by Chris DeLeon
Last updated 12/2016
English [Auto-generated]
Current price: $29 Original price: $45 Discount: 36% off
30-Day Money-Back Guarantee
  • 5 hours on-demand video
  • 16 Supplemental Resources
  • Full lifetime access
  • Access on mobile and TV
  • Certificate of Completion
What Will I Learn?
  • Create, display, and play with a 2D tile world that supports optimized collision (a central concept for generations of games in a variety of genres!)
  • Program games in JavaScript for HTML5 Canvas without using any external libraries or plug-ins
  • Create, load, display, and rotate image graphics in games
  • Break game code into multiple files to better manage large projects
  • Define a class and use it to create multiple instances of gameplay objects in unique positions (note: only using the very basic first concept of object-oriented programming, it doesn't dive deep into that rabbit hole)
  • Handle mouse input for a one-player game, or keyboard controls for both one and two-player games
  • Implement basic item pick-ups (keys) and trigger their usage upon collision (open doors)
  • Develop and adapt gameplay for basic platformer movement, digital board/strategy games, simple matrix formations for retro arcade-style enemies, and worlds larger than the screen viewed by scrolling camera
  • Apply simple trigonometry calls to move game objects at arbitrary angles
  • Implement basic loading screen functionality in HTML5
View Curriculum
  • Any plain text editor like Notepad will do, however one which supports features for programmers such as multiple file tabs, code highlighting, line numbers, and smart/auto-indentation can be handy for later phases as the code grows in length (Notepad++ is free for Windows, TextWrangler for Mac, or Sublime Text 2 which I use has a fully functional free trial for either)
  • Any common web browser should work fine, although I use Google Chrome (free) so you may prefer that one just to see on your side exactly how it shows up in the videos
  • To follow along the few steps for drawing art you'll need a program that lets you draw and save images with transparency. I use a slightly older version of Photoshop, although free alternatives exist and the steps are similar. I also attach all art files that I create, so if you prefer to only focus on the coding steps you can download the images that I create in the videos.

By taking this new course you'll program several classic game types that all incorporate 2D tile-based worlds. You'll code in JavaScript for HTML5 Canvas, so a text editor and ordinary web browser are all you need (an art program can be handy for a few sections but is not required). I've attached my code for each step so you'll never be stuck. At the end you'll learn even more ways to apply what you've learned. Also by completing the course you'll get a PDF of my complete 500-page textbook on game development: Hands-On Intro to Game Programming. The book contains over 100 exercises, a couple of more game types, and additional material with more detail about the projects you created in this course.

(HTML5 Logo in the course image is by W3C, licensed under Creative Commons Attribution 3.0 Unported. Background pattern for transition cards CC BY-SA 3.0 Subtle Patterns © Atle Mo. drawn by Paul Phönixweiß.)

Who is the target audience?
  • Anyone who wants to learn practical skills to program their own games at home
  • People who may aleady be familiar with programming concepts but are new to applying that knowledge to making real-time computer games
  • Creators who have only ever tried drag-and-drop tools but are interested in learning more about how to make games by programming for an deeper level of control over the details
  • Developers interested in getting practice with a more traditional "code only" approach to core gameplay programming before moving on to major engines and tools (which are not covered in this course) like Unity or Unreal
  • People looking for a technical game design foundation based in indie-style games or classic gameplay as a starting point
  • New developers who completed the free course "Code Your First Game: Arcade Classic in JavaScript on Canvas" and are looking to furthr build upon their game development skills in JavaScript on HTML5 Canvas
  • Please note that advanced topics like object-oriented programming are only very briefly touched upon - software engineering patterns are generally outside the scope of this course
Curriculum For This Course
150 Lectures
Introduction to Your Course and Instructor
1 Lecture 07:17

Here's what you'll be learning how to create in this course, and a bit about who you'll be learning it from. Pleasure to meet you!

Preview 07:17
Ball with Mouse Paddle - Warm-Up and Review
15 Lectures 32:59

This lecture is just a bit of set up and context for what you'll be learning in this review section, including one last reminder about the previous free Udemy course that this one builds upon.

Section Introduction

Making an HTML file is a simple matter of creating a plain text file and saving it with the right extension. As a reminder, since you're programming you should make sure that your OS is set to show all file extensions, rather than hiding known types, since otherwise it will be tough to tell txt from html files, png images from jpg images, and so on.

Create the HTML File

Whereas other browsers may let you get away with a very basic (if technically incorrect) HTML wrapper for your game files, Firefox is picky and will complain with a warning in the console unless you provide it with a proper header. Since many people use Firefox and this doesn't take very long to do let's take a moment to form it properly.

Proper HTML Header

You'll see how to open your console, print code to it from your program code, and also see an example of spotting an error message in it due to an issue in the programming.

JavaScript in HTML with Console Use

To display graphics for your games we'll need a canvas to paint on. In this step you'll create that canvas with HTML and set up a way to use it from the JavaScript.

HTML5 Canvas with Setup Function

During this lecture you'll write code to display colored rectangles and circles.

Draw Filled Rectangle and Circle

For action to happen over time, rather than being computed all when the program stats, an interval time has to be set up. That's what you'll accomplish here. To show that it's working you'll also use a variable to position the ball, changing it on each update call to produce a steady horizontal motion.

Variable and Timed Updates for Motion

Now you'll get the ball bouncing off the left and right sides, as well as moving vertically and bouncing off the top and bottom of the canvas.

Modify Speed, Also for Vertical Motion

There's a semi-mysterious giant rectangle being drawn every time the game updates. It deserves some explanation (maybe even a bit of demonstration?) for why it's there.

Reason for a Big Rectangle Each Frame

Time to separate the movement and rendering lines of code. Although this isn't technically necessary it can help reduce strange complications that would later arise due to positions being updated and drawn in varying order.

Separate the Motion and Draw Code

Drawing colored rectangles and circles currently takes multiple lines of code, but that just seems silly. Here we'll wrap those up into functions so that the code which needs to use them can be kept higher level.

Make Functions for Fill Rect and Circle

It's time to hook up mouse movement to guide a player paddle. This will serve as the player's avatar within the game space.

Mouse-Controlled Horizontal Paddle

If the ball continued bouncing off all four walls there wouldn't be much challenge to the game. Here we'll create the impression that the ball can fall off the bottom by resetting its position when it reaches that edge.

Reset Ball When It Goes Off Bottom

Whereas the game shown in the previous course kept the paddle up against the edge to keep the collision code simple, for this newer game it's time to get a little fancier and give it some space from the edge. When the ball and paddle overlap (well, technically when the ball's center passes within the paddle's boundaries) the ball will bounce.

Move Paddle From Edge, Reflect Ball

Ball control is essential for these kinds of games. Here you'll review the most popular method used to steer the ball and then implement it.

Aim Based on Where Ball Hits Paddle

Most later quizzes are only a few questions, however this first one is just a little bit longer to help straighten out or refresh some concepts before going forward.

Feel free of course to skip these short quizzes if you would prefer to continue immediately and want to focus mainly on building the projects. However: being prompted to answer a question, even if it's an answer you already know, can help retain the information in your long-term memory. Couldn't hurt to give the questions a look, right?

Section 1 Review
7 questions
Row of Removable Bricks
10 Lectures 20:37

Just a brief explanation to set up what you'll hear about in this section, which includes a little extra text display code to help you inspect positions and measure the size of each brick.

Section Introduction

Here you'll set up a function to display text within the canvas area, use it to show the mouse position near the cursor, and verify that its output is consistent with what you know about your canvas.

Display Mouse Coordinate by Cursor

At this point constants will be created to describe the bricks in a consistent way. You can use these values here to draw a lone blue brick in the corner of the canvas.

Set Up and Display the First Brick

Now you'll compare a couple of different ways to leave visible gaps between the bricks. I'll make my case for subtracting the margin from the rectangles, rather than adding a margin between them as spacing.

Draw Multiple Bricks with Gaps

Each brick will need its state kept separate in the code. You'll set up a way to toggle specific bricks on or off.

First this will be done inelegantly by giving each brick its own separate variable. Soon this will be replaced with an array to make the code more straightforward and easier to adjust.

Vanish Individual Bricks

By numbering your bricks starting from 0, rather than from 1, you'll establish a clearer pattern with how each bricks is positioned as a multiple of brick dimensions. This will also help clarify the relationship to the array usage coming up soon.

Renumber Bricks to Start at Zero

Instead of having a distinct variable to go with each brick you can keep all of the states as a group in an array. The advantages to doing this will become more clear as we begin using it to reduce redundancy in the code.

Using an Array for Bricks

You can reduce code duplication in several places, even already, by using a for-loop in each place to deal with the bricks in sequence rather than doing so independently.

How For() Can Loop on the Brick Array

Now that bricks are handled systematically it's important to know how to check and modify specific bricks from the set. As evidence that the changes are reflected in the layout you'll also set up bricks to randomly be missing, each with its own 50-50 even change while being set up.

Clearing Isolated Bricks in the Array

Although comments don't affect what code does, good use of comments can save you real time as the programmer. In many cases comments are about description or explanation. The usage I show here has more to do with maintaining structure by giving meaning to otherwise identical closing braces } which appear close together.

Label Deeply Stacked Closing Braces

Since the material covered in this section is mostly new, I encourage taking this quiz even if you skipped or easily breezed through the previous one. I've still designed these questions to not be stressful or overly taxing. It'll be helpful to make certain you have these concepts down before moving forward.

Section 2 Review
2 questions
Ball-Brick Grid Collision
12 Lectures 23:49

You're about to change the type of information being displayed as text by the mouse, but first I want to clarify what it's going to be.

Section Introduction

Instead of showing a pixel x,y value by the mouse you can do a bit of division by brick dimension constants to find any given point's corresponding column and row.

Display Tile Coordinate Near Mouse

By drawing several rows of bricks stacked on top of one another you'll create the initial version of the tile grid.

Supporting Multiple Brick Rows

Accurate terminology in code can help keep ideas and reasoning clear. Column is a better label for the axis of bricks perpendicular to the row, rather than the term "count" which fit for a single line of bricks.

Changing Brick "Count" to "Columns"

The array of brick states only has a different value per column, but you need a way to set and check the condition of any brick also if it's in a different row. The trick is to look at the array left-to-right, top-to-bottom, like words read on a page.

Note that whereas many programming languages support 2D arrays or ways of creating nested arrays - meaning arrays with more than one index, for example column and row - I've opted to show for these projects how to do it with a linear array. This is a slightly more universal approach, only involves one extra step, avoids common confusions with the order of access coordinates, and is helpful as a pattern to practice since it relates to other situations sometimes encountered in game and graphics programming.

Support Removal of Each Brick Position

Thanks to the orderly way in which the bricks are now handled in relation to their constants, you can change the number and size of bricks then have the game still work more or less the same.

Make More Bricks, and Smaller

In order to have the ball interact with bricks you'll need a way to compute which array index corresponds to a given column and row for a brick position on the canvas. The math for this is simple, but why it actually works is sometimes tricky for people to visualize when new to it.

Compute Index From Row and Column

Since you can find the pixel position of the mouse, get the column and row for a given pixel position, and the array index which corresponds to any column and row pair, you have all the information needed to vanish bricks when they're under your mouse cursor.

Remove Bricks Under Mouse

This takes the functionality which was used for the mouse pointer and does it for the ball's position instead. Even though it's technically not much different at a code level the effect makes the ball feel a lot more real within the virtual space than it did while passing through bricks without consequence.

Remove Bricks Where the Ball Goes

A side effect of how the linear array positions match up to row and column pairs is that if the ball collides with the left or right edge of the screen it may interact improperly with a brick which is nearly across from it on the screen. This helps highlight why boundary checking needs to be kept separate for column and row, i.e. it's not sufficient to just determine whether the computed array index is valid in the array's bounds (from 0 to the last element).

Fix Edge-Wrap Collision Bug

The method here is very basic, but easy to do, and it already gives the ball a more solid feel within the game.

Bounce Ball When It Hits Bricks

The ball has been starting within the brick wall, although that didn't really matter up until the ball's path started being affected by the bricks. I'll show here how to start the ball in the screen's center, below the grid... but I'll also explain why putting off this fix until a bit later will actually make it easier to work on improving the ball-brick collision.

How to Start the Ball in the Center

Answering these questions is optional but recommended.

Section 3 Review
2 questions
Advanced Ball Collision
6 Lectures 18:07

A moment to highlight why the ball-brick collision code is about to get a little more complicated.

Even though the desired result is intuitive, the ways to accomplish it require a logical way of reasoning about different cases in terms of a ball's position or velocity relative to a brick when the two collide.

Section Introduction

The movement function is taken over by various blocks of code handling different situations for the ball. To keep that code organized so that it's easier to read and work on let's break that code up into smaller functions with descriptive labels.

Cutting Ball Code Into Functions

There are various approaches to determining which side of a brick is hit by a ball. I'll explain a method here which is appealing because in addition to using values easily available to the computer it also makes conceptual sense in the most common cases.

Understanding the Ball-Brick Side Test

The previous step was just talking about it so that it'd make sense while doing it. In this step you're actually getting the side collision test working.

Get the Ball Bouncing Off Brick Sides

By teleporting the ball to the mouse whenever the mouse moves, in addition to giving the ball a consistent heading at that time, you can more easily reproduce collision cases to determine which if any still produce unwanted results.

Add Cheat to Reposition the Ball

This complication emerges as an effect of earlier corrective code. The simple workaround is shown here.

Fix the Covered-Edge-Corner Case

Answering these questions is optional but recommended.

Section 4 Review
2 questions
Finish Brick Gameplay
9 Lectures 14:16

In this section you'll wrap up the remaining core gameplay for this project. After this one you'll move directly on to reworking it into the Racing practice game.

Section Introduction

In order to tell whether the player has run out of bricks to hit you'll want a way to keep an accurate count of how many are left.

Keep Count of Bricks Remaining

This seems like such a simple thing, but it impacts gameplay by giving the player an implicit mini-goal and establishes a range for what it means to do it well (minimal exit space upon entry) as opposed to poorly (huge or numerous openings into the top before getting the ball up there). The technical aspect of achieving this isn't complicated, but can be a tad awkward.

Start with Empty Gutter at Top

Rather than present the winning player with an empty space forever until they willingly let the ball pass it makes more sense to refresh bricks once they all get cleared. To avoid the ball becoming stuck inside the wall wait for the ball to return to the paddle before refilling the grid. We can also now let the ball start in the middle of the play area.

Reset Ball at Start, Bricks After Last Hit

There needs to be some penalty for missing the ball. There's no concept in the game at this time about either limited lives or a scoring value, so for now missing the ball will cause the player's progress to be reset.

Reset Bricks When Player Misses Ball

The bottom-most bricks in the grid cause a strange ball behavior. You'll learn why that is, and what we can do it about it.

Fix Bug with Hitting Bottom Bricks

Playing your game is an essential part of making it, in part since while doing so odds are good that you'll spot more things about it that ought to be changed.

Testing to Look for Remaining Bugs

If the ball hits the paddle near a wall sometimes the ball gets wedged partially off-screen. I'll explain what causes this to happen, then we'll fix it.

Fixing the Ball-Stuck-Along-Edge Bug

Another quick test run just to double check that the code is behaving as expected.

Play Testing to Look for Bugs Again

Answering these questions is optional but recommended.

Section 5 Review
2 questions
Adapt the Grid for Racing
9 Lectures 14:41

Very brief introduction to what you can expect in this next section.

Section Introduction

Since the whole project will be reworked into the Racing game now is your chance to make a copy of it before proceeding.

Now Let's Tear This Up

The ball will become the car and the bricks will become the track, but there's no need for something in this Racing game which has much in common with the mouse paddle.

Remove the Paddle

Since the bricks are becoming track sections the code naming should reflect that, or things will get needlessly confusing soon. Remember to use case-sensitive with different variations (lowercase, camelCase, and UPPER_CASE) any time you're doing find and replace in code.

Rename "Brick" in the Code to "Track"

By adjusting the tile dimensions as well as the row and column constants you can stretch the grid to cover the entire canvas. This will be useful for using the grid information for map layouts.

Stretch Tile Grid to Cover the Canvas

Rather than having for() loops set all track wall states on, off, or randomly, it makes sense to instead design ahead of time a layout which makes sense for your game. To do this we'll move away from using true/false boolean to indicate state and instead use 0's and 1's, which has the added advantage of being able to depict more information for a given tile.

Design a Grid Layout by Hand

Here are some simple layouts showing the connection between the array data and the game's environment.

Quick Example of Grid Map Design

I'll show you the layout I've designed for use. If you want to use this one but don't want to bother typing it in you can download the attached resources and grab it from my file.

Fill in a Basic Track Layout

It's often helpful to be able to place characters, items, or in this case cars (well, ball for now) to begin in specific places within the tile data. Here's a way to make it do just that.

Set Ball Start Location in the Array

Answering these questions is optional but recommended.

Section 6 Review
2 questions
Draw and Code an Image
4 Lectures 10:42

Time to create a bit of art.

Section Introduction

Here's how I create the car(s) graphics.

How to Create the Car Image

These lighting effects aren't done in code, they're actually just a simple part of the image file.

Turning on Headlights and Taillights

Having the image made only gets you partway there. Time to load it from code and get it displaying in-game.

Import and Display the Car Image

Answering these questions is optional but recommended.

Section 7 Review
3 questions
Spin and Angled Motion
7 Lectures 08:26

This section will replace the ball that bounces with a car that drives.

Section Introduction

First fix up labels in the code. In addition to keeping the code clear to reason about this also makes it easier for us to talk about.

Replace "Ball" in Code with "Car"

Keeping an angle variable isn't very tricky, however writing an image function to spin an image around its center reveals this task to be a bit more involved than it seems.

Spin the Car Image

This is a common usage of trigonometry calls for game programming, however it often trips up people new to doing it. The next two lectures will provide animations, illustrations, and explanation of what it's doing and why.

Preview 01:16

No talk here of identifies, proofs, or equations, instead it's all about a very practical and direct application of these numbers for programming motion toward an arbitrary direction.

Preview 01:31

I provide here a brief connection for how the trigonometry numbers are used in math outside of games as another way to explain visualizing what result they achieve and why.

Understanding Why We Use Sin & Cos

Just tidying up, since there were aspects of the ball's bounce motion that don't relate to the car.

Clean Away Outdated Ball Code

Answering these questions is optional but recommended.

Section 8 Review
2 questions
Giving You the Car Keys
8 Lectures 12:27

In addition to setting up keys to let the player steer the car, this section also addresses other related aspects of motion, such as friction. and what to do when hitting a wall.

Section Introduction

Like mouse events these are set up in window.onload. Unlike mouse events, which listen for the canvas, keys listen for a relevant message from the document.

Functions on Key Press and Release

Of course these could be looked up, but they're easy to get locally, and it's good to know where these things come from.

Find the Key Code for Each Arrow Key

The keys at this phase only work by tapping, but they should affect the car's angle and speed.

Crude Steering and Gas on Key Presses

By storing hold state for each gameplay key you can treat keys in code more like buttons. Importantly, this means you can support much smoother drive, braking, and steering than could be done by typing.

Treat Keys More Like Buttons

Dampen the car's speed upon collision, rather than bouncing off walls with 100% of the speed brought into it. The way recorded in the video has a minor bug. As explained in the callout I added atop the video, this issue can be overcome by first subtracting the most recent movement prior to changing its speed.

Lose Speed From Driving Into Walls

When you take your foot off the gas a car should lose speed.

Slow Down Over Time

The map is laid out in a way that it'll work best for the cars to initially point north/up.

Fix Car's Start Direction

Answering these questions is optional but recommended.

Section 9 Review
2 questions
11 More Sections
About the Instructor
Chris DeLeon
4.7 Average rating
11,312 Reviews
94,079 Students
2 Courses
Independent Game Development Educator, 20 years making games

Hey! I live in an L.A. apartment with my fiancée Laura and our 3-year-old gray cat EDI. I've been making games for 20 years, including pro game design on console games for Electronic Arts, in casual web games at a Silicon Valley start-up, and indie mobile (including the #2 top ranked game in 2008). Before starting Gamkedo I taught game creation skills at Georgia Tech. On the side I organize IndieCade's workshops in L.A. and Paris, teach kids coding in Malibu, and do game developer outreach now with over 70 podcast episodes and over 50k YouTube subscribers.