Points
In this lesson, you will apply what you've learned about JavaScript proxy to award points for various events in the game.
We'll cover the following
To add a bit more excitement to our game, we need to have some kind of points system. Most games award points to the player for completing various tasks.
Point system
The scoring formula for Tetris is built on the idea that more difficult line clears should be awarded more points. For example, a single line clear in Tetris is worth 100 points, clearing four lines at once (known as a Tetris) is worth 800.
Tetris games also allow the player to press a button to increase the speed of the current piece’s descent or cause the piece to drop and lock into place immediately. These are known as a “soft drop” and a “hard drop,” respectively.
We can award some points based on the height that the piece fell before locking, and which drop was used.
With these guidelines, we set these values as our points system:
const POINTS = {
SINGLE: 100,
DOUBLE: 300,
TRIPLE: 500,
TETRIS: 800,
SOFT_DROP: 1,
HARD_DROP: 2
}
Object.freeze(POINTS);
Proxy
To keep track of the game progress, we add an accountValues
object with the score and the lines that we have cleared:
// main.js
let accountValues = {
score: 0,
lines: 0
}
To act on changes to the account object, we can create a proxy object. Then, we run the code to update the screen in the set method. We send in the accountValues
object as the target to the proxy since this is the object we want to have custom behaviors on:
// main.js
let account = new Proxy(accountValues, {
set: (target, key, value) => {
target[key] = value;
updateAccount(key, value); // TODO
return true;
}
}
Now, every time we call the properties of the proxy account
, we call the updateAccount()
function to update the game score or lines on the screen depending which key we get as input:
// main.js
function updateAccount(key, value) {
let element = document.getElementById(key);
if (element) {
element.textContent = value;
}
}
So, if the key
is “score,” we get its DOM element and update its textContext
to the value
provided.
Drops
Let’s continue perfecting our point system by adding the scores for soft and hard drops in our event handler:
// main.js
if (event.keyCode === KEY.SPACE) {
while (board.valid(p)) {
board.piece.move(p);
account.score += POINTS.HARD_DROP;
p = moves[KEY.DOWN](board.piece);
}
} else if (board.valid(p)) {
board.piece.move(p);
if (event.keyCode === KEY.DOWN) {
account.score += POINTS.SOFT_DROP;
}
}
Now, every time we hit the down key, we get one point. When we hit space for a hard drop, we get two points for every line that the piece drops until it settles.
Line clear
For the line clear points, we define the points depending on the number of lines that are cleared at once:
// board.js
getLineClearPoints(lines) {
return lines === 1 ? POINTS.SINGLE :
lines === 2 ? POINTS.DOUBLE :
lines === 3 ? POINTS.TRIPLE :
lines === 4 ? POINTS.TETRIS :
0;
}
Notice that we don’t have any logic for how many lines are cleared at one time. Let’s add the logic to count how many lines we clear in our clearLines
method:
// board.js
clearLines() {
let lines = 0;
this.board.forEach((row, y) => {
if (row.every(value => value !== 0)) {
lines++; // Increase for cleared line
this.board.splice(y, 1);
this.board.unshift(Array(COLS).fill(0));
}
});
if (lines > 0) {
// Add points if we cleared some lines
account.score += this.getLineClearPoints(lines);
}
}
If we try playing now, we can see that we are increasing our score. What we need to keep in mind is that whenever we want something to show up on the screen, we need to go through the proxy instead of directly to the account object.
Now that we can count our score, we should increase the difficulty as the game progresses and be able to score even more points! Let’s look at that next lesson.
Get hands-on with 1400+ tech skills courses.