Ping Pong Mejorado - Alta Velocidad
Juego rápido y fluido con IA adaptativa. ¡Demuestra tus habilidades!
Controles
- Flecha Arriba: Mover hacia arriba
- Flecha Abajo: Mover hacia abajo
- Espacio: Pausar/Reanudar
- R: Reiniciar juego
Estadísticas
0
Jugador1
Nivel0
SMARTSERVICE
Características del Juego
Alta Velocidad
Optimizado para máxima fluidez:
- Velocidad inicial de pelota: 8px/frame
- Incremento progresivo por nivel
- Máxima velocidad: 15px/frame
- Respuesta instantánea a controles
IA Inteligente
Sistema adaptativo de dificultad:
- Nivel 1-3: Velocidad media + predicción básica
- Nivel 4-7: Alta velocidad + predicción media
- Nivel 8+: Velocidad máxima + predicción avanzada
Código Completo para Copiar
HTML, CSS y JavaScript del Ping Pong Mejorado
<!-- HTML del juego -->
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="card bg-secondary text-white">
<div class="card-body">
<h5 class="card-title">Controles</h5>
<ul class="list-unstyled">
<li>Flecha Arriba: Mover paleta hacia arriba</li>
<li>Flecha Abajo: Mover paleta hacia abajo</li>
<li>Espacio: Pausar/Reanudar</li>
<li>R: Reiniciar juego</li>
</ul>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card bg-secondary text-white">
<div class="card-body">
<h5 class="card-title">Estadísticas</h5>
<div class="row text-center">
<div class="col-4">
<h3 id="player-score" class="text-warning">0</h3>
<small>Jugador</small>
</div>
<div class="col-4">
<h3 id="level" class="text-info">1</h3>
<small>Nivel</small>
</div>
<div class="col-4">
<h3 id="pc-score" class="text-danger">0</h3>
<small>Computadora</small>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="text-center my-4">
<canvas id="pingpongCanvas" width="800" height="500" class="border border-light rounded shadow"></canvas>
</div>
<div class="text-center">
<button id="startBtn" class="btn btn-success btn-lg me-2">Iniciar Juego</button>
<button id="pauseBtn" class="btn btn-warning btn-lg me-2" disabled>Pausar</button>
<button id="resetBtn" class="btn btn-danger btn-lg">Reiniciar</button>
</div>
</div>
<style>
/* Estilos del juego */
canvas {
background: #000;
display: block;
margin: 0 auto;
}
.card {
margin-bottom: 1rem;
}
</style>
<script>
// JavaScript del juego Ping Pong Mejorado
const canvas = document.getElementById('pingpongCanvas');
const ctx = canvas.getContext('2d');
// Elementos del juego
const playerScoreElem = document.getElementById('player-score');
const pcScoreElem = document.getElementById('pc-score');
const levelElem = document.getElementById('level');
const startBtn = document.getElementById('startBtn');
const pauseBtn = document.getElementById('pauseBtn');
const resetBtn = document.getElementById('resetBtn');
const gameMessage = document.getElementById('gameMessage');
// Variables del juego
let gameRunning = false;
let gamePaused = false;
let animationId;
let keys = {};
// Configuración del juego - VELOCIDAD MEJORADA
const config = {
paddleWidth: 12,
paddleHeight: 90,
ballSize: 10,
initialBallSpeed: 8, // Aumentada para mayor velocidad
maxBallSpeed: 15, // Velocidad máxima más alta
paddleSpeed: 12, // Velocidad de paleta aumentada
winningScore: 7 // Puntuación para ganar reducida para juegos más rápidos
};
// Objetos del juego
const player = {
x: 20,
y: canvas.height / 2 - config.paddleHeight / 2,
width: config.paddleWidth,
height: config.paddleHeight,
speed: config.paddleSpeed,
score: 0
};
const pc = {
x: canvas.width - 20 - config.paddleWidth,
y: canvas.height / 2 - config.paddleHeight / 2,
width: config.paddleWidth,
height: config.paddleHeight,
speed: config.paddleSpeed,
score: 0
};
const ball = {
x: canvas.width / 2,
y: canvas.height / 2,
size: config.ballSize,
speed: config.initialBallSpeed,
velocityX: 0,
velocityY: 0
};
// Sistema de niveles
let level = 1;
let rallyCount = 0;
// Inicializar el juego
function initGame() {
resetBall();
player.score = 0;
pc.score = 0;
level = 1;
rallyCount = 0;
updateScore();
updateLevel();
}
// Reiniciar la pelota con dirección aleatoria
function resetBall() {
ball.x = canvas.width / 2;
ball.y = canvas.height / 2;
// Dirección aleatoria con mayor velocidad base
const direction = Math.random() > 0.5 ? 1 : -1;
const speed = config.initialBallSpeed + (level * 0.4); // Incremento más agresivo
ball.velocityX = direction * Math.min(speed, config.maxBallSpeed);
ball.velocityY = (Math.random() * 4 - 2) * (config.initialBallSpeed / 3);
rallyCount = 0;
}
// Dibujar elementos
function draw() {
// Limpiar canvas
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Dibujar línea central punteada
ctx.setLineDash([5, 10]);
ctx.beginPath();
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.strokeStyle = '#444';
ctx.lineWidth = 2;
ctx.stroke();
ctx.setLineDash([]);
// Dibujar paletas con efecto de gradiente
const playerGradient = ctx.createLinearGradient(player.x, 0, player.x + player.width, 0);
playerGradient.addColorStop(0, '#4da6ff');
playerGradient.addColorStop(1, '#80c1ff');
ctx.fillStyle = playerGradient;
ctx.fillRect(player.x, player.y, player.width, player.height);
const pcGradient = ctx.createLinearGradient(pc.x, 0, pc.x + pc.width, 0);
pcGradient.addColorStop(0, '#ff4d4d');
pcGradient.addColorStop(1, '#ff8080');
ctx.fillStyle = pcGradient;
ctx.fillRect(pc.x, pc.y, pc.width, pc.height);
// Dibujar pelota con efecto de brillo
ctx.fillStyle = '#fff';
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.size, 0, Math.PI * 2);
ctx.fill();
// Efecto de brillo en la pelota
ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';
ctx.beginPath();
ctx.arc(ball.x - ball.size/3, ball.y - ball.size/3, ball.size/3, 0, Math.PI * 2);
ctx.fill();
}
// Actualizar posición de elementos
function update() {
if (gamePaused) return;
// Mover pelota con velocidad mejorada
ball.x += ball.velocityX;
ball.y += ball.velocityY;
// Rebote en paredes superior e inferior
if (ball.y + ball.size > canvas.height || ball.y - ball.size < 0) {
ball.velocityY = -ball.velocityY;
}
// Detectar colisión con paletas - FÍSICA MEJORADA
// Jugador
if (
ball.x - ball.size < player.x + player.width &&
ball.y + ball.size > player.y &&
ball.y - ball.size < player.y + player.height &&
ball.velocityX < 0
) {
// Ajustar ángulo y velocidad basado en dónde golpea la paleta
const hitPosition = (ball.y - player.y) / player.height;
const angle = hitPosition * Math.PI / 2 - Math.PI / 4;
// Incrementar velocidad con cada golpe
const speedIncrease = 0.1;
const currentSpeed = Math.sqrt(ball.velocityX * ball.velocityX + ball.velocityY * ball.velocityY);
const newSpeed = Math.min(currentSpeed * (1 + speedIncrease), config.maxBallSpeed);
ball.velocityX = Math.cos(angle) * newSpeed;
ball.velocityY = Math.sin(angle) * newSpeed;
rallyCount++;
checkLevelUp();
}
// Computadora
if (
ball.x + ball.size > pc.x &&
ball.y + ball.size > pc.y &&
ball.y - ball.size < pc.y + pc.height &&
ball.velocityX > 0
) {
// Ajustar ángulo y velocidad basado en dónde golpea la paleta
const hitPosition = (ball.y - pc.y) / pc.height;
const angle = hitPosition * Math.PI / 2 - Math.PI / 4;
// Incrementar velocidad con cada golpe
const speedIncrease = 0.1;
const currentSpeed = Math.sqrt(ball.velocityX * ball.velocityX + ball.velocityY * ball.velocityY);
const newSpeed = Math.min(currentSpeed * (1 + speedIncrease), config.maxBallSpeed);
ball.velocityX = -Math.cos(angle) * newSpeed;
ball.velocityY = Math.sin(angle) * newSpeed;
rallyCount++;
checkLevelUp();
}
// IA de la computadora MEJORADA
moveComputerPaddle();
// Mover jugador con teclado
movePlayerPaddle();
// Puntuación
if (ball.x < 0) {
pc.score++;
updateScore();
resetBall();
checkLevelDown();
} else if (ball.x > canvas.width) {
player.score++;
updateScore();
resetBall();
checkLevelUp();
}
// Verificar ganador
if (player.score >= config.winningScore || pc.score >= config.winningScore) {
endGame();
}
}
// Mover paleta del jugador
function movePlayerPaddle() {
if (keys['ArrowUp']) {
player.y = Math.max(0, player.y - player.speed);
}
if (keys['ArrowDown']) {
player.y = Math.min(canvas.height - player.height, player.y + player.speed);
}
}
// Mover paleta de la computadora con IA MEJORADA
function moveComputerPaddle() {
// Calcular posición objetivo con predicción
const predictY = ball.y + (ball.velocityY * (pc.x - ball.x) / ball.velocityX);
const targetY = predictY - pc.height / 2;
// Ajustar la dificultad según el nivel
let reactionSpeed;
let errorMargin;
if (level <= 3) {
// Nivel fácil: reacción media, margen de error alto
reactionSpeed = 0.08;
errorMargin = 50;
} else if (level <= 7) {
// Nivel medio: reacción rápida, margen de error medio
reactionSpeed = 0.12;
errorMargin = 30;
} else {
// Nivel difícil: reacción muy rápida, margen de error bajo
reactionSpeed = 0.18;
errorMargin = 15;
}
// Añadir error de predicción para hacerlo más humano
const error = (Math.random() - 0.5) * errorMargin;
const finalTarget = targetY + error;
// Mover suavemente hacia la posición objetivo
const diff = finalTarget - pc.y;
pc.y += diff * reactionSpeed;
// Mantener dentro de los límites
if (pc.y < 0) pc.y = 0;
if (pc.y + pc.height > canvas.height) pc.y = canvas.height - pc.height;
}
// Verificar si subir de nivel
function checkLevelUp() {
// Subir nivel si el jugador tiene ventaja de 3 puntos
if (player.score - pc.score >= 3 && level < 10) {
level++;
updateLevel();
showMessage(`¡Nivel ${level}!`, 'success');
}
// Subir nivel si hay un rally muy largo
else if (rallyCount >= 8 && level < 10) {
level++;
updateLevel();
showMessage(`¡Rally épico! Nivel ${level}`, 'success');
rallyCount = 0;
}
}
// Verificar si bajar de nivel
function checkLevelDown() {
// Bajar nivel si la computadora tiene ventaja de 3 puntos
if (pc.score - player.score >= 3 && level > 1) {
level--;
updateLevel();
showMessage(`Nivel ${level}`, 'warning');
}
}
// Actualizar marcador
function updateScore() {
playerScoreElem.textContent = player.score;
pcScoreElem.textContent = pc.score;
}
// Actualizar nivel
function updateLevel() {
levelElem.textContent = level;
}
// Mostrar mensaje temporal
function showMessage(text, type) {
gameMessage.textContent = text;
gameMessage.className = `position-absolute top-50 start-50 translate-middle display-4 fw-bold text-${type}`;
gameMessage.style.display = 'block';
setTimeout(() => {
gameMessage.style.display = 'none';
}, 1200);
}
// Terminar juego
function endGame() {
gameRunning = false;
cancelAnimationFrame(animationId);
const winner = player.score > pc.score ? 'Jugador' : 'Computadora';
showMessage(`¡${winner} gana!`, player.score > pc.score ? 'success' : 'danger');
startBtn.disabled = false;
pauseBtn.disabled = true;
}
// Bucle del juego optimizado
function gameLoop() {
draw();
update();
if (gameRunning) {
animationId = requestAnimationFrame(gameLoop);
}
}
// Controles del teclado MEJORADOS
document.addEventListener('keydown', (e) => {
keys[e.key] = true;
if (e.key === ' ' && gameRunning) {
togglePause();
e.preventDefault();
}
if ((e.key === 'r' || e.key === 'R') && gameRunning) {
resetGame();
}
});
document.addEventListener('keyup', (e) => {
keys[e.key] = false;
});
// Funciones de control del juego
function startGame() {
if (!gameRunning) {
gameRunning = true;
gamePaused = false;
startBtn.disabled = true;
pauseBtn.disabled = false;
gameLoop();
}
}
function togglePause() {
gamePaused = !gamePaused;
pauseBtn.textContent = gamePaused ? 'Reanudar' : 'Pausar';
pauseBtn.innerHTML = gamePaused ?
' Reanudar' :
' Pausar';
if (!gamePaused && gameRunning) {
gameLoop();
}
}
function resetGame() {
gameRunning = false;
gamePaused = false;
cancelAnimationFrame(animationId);
initGame();
draw();
startBtn.disabled = false;
pauseBtn.disabled = true;
pauseBtn.textContent = 'Pausar';
pauseBtn.innerHTML = ' Pausar';
gameMessage.style.display = 'none';
}
// Event listeners
startBtn.addEventListener('click', startGame);
pauseBtn.addEventListener('click', togglePause);
resetBtn.addEventListener('click', resetGame);
// Inicializar
initGame();
draw();
</script>