How To Program Games

Learn to code tile-based worlds and related core gameplay for genres like arcade, overhead racing, and puzzle adventure.

Last updated 2022-01-10 | 4.7

- 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

What you'll 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

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

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

Who this course is for:

  • Anyone who wants to learn practical skills to program their own games at home
  • People who may already 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 further 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

Course content

21 sections • 168 lectures

Introduction to Your Course and Instructor Preview 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 Introduction Preview 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.

Create the HTML File Preview 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.

Proper HTML Header Preview 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.

JavaScript in HTML with Console Use Preview 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.

HTML5 Canvas with Setup Function Preview 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.

Draw Filled Rectangle and Circle Preview 02:11

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

Variable and Timed Updates for Motion Preview 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.

Modify Speed, Also for Vertical Motion Preview 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.

Reason for a Big Rectangle Each Frame Preview 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.

Separate the Motion and Draw Code Preview 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.

Make Functions for Fill Rect and Circle Preview 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.

Mouse-Controlled Horizontal Paddle Preview 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.

Reset Ball When It Goes Off Bottom Preview 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.

Move Paddle From Edge, Reflect Ball Preview 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.

Aim Based on Where Ball Hits Paddle Preview 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.

Section 1 Review

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 Introduction Preview 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.

Display Mouse Coordinate by Cursor Preview 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.

Set Up and Display the First Brick Preview 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.

Draw Multiple Bricks with Gaps Preview 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.

Vanish Individual Bricks Preview 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.

Renumber Bricks to Start at Zero Preview 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.

Using an Array for Bricks Preview 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.

How For() Can Loop on the Brick Array Preview 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.

Clearing Isolated Bricks in the Array Preview 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.

Label Deeply Stacked Closing Braces Preview 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.

Section 2 Review

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 Introduction Preview 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.

Display Tile Coordinate Near Mouse Preview 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.

Supporting Multiple Brick Rows Preview 03:03

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

Changing Brick "Count" to "Columns" Preview 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.

Support Removal of Each Brick Position Preview 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.

Make More Bricks, and Smaller Preview 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.

Compute Index From Row and Column Preview 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.

Remove Bricks Under Mouse Preview 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.

Remove Bricks Where the Ball Goes Preview 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.

Fix Edge-Wrap Collision Bug Preview 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).

Bounce Ball When It Hits Bricks Preview 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.

How to Start the Ball in the Center Preview 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.

Section 3 Review

Answering these questions is optional but recommended.

Section Introduction Preview 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.

Cutting Ball Code Into Functions Preview 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.

Understanding the Ball-Brick Side Test Preview 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.

Get the Ball Bouncing Off Brick Sides Preview 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.

Add Cheat to Reposition the Ball Preview 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.

Fix the Covered-Edge-Corner Case Preview 06:28

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

Section 4 Review

Answering these questions is optional but recommended.

Section Introduction Preview 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.

Keep Count of Bricks Remaining Preview 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.

Start with Empty Gutter at Top Preview 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.

Reset Ball at Start, Bricks After Last Hit Preview 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.

Reset Bricks When Player Misses Ball Preview 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.

Fix Bug with Hitting Bottom Bricks Preview 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.

Testing to Look for Remaining Bugs Preview 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.

Fixing the Ball-Stuck-Along-Edge Bug Preview 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.

Play Testing to Look for Bugs Again Preview 01:08

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

Section 5 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:16

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

Now Let's Tear This Up Preview 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.

Remove the Paddle Preview 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.

Rename "Brick" in the Code to "Track" Preview 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.

Stretch Tile Grid to Cover the Canvas Preview 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.

Design a Grid Layout by Hand Preview 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.

Quick Example of Grid Map Design Preview 01:01

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

Fill in a Basic Track Layout Preview 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.

Set Ball Start Location in the Array Preview 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.

Section 6 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:36

Time to create a bit of art.

How to Create the Car Image Preview 04:09

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

Turning on Headlights and Taillights Preview 02:43

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

Import and Display the Car Image Preview 03:14

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

Section 7 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:21

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

Replace "Ball" in Code with "Car" Preview 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.

Spin the Car Image Preview 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.

Drive the Car the Way It Faces Preview 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.

Use of Sine and Cosine for Games Preview 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.

Understanding Why We Use Sin & Cos Preview 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.

