Tetris in HTML5 for Noobs: Part 7 – Basic Collision Detection

Now that we have a game state grid variable, we can use it to implement basic collision detection. We want to prevent moving the current game piece into any existing tetriminos or off the grid boundary. To do this, we need to modify the setGrid function so that it can check to see if a grid cell is empty. We already use the t parameter to indicate the block type, or if we want to clear the cell, so we can also use it to indicate that we only want to check the value without actually returning anything. We’ll use a value of -1 to indicate that we are performing a check, and a value of 0 or greater to actually modify the grid. The return statement tells the JavaScript interpreter to immediately exit the function and to return a specific value to the calling function. We’ll see how that works in a minute. Modify the setGrid function to look like this:

You may notice that I’ve used a one-line if statement. This is a compact way of writing the code that doesn’t use curly braces, but only works for a single statement.

The setGrid function is only called in the drawTetrimino function, so we need a way to check the returned value. Again, we’ll modify this function to accept a d parameter of -1 to only perform a drawing test, and then return either true or false. This means that we use a d value of 1 to draw, 0 to erase, and -1 to test. We can obtain the proper value to send to each setGrid function call with the following code:

Now we need a way to check if all the setGrid function calls returned true. We want drawTetrimino to return true only if all of the setGrid functions return true, otherwise it should return false. To do this, we’ll use the logical AND operator, represented as && in JavaScript. We start with a variable valid initialized to true.

After each call to setGrid, valid is set to it’s current value ANDed with the value returned from setGrid.

This returns true only if both values were true, effectively setting valid to false if any of the setGrid calls return false. At the end of the function, we return the valid variable.

The last thing we need to do to implement collision detection is actually perform the check each time before we update the current position. I’ve modified the keyDown function to perform these extra checks.

For each of the possible key presses, we first erase the existing tetrimino, and then create a temporary variable with what the new position would be. We check to see if this position would be valid, and if so, we commit the change to the position variables. The exception is the general case when we create a new tetrimino. Here, we don’t erase the last tetrimino and only update the position variables if they produce a tetrimino with no collisions. Finally, we draw the tetrimino with the new position variables and call the drawGrid() function to redraw the canvas.

An addition feature I’ve included in the keyDown function is the space-bar drop. In this case, we use a while loop to continuously decrease the y coordinate until the check returns false. Similar to a for loop, a while loop will execute the contents of it’s block (in our case a single line) as long as its condition is true. The complete code should now look like this:

We’ll be making some more changes to this function in the future as we begin to implement game logic. If we play the game now, we can stack the blocks and notice that we can’t move over existing pieces, but the game doesn’t work by itself yet. We need to make the block drop by itself and clear lines when they are complete. We’ll look at this next time when we add game logic.

Updated: February 11, 2015 — 9:48 am

2 Comments

Add a Comment
  1. Hi, I’m struggling with the setGrid function, I don’t understand how the line if(t < 0) return grid[y][x] == 0; is used to test whether the grid location is occupied or not.

    Can you help.

    Thanks

    Ken

    1. The grid array is set up to store the block type at each grid location. A value greater than zero indicates that a block is present, while a value of zero indicates that the location is empty. The setGrid function can be used to either assign the value of t into the grid array if t >= 0, or check if a location is empty if t < 0. When t < 0, it indicates that we only want to return whether or not we can safely add a block in this location. This is true only if the value of grid[y][x] == 0. Perhaps it would have been clearer to use a separate variable or function to indicate whether we want to check or modify the grid array.

Leave a Reply to Drew Cancel reply

Your email address will not be published. Required fields are marked *

DrewBuck.com © 2015 Frontier Theme