1 results found

Escreva um jogo 3D da cobrinha em um único código HTML

Para criar um jogo 3D da cobrinha em um único arquivo HTML de forma concisa, vamos utilizar o `<canvas>` e simular um efeito 3D simples usando técnicas de desenho 2D (como sombras e sobreposições), pois um WebGL completo seria muito extenso para ser "conciso".

Este código HTML incluirá CSS e JavaScript no mesmo arquivo para um jogo funcional de cobrinha com um toque "3D".

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Snake Game (HTML Single File)</title>
<style>
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #2c3e50; /* Fundo escuro */
color: #ecf0f1;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
overflow: hidden;
}
canvas {
background-color: #34495e; /* Fundo do tabuleiro */
border: 5px solid #2980b9;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
margin-bottom: 20px;
}
#game-info {
text-align: center;
font-size: 1.2em;
margin-top: 10px;
}
#restart-button {
background-color: #27ae60;
color: white;
padding: 10px 20px;
border: none;
border-radius: 5px;
font-size: 1em;
cursor: pointer;
margin-top: 15px;
transition: background-color 0.3s ease;
}
#restart-button:hover {
background-color: #2ecc71;
}
.game-over-text {
color: #e74c3c;
font-size: 1.8em;
font-weight: bold;
margin-bottom: 10px;
}
.instructions {
font-size: 0.9em;
color: #bdc3c7;
margin-top: 10px;
}
</style>
</head>
<body>
<h1>3D Snake Game</h1>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div id="game-info">
<div id="score">Pontuação: 0</div>
<div class="instructions">Use as setas do teclado para mover.</div>
<div id="game-message"></div>
<button id="restart-button" style="display: none;">Reiniciar Jogo</button>
</div>

<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const gameMessage = document.getElementById('game-message');
const restartButton = document.getElementById('restart-button');

const gridSize = 20; // Tamanho de cada célula (bloco)
let snake = [{ x: 10 * gridSize, y: 10 * gridSize }];
let food = {};
let dx = gridSize; // Direção inicial X (para a direita)
let dy = 0; // Direção inicial Y
let score = 0;
let gameOver = false;
let gameInterval;
let gameSpeed = 150; // Velocidade do jogo (ms)

// --- Funções do Jogo ---

function initGame() {
snake = [{ x: 10 * gridSize, y: 10 * gridSize }];
dx = gridSize;
dy = 0;
score = 0;
scoreDisplay.textContent = `Pontuação: ${score}`;
gameOver = false;
gameMessage.textContent = '';
restartButton.style.display = 'none';
generateFood();
startGameLoop();
}

function startGameLoop() {
if (gameInterval) clearInterval(gameInterval);
gameInterval = setInterval(update, gameSpeed);
}

function generateFood() {
let randX, randY;
do {
randX = Math.floor(Math.random() * (canvas.width / gridSize)) * gridSize;
randY = Math.floor(Math.random() * (canvas.height / gridSize)) * gridSize;
} while (isOccupied(randX, randY, snake)); // Garante que a comida não apareça na cobra

food = { x: randX, y: randY };
}

function isOccupied(x, y, segments) {
for (let i = 0; i < segments.length; i++) {
if (segments[i].x === x && segments[i].y === y) {
return true;
}
}
return false;
}

function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Limpa o canvas

// Desenha a comida (com efeito pseudo-3D)
drawPseudo3DBlock(food.x, food.y, '#e74c3c', '#c0392b'); // Vermelho

// Desenha a cobra (com efeito pseudo-3D)
for (let i = 0; i < snake.length; i++) {
const color = (i === 0) ? '#2ecc71' : '#27ae60'; // Cabeça verde brilhante, corpo verde escuro
const shadowColor = (i === 0) ? '#27ae60' : '#229a56';
drawPseudo3DBlock(snake[i].x, snake[i].y, color, shadowColor);
}
}

// Função para desenhar um bloco com efeito pseudo-3D
function drawPseudo3DBlock(x, y, mainColor, shadowColor) {
const shadowOffset = 3; // Deslocamento para a sombra
const borderColor = 'rgba(0,0,0,0.5)';

// Sombra
ctx.fillStyle = shadowColor;
ctx.fillRect(x + shadowOffset, y + shadowOffset, gridSize, gridSize);

// Borda
ctx.strokeStyle = borderColor;
ctx.lineWidth = 2;
ctx.strokeRect(x, y, gridSize, gridSize);

// Face principal
ctx.fillStyle = mainColor;
ctx.fillRect(x, y, gridSize, gridSize);
}

function update() {
if (gameOver) return;

const head = { x: snake[0].x + dx, y: snake[0].y + dy };

// Verifica colisões
const hitWall = head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height;
const hitSelf = isOccupied(head.x, head.y, snake.slice(0, snake.length -1)); // Não colide com a cauda se ela vai sair

if (hitWall || hitSelf) {
endGame();
return;
}

snake.unshift(head); // Adiciona nova cabeça

// Verifica se comeu a comida
if (head.x === food.x && head.y === food.y) {
score++;
scoreDisplay.textContent = `Pontuação: ${score}`;
generateFood();
// Opcional: Aumentar a velocidade do jogo
// gameSpeed = Math.max(50, gameSpeed - 5);
// startGameLoop(); // Reinicia o loop com a nova velocidade
} else {
snake.pop(); // Remove a cauda se não comeu a comida
}

draw();
}

function endGame() {
gameOver = true;
clearInterval(gameInterval);
gameMessage.innerHTML = '<div class="game-over-text">GAME OVER!</div>';
restartButton.style.display = 'block';
}

// --- Eventos ---
document.addEventListener('keydown', e => {
if (gameOver) return; // Não permite mudar direção se o jogo acabou

// Previne a cobra de ir na direção oposta instantaneamente
switch (e.key) {
case 'ArrowUp':
if (dy === 0) { dx = 0; dy = -gridSize; }
break;
case 'ArrowDown':
if (dy === 0) { dx = 0; dy = gridSize; }
break;
case 'ArrowLeft':
if (dx === 0) { dx = -gridSize; dy = 0; }
break;
case 'ArrowRight':
if (dx === 0) { dx = gridSize; dy = 0; }
break;
}
});

restartButton.addEventListener('click', initGame);

// Inicia o jogo quando a página carrega
window.onload = initGame;
</script>
</body>
</html>
```

Related Questions

What is the history of this topic?
More details about the context

Quick Insights

Read time 45 seconds
Sources 12 verified
Last updated 2 hours ago

Try Pro!

Get priority access to the latest AI models and unlimited searches.