Animación de Gato de Zafiro y Diamantes
- samuel gaitan
- 27 jun
- 6 Min. de lectura
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gato de Diamantes: La Aventura</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Cinzel:wght@700&family=Press+Start+2P&display=swap');
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
transition: background 0.5s ease;
overflow: hidden;
}
/* --- Pantalla de Inicio --- */
.start-screen-body {
background-color: #050214;
font-family: 'Cinzel', serif;
}
#start-screen {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
color: white;
}
#start-screen h1 {
font-size: 3rem;
color: #d4e1ff;
margin-bottom: 1rem;
}
#start-button {
font-family: 'Press Start 2P', cursive;
font-size: 1.5rem;
padding: 15px 30px;
color: white;
background: #1e3a8a;
border: 3px solid #92b6f5;
border-radius: 10px;
cursor: pointer;
box-shadow: 0 0 10px #92b6f5, inset 0 0 5px rgba(255, 255, 255, 0.5);
transition: all 0.2s ease-in-out;
margin-top: 2rem;
}
#start-button:hover {
transform: scale(1.05);
box-shadow: 0 0 20px #92b6f5, inset 0 0 8px rgba(255, 255, 255, 0.7);
}
.animation-container {
position: relative;
width: 300px;
height: 300px;
animation: float 6s ease-in-out infinite;
}
.gato-zafiro {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
filter: drop-shadow(0 0 15px rgba(7, 95, 222, 0.7)) drop-shadow(0 0 45px rgba(0, 123, 255, 0.5));
}
.sapphire-body {
fill: url(#sapphire-gradient);
stroke: #92b6f5;
stroke-width: 0.5;
}
.sparkles-container {
position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;
}
.sparkle-diamond {
position: absolute; background-color: white; border-radius: 50%; width: 4px; height: 4px;
animation: sparkle-animation 1.5s ease-out forwards; opacity: 0;
}
@keyframes sparkle-animation {
0% { transform: scale(0); opacity: 0.5; } 50% { transform: scale(1.5); opacity: 1; } 100% { transform: scale(0); opacity: 0; }
}
@keyframes float {
0% { transform: translateY(0px); } 50% { transform: translateY(-20px); } 100% { transform: translateY(0px); }
}
/* --- Estilos del Juego --- */
.game-active-body {
font-family: 'Press Start 2P', cursive;
}
#game-container {
display: none; /* Oculto al inicio */
position: relative;
border: 8px solid #4a2a0a;
border-radius: 10px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3), inset 0 0 15px rgba(0, 0, 0, 0.4);
}
canvas { display: block; background-color: transparent; }
#ui-container {
position: absolute; top: 20px; left: 20px; right: 20px;
display: flex; justify-content: space-between; align-items: center;
pointer-events: none; color: white;
}
font-size: 24px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);
}
#message {
position: absolute; top: 50%; left: 50%;
transform: translate(-50%, -50%); font-size: 32px;
text-align: center; display: none;
}
</style>
</head>
<body class="start-screen-body">
<!-- Pantalla de Inicio -->
<div id="start-screen">
<h1>Gato de Diamantes</h1>
<div class="animation-container">
<svg class="gato-zafiro" viewBox="0 0 200 200">
<defs>
<linearGradient id="sapphire-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#4a90e2;" />
<stop offset="50%" style="stop-color:#1e3a8a;" />
<stop offset="100%" style="stop-color:#0d214f;" />
<animateTransform attributeName="gradientTransform" type="rotate" from="0 100 100" to="360 100 100" dur="10s" repeatCount="indefinite" />
</linearGradient>
</defs>
<path class="sapphire-body" id="cat-path" d="M100 180 C 40 180 40 100 65 75 C 75 50 110 30 140 55 C 160 80 160 180 100 180 Z M 140 55 C 130 35 140 20 150 20 C 160 20 150 40 145 50 Z M 125 55 C 115 35 125 20 135 20 C 145 20 135 40 130 50 Z M 40 170 C 10 170 10 120 50 110 C 20 80 40 170 40 170Z" />
</svg>
<div id="sparkles-container" class="sparkles-container"></div>
</div>
<button id="start-button">START</button>
</div>
<!-- Contenedor del Juego -->
<div id="game-container">
<canvas id="gameCanvas"></canvas>
<div id="ui-container">
<div id="score">Gemas: 0</div>
</div>
<div id="message"></div>
</div>
<script>
// --- Referencias a Elementos del DOM ---
const startScreen = document.getElementById('start-screen');
const gameContainer = document.getElementById('game-container');
const startButton = document.getElementById('start-button');
const sparklesContainer = document.getElementById('sparkles-container');
const catPath = document.getElementById('cat-path');
// --- Lógica de Animación de Inicio ---
const pathLength = catPath.getTotalLength();
function createSparkle() {
const randomPoint = catPath.getPointAtLength(Math.random() * pathLength);
const sparkle = document.createElement('div');
sparkle.className = 'sparkle-diamond';
sparkle.style.left = `${(randomPoint.x / 200) * 100}%`;
sparkle.style.top = `${(randomPoint.y / 200) * 100}%`;
sparkle.style.animationDuration = `${Math.random() * 1 + 0.8}s`;
sparklesContainer.appendChild(sparkle);
setTimeout(() => sparkle.remove(), 2000);
}
let sparkleInterval = setInterval(createSparkle, 150);
// --- Evento para Empezar el Juego ---
startButton.addEventListener('click', () => {
// Ocultar pantalla de inicio
startScreen.style.display = 'none';
// Detener la animación de destellos
clearInterval(sparkleInterval);
// Mostrar contenedor del juego
document.body.className = 'game-active-body';
gameContainer.style.display = 'block';
// Iniciar el juego
startGame();
});
// --- LÓGICA DEL JUEGO DE PLATAFORMAS ---
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('score');
const messageElement = document.getElementById('message');
const GAME_WIDTH = 800;
const GAME_HEIGHT = 600;
canvas.width = GAME_WIDTH;
canvas.height = GAME_HEIGHT;
const gravity = 0.6;
let score = 0;
let gameOver = false;
let gameStarted = false;
const player = { x: 100, y: 400, width: 50, height: 40, speed: 5, velocityX: 0, velocityY: 0, jumpForce: -14, isJumping: false, direction: 'right' };
const keys = { right: false, left: false, up: false };
const platforms = [
{ x: 0, y: GAME_HEIGHT - 40, width: GAME_WIDTH, height: 40 }, { x: 200, y: 450, width: 150, height: 20 },
{ x: 400, y: 350, width: 150, height: 20 }, { x: 150, y: 250, width: 100, height: 20 },
{ x: 550, y: 220, width: 200, height: 20 }
];
let gems = [];
function setupGems() {
gems = [
{ x: 250, y: 410, width: 20, height: 20, collected: false }, { x: 450, y: 310, width: 20, height: 20, collected: false },
{ x: 175, y: 210, width: 20, height: 20, collected: false }, { x: 600, y: 180, width: 20, height: 20, collected: false },
{ x: 700, y: 180, width: 20, height: 20, collected: false }, { x: 50, y: 500, width: 20, height: 20, collected: false },
];
}
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowRight') keys.right = true; if (e.key === 'ArrowLeft') keys.left = true; if (e.key === 'ArrowUp') keys.up = true;
});
document.addEventListener('keyup', (e) => {
if (e.key === 'ArrowRight') keys.right = false; if (e.key === 'ArrowLeft') keys.left = false; if (e.key === 'ArrowUp') keys.up = false;
});
function drawPlayer() {
ctx.fillStyle = '#FFA500'; ctx.strokeStyle = '#A0522D'; ctx.lineWidth = 3;
ctx.beginPath(); ctx.roundRect(player.x, player.y, player.width, player.height, 10); ctx.fill(); ctx.stroke();
ctx.beginPath(); ctx.arc(player.x + player.width / 2, player.y, player.width / 3, 0, Math.PI * 2); ctx.fill(); ctx.stroke();
ctx.beginPath(); ctx.moveTo(player.x + player.width / 2 - 15, player.y - 10); ctx.lineTo(player.x + player.width / 2 - 5, player.y - 20); ctx.lineTo(player.x + player.width / 2, player.y - 10); ctx.fill(); ctx.stroke();
ctx.beginPath(); ctx.moveTo(player.x + player.width / 2 + 15, player.y - 10); ctx.lineTo(player.x + player.width / 2 + 5, player.y - 20); ctx.lineTo(player.x + player.width / 2, player.y - 10); ctx.fill(); ctx.stroke();
ctx.fillStyle = 'black';
if (player.direction === 'right') { ctx.fillRect(player.x + player.width / 2 + 5, player.y - 5, 4, 4); } else { ctx.fillRect(player.x + player.width / 2 - 9, player.y - 5, 4, 4); }
}
function drawPlatforms() {
ctx.fillStyle = '#654321'; ctx.strokeStyle = '#4a2a0a'; ctx.lineWidth = 4;
platforms.forEach(p => { ctx.beginPath(); ctx.roundRect(p.x, p.y, p.width, p.height, 5); ctx.fill(); ctx.stroke(); });
}
function drawGems() {
gems.forEach(gem => {
if (gem.collected) return;
ctx.save(); ctx.translate(gem.x + gem.width / 2, gem.y + gem.height / 2); ctx.rotate(Math.PI / 4);
ctx.fillStyle = '#4a90e2'; ctx.strokeStyle = '#d4e1ff'; ctx.lineWidth = 2;
ctx.beginPath(); ctx.rect(-gem.width / 2, -gem.height / 2, gem.width, gem.height); ctx.fill(); ctx.stroke();
ctx.restore();
});
}
function update() {
if (gameOver || !gameStarted) return;
player.velocityX = 0;
if (keys.right) { player.velocityX = player.speed; player.direction = 'right'; }
if (keys.left) { player.velocityX = -player.speed; player.direction = 'left'; }
if (keys.up && !player.isJumping) { player.velocityY = player.jumpForce; player.isJumping = true; }
player.x += player.velocityX; player.velocityY += gravity; player.y += player.velocityY;
player.isJumping = true;
platforms.forEach(platform => {
if (player.x < platform.x + platform.width && player.x + player.width > platform.x && player.y < platform.y + platform.height && player.y + player.height > platform.y && player.velocityY >= 0 && (player.y + player.height - player.velocityY) <= platform.y) {
player.y = platform.y - player.height; player.velocityY = 0; player.isJumping = false;
}
});
gems.forEach(gem => {
if (!gem.collected && player.x < gem.x + gem.width && player.x + player.width > gem.x && player.y < gem.y + gem.height && player.y + player.height > gem.y) {
gem.collected = true; score++; scoreElement.textContent = `Gemas: ${score}`;
}
});
if (player.x < 0) player.x = 0; if (player.x + player.width > GAME_WIDTH) player.x = GAME_WIDTH - player.width;
if (player.y > GAME_HEIGHT) { gameOver = true; showMessage("¡Juego Terminado!"); setTimeout(resetGame, 2000); }
if (gems.every(gem => gem.collected)) { gameOver = true; showMessage("¡Ganaste!"); setTimeout(resetGame, 3000); }
ctx.clearRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
drawPlatforms(); drawGems(); drawPlayer();
requestAnimationFrame(update);
}
function showMessage(text) { messageElement.textContent = text; messageElement.style.display = 'block'; }
function hideMessage() { messageElement.style.display = 'none'; }
function resetGame() {
player.x = 100; player.y = 400; player.velocityX = 0; player.velocityY = 0; player.isJumping = false;
setupGems();
score = 0; scoreElement.textContent = `Gemas: ${score}`;
gameOver = false; hideMessage();
requestAnimationFrame(update);
}
function startGame() {
if (gameStarted) return;
gameStarted = true;
setupGems();
resetGame();
}
</script>
</body>
</html>





Comentarios