Clean Away Outdated Ball Code Preview 00:58

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

Section 8 Review

Answering these questions is optional but recommended.

Section Introduction Preview 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.

Functions on Key Press and Release Preview 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.

Find the Key Code for Each Arrow Key Preview 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.

Crude Steering and Gas on Key Presses Preview 01:43

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

Treat Keys More Like Buttons Preview 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.

Lose Speed From Driving Into Walls Preview 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.

Slow Down Over Time Preview 01:18

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

Fix Car's Start Direction Preview 01:09

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

Section 9 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:15

This section won't change what the code does, but it will change how it does so. Most importantly, you'll finally be breaking your project into multiple files!

Label Car Tuning Values Preview 01:17

As a general rule, leaving hard-coded numbers mixed into where they're used in the code makes it inconvenient to tune that value (takes digging) and harder to make sense of the code later.

Create Labels for Tile Types Preview 01:51

Before adding more types of tiles for the grid it'll help to clearly label the ones that are already in use.

JavaScript and HTML in Different Files Preview 01:55

Although the main goal is to break up the JS into multiple files, for starters just get the JS out of the HTML file.

Give Common Graphics Code a File Preview 01:06

By keeping generic graphics code in a separate file you make it easier to carry your discoveries forward to future projects,

Divide Code Into Files by Purpose Preview 07:14

Finally, your game code will be divided into files based on what the code gets used for. No more rooting around through unrelated code to find the part you're looking for.

Section 10 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:17

These tile graphics can bring a lot of atmosphere and style to what has so far been a very abstract space. In this section you'll draw and integrate a couple of them.

Draw the Road Tile Image Preview 00:58

The road texture is basically just a noise filter washed out in gray.

Create Wall Tile Art Preview 01:50

For the walls I use gradients in an effort to give them a little depth, to help reinforce that the player's car will be blocked by them.

Load Your Tile Art in Code Preview 00:56

For now these images can be loaded in a kinda quick and easy way. Later on you'll learn a more robust way to handle loading track art.

Display the Tile Images Preview 02:26

Drawing these images instead of the blue wall rectangles turns out to be a lot less work than the car since these tiles do not need to rotate.

Stop Drawing Giant Rect Every Frame Preview 00:57

Now that the whole screen gets covered over by track images each frame the big rectangle used to wipe the outdated graphics is no longer needed.

Section 11 Review

Answering these questions is optional but recommended.

Section Introduction Preview 01:08

There's a lot to this topic. The end result won't be visibly different, but knowing and doing these steps will make it easier for you to handle new pictures.

Bring Together All Image Code Preview 01:49

As with most clean up tasks, begin by pulling it all together so it can be dealt with all in one place.

Wait for the Last Image to Load Preview 03:13

Given there are multiple images to load a counter is more appropriate here than true/false boolean values.

Connect OnLoad Automatically Preview 01:43

Let's make this one less thing to worry about remembering to do each time.

Auto Count Images to Load: A Bad Way Preview 02:27

We don't want to have to keep a number manually in-sync with how many images the game is going to use. Games use a lot of images! The solution discussed here is tempting because it's intuitive, and it even often appears to work, but beware. It can lead to trouble.

Auto Count Images to Load: Good Way Preview 03:29

Here's a better way to achieve the same goals as the previous step was attempting. This is also a good example of ways to use object literals (data grouped by label) in arrays, which is a very flexible and convenient feature available in JavaScript.

Add a Basic Loading Screen Preview 01:48

We won't put time into making it fancy, but just having it there and working is a lot better than showing the player a blank screen while they wonder if it's going to start.

Section 12 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:22

A heads up that the next thing we're going to do is divide the files up into folders based on file type.

Divide Project Files Into Folders Preview 01:55

Making folders, moving files, and updating their references in code. Not much to it, but it'll save headaches later as the number of files involved continues to increase.

Create Images for New Track Tiles Preview 06:21

Here I'll show you how to draw art for the trees, goal line, and decorative flag markers.

Load New Track Images in Code Preview 01:45

The code needs a connection to the new image files to display them during play.

Put New Track Types in Level Grid Preview 01:02

These don't need to look good, just toss them anywhere so they can be tested.

Get New Tile Types to Block Car Preview 00:40

Where code used to test for "a tile type other than the road" that used to implicitly mean the same thing as "a tile type which is the wall" since there were only 2 kinds in use. Ensure that obstacle code gives the new obstacles the ability to block the car.

