Como rodar Laravel no WSL com Valet Linux (de verdade)
Sim, dá pra desenvolver Laravel no Windows sem sofrer. Mas você precisa fazer do jeito certo: usando WSL + Valet... 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.
Sim, dá pra desenvolver Laravel no Windows sem sofrer. Mas você precisa fazer do jeito certo: usando WSL + Valet... Leia mais
O Laravel é um dos frameworks de desenvolvimento web mais populares e poderosos em uso atualmente. Ele tem muitas características... Leia mais
Publiquei neste artigo https://paulorb.dev/alternar-entre-multiplas-versoes-no-php/ formas de como instalar diversas versões do PHP em distros Linux mas surgiu um problema que... Leia mais
Neste tutorial, vamos aprender como exportar uma lista de cadastros de clientes para uma planilha Excel, incluindo as fotos dos... Leia mais