Desarrollé un juego completo de supervivencia desde cero utilizando HTML5 Canvas, JavaScript vanilla y CSS3. El juego implementa un sistema de colisiones complejo, animaciones con sprites, sistema de vida dinámico, enemigos con movimiento direccional, y mecánicas de disparo direccional con cálculo trigonométrico.
Implementar detección de colisiones entre múltiples elementos (jugador, enemigos, balas, bonificaciones) con diferentes tamaños y velocidades en tiempo real.
Creé funciones específicas para cada tipo de colisión usando coordenadas rectangulares y cálculos matemáticos precisos para detectar intersecciones entre elementos del juego.
Sistema robusto que maneja colisiones en tiempo real entre 6+ tipos de elementos diferentes sin errores de detección.
Crear enemigos que se muevan hacia el jugador de forma fluida y natural usando cálculos matemáticos.
Implementé algoritmos de normalización vectorial y cálculo trigonométrico para que los enemigos se muevan directamente hacia el jugador con velocidades diferenciadas.
Dos tipos de enemigos con velocidades distintas (PythonEnemy: 1, OctoEnemy: 2.5) que persiguen al jugador de forma fluida usando vectores normalizados.
Crear animaciones fluidas para todos los elementos del juego usando sprites con diferentes números de frames y sincronización.
Desarrollé un sistema de animación basado en frames que sincroniza todas las animaciones con el loop principal del juego a 60 FPS usando índices de frames.
Animaciones sincronizadas para jugador (4 frames), enemigos (5-7 frames), balas (3 frames) y bonificaciones (4 frames) que funcionan perfectamente.
Crear un loop de juego eficiente que maneje renderizado, lógica, colisiones y audio sin afectar el rendimiento.
Implementé un game loop con setInterval optimizado que ejecuta todas las operaciones del juego cada 20ms (50 FPS) con gestión eficiente de memoria.
Juego fluido que mantiene 60 FPS de animación con gestión eficiente de recursos y sin memory leaks.
Permite al jugador disparar en cualquier dirección haciendo clic en el canvas, calculando automáticamente el ángulo y trayectoria de la bala usando trigonometría (atan2, cos, sin).
Barra de vida visual que cambia en tiempo real según el daño recibido, con imágenes predefinidas que representan diferentes niveles de salud del jugador (0%, 20%, 40%, 60%, 80%, 100%).
Integración de efectos de sonido para disparos y música de fondo con control de volumen (0.2) y loop automático para mejorar la experiencia del jugador.
Cuenta regresiva de 30 segundos que controla la duración del juego y activa automáticamente la pantalla de victoria cuando se completa el tiempo, con formato visual de 2 dígitos.
Sistema completo de estados que maneja el inicio, juego activo, game over y victoria con pantallas específicas, imágenes de resultado y funcionalidad de reinicio.
Sistema completo de carga y renderizado de sprites con diferentes números de frames, animación sincronizada y gestión eficiente de memoria para todos los elementos visuales.
Sistema robusto de detección de colisiones que maneja 4 tipos diferentes de interacciones entre elementos del juego usando cálculos matemáticos precisos.
// Sistema de detección de colisiones
function checkCollision(obj1, obj2) {
const dx = obj1.x - obj2.x;
const dy = obj1.y - obj2.y;
const distance = Math.sqrt(dx * dx + dy * dy);
return distance < (obj1.radius + obj2.radius);
}
// Colisión específica para balas con enemigos
function checkBulletEnemyCollision(bullet, enemy) {
if (checkCollision(bullet, enemy)) {
enemy.health -= bullet.damage;
bullet.destroy = true;
return true;
}
return false;
}
// Colisión jugador con bonificaciones
function checkPlayerBonusCollision(player, bonus) {
if (checkCollision(player, bonus)) {
player.health = Math.min(100, player.health + bonus.healAmount);
bonus.destroy = true;
return true;
}
return false;
}Sistema de movimiento direccional que hace que los enemigos persigan al jugador usando vectores normalizados y velocidades diferenciadas.
// Movimiento de enemigos hacia el jugador
class Enemy {
constructor(x, y, speed, type) {
this.x = x;
this.y = y;
this.speed = speed;
this.type = type;
}
update(player) {
// Calcular dirección hacia el jugador
const dx = player.x - this.x;
const dy = player.y - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);
// Normalizar vector y aplicar velocidad
if (distance > 0) {
this.x += (dx / distance) * this.speed;
this.y += (dy / distance) * this.speed;
}
}
}
// Crear enemigos con diferentes velocidades
const pythonEnemy = new Enemy(x, y, 1, 'python');
const octoEnemy = new Enemy(x, y, 2.5, 'octopus');Sistema de disparo que calcula automáticamente la dirección y trayectoria de las balas usando trigonometría (atan2, cos, sin) basado en la posición del clic del mouse.
// Sistema de disparo direccional
class Bullet {
constructor(x, y, targetX, targetY, speed) {
this.x = x;
this.y = y;
this.speed = speed;
// Calcular ángulo hacia el objetivo
const dx = targetX - x;
const dy = targetY - y;
this.angle = Math.atan2(dy, dx);
}
update() {
// Mover bala usando trigonometría
this.x += Math.cos(this.angle) * this.speed;
this.y += Math.sin(this.angle) * this.speed;
}
}
// Manejar clic del mouse para disparar
canvas.addEventListener('click', (e) => {
const rect = canvas.getBoundingClientRect();
const targetX = e.clientX - rect.left;
const targetY = e.clientY - rect.top;
const bullet = new Bullet(player.x, player.y, targetX, targetY, 5);
bullets.push(bullet);
});