Show the Images for New Track Types Preview 03:13

You'll see how to go from an if-else pattern to a swtich-case. How this is being done at this stage will evolve again soon into an even better form.

Make a Layout Using New Tiles Preview 01:15

Now that the new tiles are working you can integrate them into your map layout.

Tune Car & Disallow Spinning in Place Preview 01:30

How well you can corner at low speeds may affect level design, so it's a problem that currently the cars can pivot in place. Here's the fix for that.

Section 13 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:29

This section is another one that won't affect the game much outwardly, but is still worthwhile for how it can speed up your working with the code and the code's time needed to do its thing.

Save All Track Tile Art to an Array Preview 04:10

Rather than put each track tile image into a separate variable let's group them into an array. Just as it did for the brick row earlier this can help reduce code reptition.

Draw Track Tile Based on Index Preview 01:25

Each tile type already is assigned to a unique number. Why not make that serve as the index into the track tile art array?

Optimizing the Track Draw Loops Preview 03:20

Although the game isn't likely hitting a performance issue on your machine, as an exercise this is an ideal spot in the code to pay attention to. The goal is to find simpler or faster ways to get the same outcome.

Section 14 Review

Answering these questions is optional but recommended.

Section Introduction Preview 01:20

You'll be creating a class for the car, since by doing so you can more easily add a second car.

Put Car's Vars and Functions in a Class Preview 03:11

No need to restart your car code, just wrap it up where it already is.

Update Use of Variables in the Class Preview 01:17

How the class values are referenced needs to be updated now that they're in a class.

