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.7 (270 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.
1,939 students enrolled Bestselling in JavaScript
$19
$45
58% off
Take This Course
  • Lectures 150
  • Length 14 hours
  • Skill Level Intermediate Level
  • Languages English
  • Includes Lifetime access
    30 day money back guarantee!
    Available on iOS and Android
    Certificate of Completion
Wishlisted Wishlist

How taking a course works

Discover

Find online courses made by experts from around the world.

Learn

Take your courses with you and learn anywhere, anytime.

Master

Learn and practice real-world skills and achieve your goals.

About This Course

Published 9/2015 English

Course Description

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

What are the requirements?

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

What am I going to get from this course?

  • 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

What 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

What you get with this course?

Not for you? No problem.
30 day money back guarantee.

Forever yours.
Lifetime access.

Learn on the go.
Desktop, iOS and Android.

Get rewarded.
Certificate of completion.

Curriculum

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!

Section 1: Ball with Mouse Paddle - Warm-Up and Review
00:46

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.

01:04

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.

02:44

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.

00:56

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.

01:45

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.

02:11

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

02:04

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.

02:09

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.

01:30

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.

01:02

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.

02:37

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.

05:00

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.

01:09

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.

03:51

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.

04:11

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.

7 questions

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 2: Row of Removable Bricks
00: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.

03:39

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.

01:42

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.

01:50

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.

02:03

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.

01:46

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.

02:40

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.

03:48

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.

01:38

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.

00:54

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.

2 questions

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 3: Ball-Brick Grid Collision
00:29

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.

03:08

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.

03:03

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

00:45

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.

04:07

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.

01:53

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.

02:19

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.

02:14

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.

01:32

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.

01:55

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

01:16

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

01:08

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.

2 questions

Answering these questions is optional but recommended.

Section 4: Advanced Ball Collision
00:25

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.

01:58

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.

03:37

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.

03:53

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.

01:46

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.

06:28

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

2 questions

Answering these questions is optional but recommended.

Section 5: Finish Brick Gameplay
00:26

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.

02:14

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.

02:11

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.

01:32

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.

00:43

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.

03:43

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.

00:33

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.

01:46

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.

01:08

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

2 questions

Answering these questions is optional but recommended.

Section 6: Adapt the Grid for Racing
00:16

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

00:42

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

00:39

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.

01:16

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.

00:59

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.

04:31

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.

01:01

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

01:51

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.

03:26

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.

2 questions

Answering these questions is optional but recommended.

Section 7: Draw and Code an Image
00:36

Time to create a bit of art.

04:09

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

02:43

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

03:14

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

3 questions

Answering these questions is optional but recommended.

Section 8: Spin and Angled Motion
00:21

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

01:11

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.

02:21

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.

01:16

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.

01:31

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.

00:48

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.

00:58

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

2 questions

Answering these questions is optional but recommended.

Section 9: Giving You the Car Keys
00:56

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.

01:15

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.

01:05

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.

01:43

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

04:16

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.

00:45

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.

01:18

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

01:09

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

2 questions

Answering these questions is optional but recommended.

Section 10: Break to Get Organized

Students Who Viewed This Course Also Viewed

  • Loading
  • Loading
  • Loading

Instructor Biography

Gamkedo Game Development Coach Chris DeLeon, Independent Game Development Educator, 18 years making games

My background in professional game development includes console (for EA: level design for Boom Blox, technical game design for Medal of Honor Airborne), gameplay and engine design for a Silicon Valley start up, top-ranked indie iPhone/iPad games, and prototyping for Will Wright's Stupid Fun Club. I taught game development skills at Georgia Tech as a PhD student before I began teaching independently through Gamkedo LLC. Outside of professional applications I've developed over 90 freeware games, including serving as the engine and gameplay programmer for Vision by Proxy Second Edition which reached over 7 million players. Since then I've redirected my mission to helping more people begin their - your! - journey into making games.

Ready to start learning?
Take This Course