Over a million developers have joined DZone.

# 3D Tetris with Three.js Tutorial – Part 5

· Web Dev Zone

Comment (0)

Save
{{ articles[0].views | formatCount}} Views

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

In the fifth part of tutorial we add some final polish to the game.

## Completed slices and score counting

This function will be quite long but simple. To check if a slice is completed I calculate the maximum number of occupied fields and check every slice (moving on z-axis) if it’s full. This way I can change size of the board and this function should be still working. Try to think about all your functions in such way – if something may ever change, make your code flexible.

```Tetris.Board.checkCompleted = function() {
var x,y,z,x2,y2,z2, fields = Tetris.Board.fields;
var rebuild = false;

var sum, expected = fields[0].length*fields.length, bonus = 0;

for(z = 0; z < fields[0][0].length; z++) {
sum = 0;
for(y = 0; y < fields[0].length; y++) {
for(x = 0; x < fields.length; x++) {
if(fields[x][y][z] === Tetris.Board.FIELD.PETRIFIED) sum++;
}
}
// to be continued```

When the slice is full, we should remove it and shift all the following slices. To make sure that we don’t skip a shifted slice we decrease z once. To make the game more interesting, bonus points are granted if there are multiple slices completed at once.

```  if(sum == expected) {
bonus += 1 + bonus; // 1, 3, 7, 15...

for(y2 = 0; y2 < fields[0].length; y2++) {
for(x2 = 0; x2 < fields.length; x2++) {
for(z2 = z; z2 < fields[0][0].length-1; z2++) {
Tetris.Board.fields[x2][y2][z2] = fields[x2][y2][z2+1]; // shift
}
Tetris.Board.fields[x2][y2][fields[0][0].length-1] = Tetris.Board.FIELD.EMPTY;
}
}
rebuild = true;
z--;
}
}
if(bonus) {
}```

Now, even though we dealt with board information, we still have to make changes to Three.js geometries. We couldn’t do it in previous loop as it could rebuild the geometries twice or even more if multiple slices were completed at once. This loop checks every Tetris.Board.fields with corresponding Tetris.staticBlocks adding and removing geometries where needed.

```  if(rebuild) {
for(var z = 0; z < fields[0][0].length-1; z++) {
for(var y = 0; y < fields[0].length; y++) {
for(var x = 0; x < fields.length; x++) {
if(fields[x][y][z] === Tetris.Board.FIELD.PETRIFIED && !Tetris.staticBlocks[x][y][z]) {
}
if(fields[x][y][z] == Tetris.Board.FIELD.EMPTY && Tetris.staticBlocks[x][y][z]) {
Tetris.scene.removeObject(Tetris.staticBlocks[x][y][z]);
Tetris.staticBlocks[x][y][z] = undefined;
}
}
}
}
}
};```

## Audio API

```<audio id="audio_theme" src="music/tetris.mp3" preload="auto"></audio>

Using these files in JS is also easy. First create an object to store your sounds:

```// before Tetris.init()
Tetris.sounds = {};```

To call Audio API we have to retrieve these DOM elements.

```// in Tetris.init()
Tetris.sounds["theme"] = document.getElementById("audio_theme");
Tetris.sounds["collision"] = document.getElementById("audio_collision");
Tetris.sounds["move"] = document.getElementById("audio_move");
Tetris.sounds["gameover"] = document.getElementById("audio_gameover");
Tetris.sounds["score"] = document.getElementById("audio_score");```

There are numerous methods and you can create you own audio player but for our purposes play() and pause() is enough. You can probably guess where you should add the music

• Tetris.sounds["theme"].play() – in Tetris.init(), right after initialization of sound object.
• Tetris.sounds["theme"].pause() – in Tetris.start().
• else {Tetris.sounds["move"].play();} – in Tetris.Block.move(), if there is no ground collision.
• Tetris.sounds["collision"].play(); – in Tetris.Block.move(), if there is a ground collision.
• Tetris.sounds["gameover"].play(); – in Tetris.Block.generate(), where we test for the lost game.

## The end

That’s all folks! Our Tetris is fully functional now. I hope it was a fun way to learn Three.js. There are many topics like advanced geometries, shaders, lights, skeletal animation, etc., that were not covered here. I just wanted to show that to create a game they’re not always needed. Actually, the best fun I’ve ever had was with games like Tetris, where gameplay was not directly related to the graphics quality. Obviously, great games often comes with great looks, but if you are not having fun from the first to the last minute, not even the best graphics can help.

If you liked the series, please share and comment. If you want to learn more, you should probably use pure WebGL from now on. You may start with this tutorial. Check also "Building the game" by Brandon Jones.

## After this tutorial you should:

• Know how to detect and manage completed slices.
• Know basics of Audio API.
• Know how to have fun.
• Start writing your own game.

If you have trouble with any of these, check tutorial again or ask a question in the comments below.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Comment (0)

Save
{{ articles[0].views | formatCount}} Views

Published at DZone with permission of Sebastian Poręba, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

SEE AN EXAMPLE