This topic explains how to detect collisions between your vehicle and other objects on the screen.
This code sample covers the following tasks that demonstrate the basic principles of using Canvas to detect the color of different objects:
- Drawing asteroids and a home base with specific colors for later detection
- Taking snapshots of what is in front of the spaceship
- Scanning snapshots for colored objects and displaying messages
At the end of the code sample is discussion material that explains more about the design and structure of these tasks and how they work.
Note The code in this sample builds upon the code in the previous sample.
This section explains the design and structure of this code sample. It will tell you about the different parts and how they fit together. The Canvas sample uses a standard HTML5 header, <!doctype html>, so that browsers can distinguish it as part of the HTML5 specification.
This code is divided into two major parts:
- Body Code
- Script Code
The body code is the same as in the Moving Your Vehicle topic.
The script code contains several blocks of code from the Moving Your Vehicle topic. However, it modifies almost every block and adds several new ones. The script code of this sample consists of the following:
- canvasSpaceGame function
- stars function
- makeShip function
- whatKey function
- collideTest function
- drawAsteroids function
Global variables are called when the page loads. The canvasSpaceGame function is called from the body tag onload attribute. The rest of the functions are called from the canvasSpaceGame function.
This is nearly the same as the the second task of this scenario, "Moving your vehicle." The only modification is to add a call to the drawAsteroids function, which draws the asteroids and the home base on the screen.
This is almost the same as the stars function in the second task of this scenario, "Moving your vehicle." The only difference is that the star color is given a different color value. In the stars function from the second task of this scenario, "Moving your vehicle,, the star color was “white”. (The four-byte value is 100% red, blue, green, and alpha, or “#FFFFFF”.) But in this task, the stars are given the color value of “#EEEEEE”, which is almost white (the four byte values are 94% red, green, blue, and alpha). This looks the same as white because it displays only a hint of color. It is necessary to display a hint of color when scanning the screen for collision detection, because using pure white causes problems. When you are scanning for collisions and looking for an object that is 100% red, you might get a false positive for a white star, because a “white” star has 100% red in it.
Working with precise percentages of red, green, blue, and alpha will allow you to do very accurate and subtle collision detection. This is very important because almost all arcade games require collision detection in their game play. Another benefit of using precise colors is you can keep the snapshot size small and perform quick scans for color values, making for even faster collision detection.
This is the same as the makeShip function in the second task of this scenario, "Moving your vehicle." The only difference is that a 30x30 pixel snapshot of the ship is saved to the ship image for later use.
This function has nearly the same code as the whatKey function in the second task of this scenario, "Moving your vehicle." The only difference is that a call to collideTest is added after all the key events are processed. This is because every time a key is pressed, a collision is possible, so you should see what happened. Until the ship moves, you do not need to waste cycles detecting collisions, because in this game, nothing else moves.
This new function determines if the ship has collided with an asteroid or the home base. It does this in two steps. The first step is to take a snapshot of the screen at the point where the ship is about to move. This location has already been calculated by the whatKey function. The snapshot data is a simple linear array of four-byte color values, starting at the upper left-hand corner and continuing from left to right in rows, and continuing each row until the lower right-hand corner. The size of the array is 4 (for the 4-byte color value) times the length times the width. For a 20 x 20 snapshot, the size would be 4 x 20 x 20 or 1,600.
The second step is to scan through the snapshot data, four bytes at a time. You are looking to see if a 100% red value (255) is in the first byte. If you find it, an asteroid is present. You are also looking to see if a 100% blue value (255) is in the third byte. If it is, you have landed on the home base. We don’t care about the second and fourth bytes in this example, because you’re not looking for green or alpha. If a 100% red value is in the first byte, an alert box is displayed telling you that you have encountered “red”. Similarly, if a 100% blue value is in the third byte, an alert box tells you that you have hit “blue.” In the next task of this scenario, you learn how hitting red or blue ends the game, but in this task of the scenario, you can continue after you close the alert box.
This simple task of taking a snapshot and scanning the data for specific bytes of color can be very effective for detecting collisions. Large snapshots might not be efficient, but careful design of your art can make it fast and easy to detect objects on the screen. Scanning a 1,600 byte array every time you press the key is very quick.
In order to read or write colored pixels on the screen, each pixel must be assigned a color value. This value consists of four parts: red, green, blue, and alpha. For example, a white pixel is made up of 100% red, 100% green, 100% blue, and 100% alpha. (Alpha refers to the amount of transparency a color displays.) Each canvas pixel color value is stored as a four-byte array. The four bytes correspond to the percent of red, green, blue, and alpha in each pixel. (Bytes range from 0 to 255 for decimal numbers and from #0 to #FF in hexadecimal.) For more informations about the names and numeric values of specific colors, see
Web designers typically use color names (“red”) or hexadecimal values (“#FF0000”) to define colors. Canvas uses those notation systems but also uses the rgb function to indicate the first three bytes of color, or the rgba function if you need to define the alpha value. If the alpha is not defined, it is assumed to be 100%. For example, red would be rgb(255,0,0). Be aware that the rgb function was used to define colors when you drew the original ship earlier in this topic using the makeShip function.
The code in this sample shows you how Canvas uses immediate mode to read pixel colors to detect collisions between objects. Canvas does this by reading a block of pixels on the screen and determining which parts of the block contain a particular color value. For example, if you want your game program to know if a red asteroid is near your ship, you can take a snapshot of the screen and scan it to determine if it contains red. If it does, your program knows that an asteroid is present. As a result, the program is now prepared to react to the player’s action. If the player bombs the asteroid, it blows up. If the player crashes into the asteroid, the player’s spaceship blows up.
This is a new function. It is very similar to the stars function in the second task of this scenario, "Moving your vehicle." The drawAsteroids function uses the same logic as the stars function but makes the size of each asteroid larger in the Canvas arc method and makes the fillStyle “#FF0000”, which is pure red. Defining the color ensures that the collision detection routine, when it looks for 255 in the first byte of the color value in the collideTest function, will always find “red”. The drawing loop makes sure that the asteroids are not too close to the starting location of the ship or the home base. If the asteroids are drawn too close to either, the loop does not draw an asteroid, the count is increased, and the loop cycles an extra time.
The drawAsteroids function also draws the blue base. It uses the color value of “#0000FF”, which is pure “blue.” The base is a simple rectangle.
Build date: 12/13/2013