(Note: JavaScript does support ways to hide variables and functions from the outside, but I've opted to ignore those here to keep things straightforward for people who are just getting started.)

Create Player One's Car Instance Preview 02:57

Look for places in the code where the code action has been happening and instead call it on your car instance.

Make a Second Car for Player Two Preview 02:20

Getting a second car is actually pretty easy at this point. Much of the trouble will be on getting it set up to use different input.

Copy and Recolor Blue Car to Green Preview 01:37

Very minimal art demonstration this time, since it's just changing the paint job on the car.

Import and Use the Green Car Image Preview 02:05

Cars will now keep track of which graphic they're each supposed to use.

Use Different Control Keys Per Car Preview 08:05

This involves writing a bit of additional support functionality.

Keys will be WASD for player 2 and arrow keys for player 1. Feel free to map these to different controls if you'd prefer (or have a non-English keyboard etc.).

Section 15 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:16

You're almost to the end of he Racing project!

Decrease Time to Test the Finish Line Preview 00:33

Either tear down a wall in the way or put up a new goal line near where you start. You shouldn't need to drive the full track each time you test this feature.

Vary Consequences by Tile Type Hit Preview 02:05

For the goal type to reset the level some code has to be rearranged so that player cars can do more in response to a tile type than bouncing off.

Assign Each Car a Unique Name Preview 00:57

These names are so that the winner can be distinguished. For now these wil only appear on the console, so make sure you have your console open in-browser.

Declare Winner When Goal is Reached Preview 00:41

Putting those new names to good use.

Understanding the Problem with Reset Preview 01:35

Unfortunately there's no built-in "restart" game function, aside from fully reloading the page. The latter sounds too drastic, and isn't very flexible. We'll need to write our own reset functionality.

Separate Active Map From Saved Layout Preview 03:14

Keep both a master copy of the level and a scratch copy for making changes to during load or play. This sets you up to reset by simply copying the master back over the scratch version.

Reset When Finish Line is Reached Preview 00:48

With the master and scratch level arrays set up now it's a matter of making the copy when either player reaches the finish line.

Reset Car Speed When Map Reloads Preview 00:54

Since upon reset it's still exactly the same cars they'll likely carry momentum with them. Zero out their speed as part of their reset functionality.

How to Support Multiple Level Maps Preview 00:45

In the attached solution code I've included a couple of example map layouts along with a little extra code to make them cycle to next each time either player wins a race.

Racing Game Wrap-Up Preview 00:46

Congratulations! You've completed the Racing project!

Section 16 Review

Answering these questions is optional but recommended.

Section Introduction Preview 00:54

It's time for you to begin grappling with more of the details. I'll demonstrate what the transformation will look like each step of the way, and offer clues of what to do, but I'll no longer be showing exactly what to type. If you get stuck or want to see my solution (only one of many possibly ways to do several of the steps) you're welcome to download the attached example code.

Start with Racing Source Minus Player 2 Preview 00:33

The adventure game will be single player, so just drop the player two green car instance.

Rename files and variables Preview 00:26

Any time you change how code gets used you should probably change how it's named to be consistent with its usage.

Rework Drive Motion Into Walking Preview 00:38

Simple addition and subtraction to the x-axis or y-axis produces walking. This much is simpler than car steering.

Enlarge Tiles to Bring Camera Closer Preview 00:23

This is mainly about resizing the images and adjusting a few constants, you shouldn't need to change much in the code's logic.

Replace Racing Art with Dungeon Art Preview 00:37

This step looks like a big progress step, but doesn't accomplish much functionally. It's a good idea to rename the image files to reflect what they depict, so you will also need to update those filenames referenced by the image loading code.

You can find the art I'm using attached within the example solution steps.

Support Partially Transparent Tiles Preview 00:57

You don't want to have to redo a bunch of tiles every time you want to make a change to your floor. You can just have the game draw the floor under partially transparent tiles when those get reached during the nested grid draw loops.

New Layout and Code for Keys & Doors Preview 02:16

The race track doesn't really fit well for this kind of game. Make something more like an interior, or if you've made your own art it might instead be a cave or forest.

Also: hook up keys and doors. They're really great additions to games but really don't have to be very complicated at a technical level.

Adventure Core Wrap-Up Preview 00:18

You've got a good foundation started! Perhaps you may want to combine this project with the scrolling camera technique covered in the final section's examples?

Section 17 Review

Answering these questions is optional but recommended.

Section Introduction Preview 01:26

Grids are used for so many kinds of games, they're not even all shown or covered here. For example many puzzle games (not represented here) also take place in grid data.

Many Balls in Grid Preview 01:50

Possibly of interest here, besides that it has so many moving objects at once, is how the hundreds of objects are being piled into an array when the program starts. A similar technique can be used to populate an array of instances of anything - particles, projectiles, enemies, etc.

Scrolling Camera Preview 03:13

While this environment isn't huge part of what makes the grid good for scrolling spaces is that the size of the environment doesn't have to have any effect on performance. Only the tiles on-screen and at the edges of the screen need to be drawn, and that number stays the same no matter how huge the scrolling world is.

Side View Platform Jumper Preview 02:18

Multiple collision tests points on an object, with each handling the collision event differently, is yet another way to put these concepts to work.

Remember too that the world doesn't have to have such obvious dark grid lines showing where each tile starts and stops, those were manually added during development. A nice tile art set will often attempt to minimize seams. While still in simple colored shapes for prototyping though you can create a more solid effect by removing the gap/margin between tiles.

Moving Grid with Collision Gaps Preview 01:50

For games where an enemy periodically leaves the formation you can think of it as temporarily clearing its entry in the grid data, spawning a temporary independent enemy (or recycling one of a handful the game keeps reusing), then reinserting it back into the array if it survives its attack trip.

Board Game with Mouse Control Preview 02:58

I totally put the Knights in the wrong place. Whoops. Having not added graphics made this error tougher to spot since the text blended together. I've fixed their positions in the attached solution code.

Course Wrap-Up Preview 00:29

Congratulations! You've made it to the end of the video! If you'd like more material and example source code to tinker with stick around for your full book PDF which has many exercises about these games as well as details on a few others.

Section 18 Review

Answering these questions is optional but recommended.

Bonus Section: What to Do Next (HomeTeamGameDev.com Member Examples) Preview 12:25

Here are some real games developed by people as a next step project after taking this course. In addition to demonstrating some level-appropriate games you're ready to take on based on what you've learned, I also suggest in this video a handful of additional game programming concepts to explore. If you'd like to take your game development to the next level faster, better, and sooner with the help of teammates and one-on-one mentorship or project troubleshooting from industry professionals you can apply to join at https://HomeTeamGameDev.com (formerly known as Gamkedo Club)

Full Included PDF Textbook: Hands-On Intro to Game Programming Preview 560 pages

Enjoy!

Your purchase of this course fully includes any future updates I may make to this book and its example code. Any major updates will be distributed free to all students of this course via a Udemy email announcement.