
Adicionar e remover classes CSS com Vanilla Javascript
Adicionar e remover classes CSS com JQUERY é uma atividade muito simples, mas também através do javascript puro conseguimos o... Leia mais
Desenvolvedor de Software
E vamos a mais um tutorial de outro joguinho clássico só que dessa vez vamos recriar o Tetris.
Link do repositório: https://github.com/paulodm145/tetris
/projeto-tetris
│
├── index.html
├── styles.css
└── script.js
Este arquivo contém a estrutura básica da página do jogo.
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<title>Tetris</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="tetris-container">
<div id="score">Pontuação: <span>0</span></div>
<div id="tetris"></div>
<div class="buttons">
<button id="restart">Reiniciar</button>
<button id="pause">Pausar</button>
<button id="reset-score">Zerar Pontuação</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
#tetris
), a exibição da pontuação e os botões de controle.Este arquivo contém os estilos do jogo.
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #e0e0e0;
font-family: Arial, sans-serif;
margin: 0;
}
#tetris-container {
display: flex;
flex-direction: column;
align-items: center;
}
#tetris {
width: 300px;
height: 600px;
border: 2px solid #333;
background-color: #fff;
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: repeat(20, 1fr);
gap: 1px;
margin-bottom: 20px;
}
#tetris div {
background-color: #f0f0f0;
box-sizing: border-box;
}
#score {
font-size: 1.5em;
color: #333;
margin-bottom: 10px;
}
#score span {
font-weight: bold;
}
.buttons {
display: flex;
gap: 10px;
}
button {
padding: 10px 20px;
font-size: 1em;
color: #fff;
background-color: #007bff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #0056b3;
}
Este arquivo contém a lógica do jogo de Tetris.
document.addEventListener('DOMContentLoaded', () => {
const grid = document.querySelector('#tetris');
const width = 10;
let timerId;
let score = 0;
const colors = ['orange', 'red', 'purple', 'green', 'blue'];
// Criar a grade e preencher com divs
function createBoard() {
for (let i = 0; i < 200; i++) { // 200 divs para o tabuleiro
let square = document.createElement('div');
grid.appendChild(square);
}
for (let i = 0; i < 10; i++) { // 10 divs para a linha de base
let square = document.createElement('div');
square.classList.add('taken');
grid.appendChild(square);
}
}
createBoard();
let squares = Array.from(grid.querySelectorAll('div'));
const scoreDisplay = document.querySelector('#score span');
let nextRandom = 0; // inicialização correta de nextRandom
// Os Tetrominos e suas rotações
const lTetromino = [
[1, width+1, width*2+1, 2],
[width, width+1, width+2, width*2+2],
[1, width+1, width*2+1, width*2],
[width, width*2, width*2+1, width*2+2]
];
const zTetromino = [
[0, width, width+1, width*2+1],
[width+1, width+2, width*2, width*2+1],
[0, width, width+1, width*2+1],
[width+1, width+2, width*2, width*2+1]
];
const tTetromino = [
[1, width, width+1, width+2],
[1, width+1, width+2, width*2+1],
[width, width+1, width+2, width*2+1],
[1, width, width+1, width*2+1]
];
const oTetromino = [
[0, 1, width, width+1],
[0, 1, width, width+1],
[0, 1, width, width+1],
[0, 1, width, width+1]
];
const iTetromino = [
[1, width+1, width*2+1, width*3+1],
[width, width+1, width+2, width+3],
[1, width+1, width*2+1, width*3+1],
[width, width+1, width+2, width+3]
];
const theTetrominos = [lTetromino, zTetromino, tTetromino, oTetromino, iTetromino];
let currentPosition = 4;
let currentRotation = 0;
let random = Math.floor(Math.random() * theTetrominos.length);
let current = theTetrominos[random][currentRotation];
// Desenhar o Tetromino
function draw() {
current.forEach(index => {
squares[currentPosition + index].style.backgroundColor = colors[random];
});
}
// Desfazer o desenho do Tetromino
function undraw() {
current.forEach(index => {
squares[currentPosition + index].style.backgroundColor = '';
});
}
// Fazer o Tetromino cair a cada segundo
timerId = setInterval(moveDown, 1000);
// Mover Tetromino para baixo
function moveDown() {
undraw();
currentPosition += width;
draw();
freeze();
}
// Congelar quando o Tetromino atinge o fundo da grade
function freeze() {
if (current.some(index => squares[currentPosition + index + width].classList.contains('taken'))) {
current.forEach(index => squares[currentPosition + index].classList.add('taken'));
random = nextRandom;
nextRandom = Math.floor(Math.random() * theTetrominos.length);
current = theTetrominos[random][currentRotation];
currentPosition = 4;
draw();
addScore();
gameOver();
}
}
// Adicionar pontuação
function addScore() {
for (let i = 0; i < 199; i += width) {
const row = [i, i+1, i+2, i+3, i+4, i+5, i+6, i+7, i+8, i+9];
if (row.every(index => squares[index].classList.contains('taken'))) {
score += 10;
scoreDisplay.innerText = score;
row.forEach(index => {
squares[index].classList.remove('taken');
squares[index].style.backgroundColor = '';
});
const squaresRemoved = squares.splice(i, width);
squares = squaresRemoved.concat(squares);
squares.forEach(cell => grid.appendChild(cell));
}
}
}
// Verificar o fim do jogo
function gameOver() {
if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
scoreDisplay.innerText = 'Fim de jogo';
clearInterval(timerId);
}
}
document.addEventListener('keyup', control);
function control(e) {
if (e.keyCode === 37) {
moveLeft();
} else if (e.keyCode === 38) {
rotate();
} else if (e.keyCode === 39) {
moveRight();
} else if (e.keyCode === 40) {
moveDown();
}
}
function moveLeft() {
undraw();
const isAtLeftEdge = current.some(index => (currentPosition + index) % width === 0);
if (!isAtLeftEdge) currentPosition -= 1;
if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
currentPosition += 1;
}
draw();
}
function moveRight() {
undraw();
const isAtRightEdge = current.some(index => (currentPosition + index) % width === width - 1);
if (!isAtRightEdge) currentPosition += 1;
if (current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
currentPosition -= 1;
}
draw();
}
function rotate() {
undraw();
currentRotation++;
if (currentRotation === current.length) {
currentRotation = 0;
}
current = theTetrominos[random][currentRotation];
draw();
}
document.querySelector('#restart').addEventListener('click', () => {
clearInterval(timerId);
score = 0;
scoreDisplay.innerText = score;
nextRandom = 0;
createBoard();
random = Math.floor(Math.random() * theTetrominos.length);
current = theTetrominos[random][currentRotation];
currentPosition = 4;
draw();
timerId = setInterval(moveDown, 1000);
});
document.querySelector('#pause').addEventListener('click', () => {
if (timerId) {
clearInterval(timerId);
timerId = null;
document.querySelector('#pause').innerText = 'Retomar';
} else {
timerId = setInterval(moveDown, 1000);
document.querySelector('#pause').innerText = 'Pausar';
}
});
document.querySelector('#reset-score').addEventListener('click', () => {
score = 0;
scoreDisplay.innerText = score;
});
});
index.html
em um navegador web.Adicionar e remover classes CSS com JQUERY é uma atividade muito simples, mas também através do javascript puro conseguimos o... Leia mais
Ao realizar estudos de análise de dados ou ao testar sistemas que lidam com grandes volumes de informações, é comum... Leia mais
Quando trabalhamos com Eloquent no Laravel, frequentemente precisamos realizar consultas baseadas em relacionamentos entre modelos. Para isso, o Laravel oferece... Leia mais
Tabela para consulta rápida a convenção de nomes utilizadas em projetos Laravel: Leia mais