Creating a 3D Tetris Game for Dummies Like Me — IX
TL;DR: live demo or the advanced game + some shameless advertising wrapper.
Level: for beginners.
See detailed links and table of contents at the bottom of the article.
Post-production time. Today I’m going to add sound effects and polish the styles.
The sound effects in HTML5 are very simple. However, I will do it even simpler and use 3r-party: HowlerJS. Let’s install:
npm i -S howler
and import to use:
// App.svelte
import {Howl} from 'howler';
And I’m going to try adding the very first effect, the startup call. First, I need to have the sound… Pixabay! A lot of them. I selected a few and saved them to a public
folder.
Then, use:
// App.svelte
...
let isDropDown = false;
// sound effects
const startSound = new Howl({
src: ["./start.mp3"],
});
const tickSound = new Howl({
src: ["./tick.mp3"],
});
const newSound = new Howl({
src: ["./new.mp3"],
});
const clickSound = new Howl({
src: ["./click.mp3"],
});
const thudSound = new Howl({
src: ["./thud.mp3"],
});
const tadaSound = new Howl({
src: ["./tada.mp3"],
});
...
function startGame() {
if (started || gameOver) {
return;
}
if (sound) {
startSound.play();
}
...
}
And repeat such piece–
sound && startSound.play();
...
sound && thudSound.play();
...
everywhere. On move, on drop, on remove lines, on start new level…
Next step: I wand to improve the Banners
.
Firstly, it turned out that it is more convenient to switch steps using the spacebar
, and not any key
. So, I replace the texts…
<p>press Space to start</p>
and code in keyboard processing.
// App.svelte
function processKeysDown(ev) {
let e = ev.key;
if (!started) {
// "space" on not started -> to start game
if (e === "Space" || e === " ") {
startGame();
}
return;
}
if (gameOver) {
// "space" on game over -> to not started
if (e === "Space" || e === " ") {
waitGame();
}
return;
}
...
}
Then I tune overall game backgrounds, paddings for banners and styles:
<style>
#pause-banner {
position: absolute;
top: 60px;
left: 60px;
right: 60px;
bottom: 60px;
border-radius: 20px;
box-shadow: 0 10px 60px rgba(0, 0, 0, 0.8);
opacity: .97;
border: 1px solid rgba(255, 255,255, .2);
display: flex;
flex-flow: column nowrap;
align-items: center;
justify-content: center;
background: linear-gradient(to bottom right, #00b912, #1d8e01);
}
</style>
Now it looks like:
Next steps: proportions to make the main box a bit bigger, colors, background… and this is the final design:
Last minute bonus level progress bar:
<div id="level-progress">
<span style="width:{linesRemovedOnLevel * 10}%" />
</div>
#level-progress {
width: 100px;
height: 4px;
display: flex;
background-color: rgba(0, 0, 0, 0.2);
margin-top: 30px;
}
#level-progress span {
background-color: #ffa600;
height: 100%;
transition: all 1s ease;
}
Last but not least. To publish the result somewhere, this time on GitHub Pages, I need to make a couple of changes. Otherwise, it will show a white screen and swear that resources are not available.
First, index.html
: add <base href=”./”/>
to head:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<base href="./"/> <!-- this one -->
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tetris 3D</title>
</head>
<body>
...
The second, add the same to vite.config.ts
:
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
base: './' // <-- add this one
})
What result?
- Introduction to ThreeJS. Basic 3D objects, materials, scenes. Compositions and hand-made animations.
- An introduction to game design, even something as simple as this: main loop, states, controls…
- Basic sound effects.
It ain’t much, but it’s honest work.jpg.
A breath of fresh air after CRUD, REST, Scrum… at least I am satisfied with all this drive and inspiration. And maybe someone will come in handy — this will be the best result.
Of course, there are a lot of things that need to be improved, ranging from the style of the code (I hardly cared about proper code splitting for simplicity) to the game design. Like adding some animations you can see here.
It’s up to you.
And now you have everything to start creating, I’m not afraid to say, Arkanoid! Or Sokoban! Or Halo… well, not this one, yet.
All the parts on Medium:
- Introduction and setting up the environment.
- My first 3D object.
- Next 3D figure: character generator and bitmap fonts.
- Keyboard Help 3D component: embossing SVG curves.
- Game field. Auto-adjusting Camera to the field.
- Life cycle and states. Banners. Time-based animations.
- Let it fall: almost live. Active game field, Two-phased turns.
- Gameplay as it is. Catch, move and rotate.
- Sounds and Tuning it up. ← you are here
Relevant parts on GitHub:
- https://github.com/lexey111/tetris3d-stage-0
- https://github.com/lexey111/tetris3d-stage-1
- https://github.com/lexey111/tetris3d-stage-2
- https://github.com/lexey111/tetris3d-stage-3
- https://github.com/lexey111/tetris3d-stage-4
- https://github.com/lexey111/tetris3d-stage-5
- https://github.com/lexey111/tetris3d-stage-6
- https://github.com/lexey111/tetris3d-stage-7
- https://github.com/lexey111/tetris3d-stage-8 ← you are here