sispong / index.html
tionioliv's picture
undefined - Initial Deployment
f8f78dc verified
Raw
History Blame Contribute Delete
18.2 kB
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SisPong - Inspirado no Sismetro</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
body {
font-family: 'Roboto', sans-serif;
background-color: #1a1a2e;
color: white;
overflow: hidden;
}
#gameCanvas {
background-color: #16213e;
box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
}
.player-paddle {
box-shadow: 0 0 15px rgba(74, 201, 195, 0.7);
}
.ball {
box-shadow: 0 0 20px rgba(255, 123, 84, 0.8);
}
.pulse {
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.score-glow {
text-shadow: 0 0 10px #4ac9c3, 0 0 20px #4ac9c3;
}
.button-glow:hover {
box-shadow: 0 0 15px rgba(74, 201, 195, 0.7);
transform: translateY(-2px);
transition: all 0.3s;
}
</style>
</head>
<body class="flex flex-col items-center justify-center min-h-screen">
<header class="w-full max-w-4xl px-4 mb-6">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-2">
<i class="fas fa-broadcast-tower text-3xl text-cyan-400"></i>
<h1 class="text-3xl font-bold text-gradient bg-gradient-to-r from-cyan-400 to-orange-400 bg-clip-text text-transparent">Sis<span class="text-white">Pong</span></h1>
</div>
<div class="text-sm text-gray-300 hidden md:block">
<p>Inspirado no visual do <span class="text-cyan-400">Sismetro.com.br</span></p>
</div>
</div>
</header>
<div class="relative w-full max-w-4xl aspect-video">
<canvas id="gameCanvas" class="w-full h-full rounded-xl"></canvas>
<div id="startScreen" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80 rounded-xl p-6 text-center">
<h2 class="text-4xl font-bold mb-4 text-gradient bg-gradient-to-r from-cyan-400 to-orange-400 bg-clip-text text-transparent">SisPong</h2>
<p class="text-gray-300 mb-8">Use as teclas <span class="font-mono bg-gray-800 px-2 py-1 rounded">W/S</span> para mover o jogador esquerdo e as teclas <span class="font-mono bg-gray-800 px-2 py-1 rounded">↑/↓</span> para mover o jogador direito</p>
<button id="startButton" class="button-glow bg-gradient-to-r from-cyan-500 to-blue-600 text-white px-8 py-3 rounded-full font-bold pulse hover:from-cyan-600 hover:to-blue-700 transition-all">
Começar Jogo
</button>
<div class="mt-8 flex space-x-4">
<div class="flex flex-col items-center">
<p class="text-gray-400">Jogador 1</p>
<div class="flex items-center mt-2">
<div class="w-5 h-16 bg-gradient-to-t from-cyan-400 to-cyan-600 rounded-full mr-2"></div>
<div class="text-xs text-gray-300">
<p>Tecla W: ↑</p>
<p>Tecla S: ↓</p>
</div>
</div>
</div>
<div class="flex flex-col items-center">
<p class="text-gray-400">Jogador 2</p>
<div class="flex items-center mt-2">
<div class="text-xs text-gray-300 mr-2">
<p>Tecla ↑: ↑</p>
<p>Tecla ↓: ↓</p>
</div>
<div class="w-5 h-16 bg-gradient-to-t from-orange-400 to-orange-600 rounded-full"></div>
</div>
</div>
</div>
</div>
<div id="gameOverScreen" class="absolute inset-0 hidden flex-col items-center justify-center bg-black bg-opacity-80 rounded-xl p-6 text-center">
<h2 class="text-4xl font-bold mb-2 text-gradient bg-gradient-to-r from-cyan-400 to-orange-400 bg-clip-text text-transparent">Fim de Jogo!</h2>
<p id="winnerText" class="text-xl mb-6"></p>
<div class="flex space-x-4">
<button id="restartButton" class="button-glow bg-gradient-to-r from-cyan-500 to-blue-600 text-white px-6 py-2 rounded-full font-bold">
Jogar Novamente
</button>
<button id="menuButton" class="button-glow bg-gradient-to-r from-gray-600 to-gray-700 text-white px-6 py-2 rounded-full font-bold">
Menu Principal
</button>
</div>
<div class="mt-8 text-gray-300 text-sm">
<p>Criado com inspiração no visual do Sismetro.com.br</p>
<p class="flex items-center justify-center mt-2">
<i class="fas fa-code text-cyan-400 mr-1"></i> HTML, CSS e JavaScript
</p>
</div>
</div>
</div>
<div class="mt-6 w-full max-w-4xl px-4">
<div class="flex justify-between items-center">
<div class="flex items-center space-x-2">
<div class="w-5 h-16 bg-gradient-to-t from-cyan-400 to-cyan-600 rounded-full"></div>
<span class="text-2xl font-bold score-glow" id="player1Score">0</span>
</div>
<div class="text-gray-400 text-sm">
<p>Pontuação <span class="text-cyan-400">máxima: 5</span></p>
</div>
<div class="flex items-center space-x-2">
<span class="text-2xl font-bold score-glow" id="player2Score">0</span>
<div class="w-5 h-16 bg-gradient-to-t from-orange-400 to-orange-600 rounded-full"></div>
</div>
</div>
</div>
<div class="mt-4 text-xs text-gray-400 flex flex-wrap justify-center gap-2 px-4">
<div class="flex items-center"><div class="w-3 h-3 rounded-full bg-cyan-400 mr-1"></div> Controles do Jogador 1</div>
<div class="flex items-center"><div class="w-3 h-3 rounded-full bg-orange-400 mr-1"></div> Controles do Jogador 2</div>
<div class="flex items-center"><i class="fas fa-circle text-white text-xs mr-1"></i> Bola</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const player1ScoreElement = document.getElementById('player1Score');
const player2ScoreElement = document.getElementById('player2Score');
const startButton = document.getElementById('startButton');
const startScreen = document.getElementById('startScreen');
const gameOverScreen = document.getElementById('gameOverScreen');
const restartButton = document.getElementById('restartButton');
const menuButton = document.getElementById('menuButton');
const winnerText = document.getElementById('winnerText');
// Set canvas dimensions
function resizeCanvas() {
const container = canvas.parentElement;
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// Game variables
const paddleWidth = 15;
const paddleHeight = 100;
const ballSize = 15;
const paddleSpeed = 8;
const initialBallSpeed = 5;
let player1Score = 0;
let player2Score = 0;
let gameRunning = false;
// Player positions
let player1 = {
x: 30,
y: canvas.height / 2 - paddleHeight / 2,
speed: 0
};
let player2 = {
x: canvas.width - 30 - paddleWidth,
y: canvas.height / 2 - paddleHeight / 2,
speed: 0
};
// Ball properties
let ball = {
x: canvas.width / 2,
y: canvas.height / 2,
speedX: initialBallSpeed,
speedY: initialBallSpeed
};
// Key states
const keys = {
w: false,
s: false,
ArrowUp: false,
ArrowDown: false
};
// Event listeners for key presses
window.addEventListener('keydown', (e) => {
if (e.key in keys) {
keys[e.key] = true;
}
});
window.addEventListener('keyup', (e) => {
if (e.key in keys) {
keys[e.key] = false;
}
});
// Start game
startButton.addEventListener('click', startGame);
restartButton.addEventListener('click', startGame);
menuButton.addEventListener('click', () => {
gameOverScreen.classList.add('hidden');
startScreen.classList.remove('hidden');
resetGame();
});
function startGame() {
startScreen.classList.add('hidden');
gameOverScreen.classList.add('hidden');
resetGame();
gameRunning = true;
animate();
}
function resetGame() {
player1Score = 0;
player2Score = 0;
player1ScoreElement.textContent = '0';
player2ScoreElement.textContent = '0';
player1.y = canvas.height / 2 - paddleHeight / 2;
player2.y = canvas.height / 2 - paddleHeight / 2;
resetBall();
}
function resetBall() {
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
// Random direction
ball.speedX = (Math.random() > 0.5 ? 1 : -1) * initialBallSpeed;
ball.speedY = (Math.random() * 2 - 1) * initialBallSpeed * 0.5;
// Normalize speed to maintain consistent initial speed
const speed = Math.sqrt(ball.speedX * ball.speedX + ball.speedY * ball.speedY);
ball.speedX = (ball.speedX / speed) * initialBallSpeed;
ball.speedY = (ball.speedY / speed) * initialBallSpeed;
}
// Game loop
function animate() {
if (!gameRunning) return;
// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Update player positions based on key states
if (keys.w) player1.speed = -paddleSpeed;
else if (keys.s) player1.speed = paddleSpeed;
else player1.speed = 0;
if (keys.ArrowUp) player2.speed = -paddleSpeed;
else if (keys.ArrowDown) player2.speed = paddleSpeed;
else player2.speed = 0;
// Move players with boundary checking
player1.y += player1.speed;
player2.y += player2.speed;
if (player1.y < 0) player1.y = 0;
if (player1.y > canvas.height - paddleHeight) player1.y = canvas.height - paddleHeight;
if (player2.y < 0) player2.y = 0;
if (player2.y > canvas.height - paddleHeight) player2.y = canvas.height - paddleHeight;
// Move ball
ball.x += ball.speedX;
ball.y += ball.speedY;
// Ball collision with top and bottom walls
if (ball.y <= 0 || ball.y >= canvas.height - ballSize) {
ball.speedY = -ball.speedY;
}
// Ball collision with paddles
if (
ball.x <= player1.x + paddleWidth &&
ball.x + ballSize >= player1.x &&
ball.y + ballSize >= player1.y &&
ball.y <= player1.y + paddleHeight
) {
// Calculate angle based on where the ball hits the paddle
const hitPosition = (ball.y - (player1.y + paddleHeight / 2)) / (paddleHeight / 2);
const angle = hitPosition * Math.PI / 4; // Max 45 degrees
// Increase speed slightly on hit
const speed = Math.sqrt(ball.speedX * ball.speedX + ball.speedY * ball.speedY) * 1.05;
ball.speedX = Math.cos(angle) * speed;
ball.speedY = Math.sin(angle) * speed;
// Make sure ball is moving to the right after hitting left paddle
if (ball.speedX < 0) ball.speedX = -ball.speedX;
}
if (
ball.x + ballSize >= player2.x &&
ball.x <= player2.x + paddleWidth &&
ball.y + ballSize >= player2.y &&
ball.y <= player2.y + paddleHeight
) {
// Calculate angle based on where the ball hits the paddle
const hitPosition = (ball.y - (player2.y + paddleHeight / 2)) / (paddleHeight / 2);
const angle = hitPosition * Math.PI / 4; // Max 45 degrees
// Increase speed slightly on hit
const speed = Math.sqrt(ball.speedX * ball.speedX + ball.speedY * ball.speedY) * 1.05;
ball.speedX = Math.cos(angle) * -speed;
ball.speedY = Math.sin(angle) * speed;
// Make sure ball is moving to the left after hitting right paddle
if (ball.speedX > 0) ball.speedX = -ball.speedX;
}
// Ball out of bounds (score)
if (ball.x < 0) {
player2Score++;
player2ScoreElement.textContent = player2Score;
checkGameOver();
resetBall();
} else if (ball.x > canvas.width) {
player1Score++;
player1ScoreElement.textContent = player1Score;
checkGameOver();
resetBall();
}
// Draw center line
ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
ctx.lineWidth = 3;
ctx.setLineDash([10, 15]);
ctx.beginPath();
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.stroke();
ctx.setLineDash([]);
// Draw players and ball
// Player 1 (cyan)
const player1Gradient = ctx.createLinearGradient(0, player1.y, 0, player1.y + paddleHeight);
player1Gradient.addColorStop(0, '#4ac9c4');
player1Gradient.addColorStop(1, '#1e90ff');
ctx.fillStyle = player1Gradient;
ctx.beginPath();
ctx.roundRect(player1.x, player1.y, paddleWidth, paddleHeight, 20);
ctx.fill();
// Player 2 (orange)
const player2Gradient = ctx.createLinearGradient(0, player2.y, 0, player2.y + paddleHeight);
player2Gradient.addColorStop(0, '#ff7b54');
player2Gradient.addColorStop(1, '#ff5353');
ctx.fillStyle = player2Gradient;
ctx.beginPath();
ctx.roundRect(player2.x, player2.y, paddleWidth, paddleHeight, 20);
ctx.fill();
// Ball (white with glow)
ctx.fillStyle = 'white';
ctx.beginPath();
ctx.arc(ball.x + ballSize/2, ball.y + ballSize/2, ballSize/2, 0, Math.PI * 2);
ctx.fill();
requestAnimationFrame(animate);
}
function checkGameOver() {
if (player1Score >= 5 || player2Score >= 5) {
gameRunning = false;
gameOverScreen.classList.remove('hidden');
if (player1Score >= 5) {
winnerText.textContent = 'Jogador 1 venceu!';
winnerText.className = 'text-xl mb-6 text-cyan-400';
} else {
winnerText.textContent = 'Jogador 2 venceu!';
winnerText.className = 'text-xl mb-6 text-orange-400';
}
}
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=tionioliv/sispong" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>