Los juegos de plataformas 2D son más complejos que los shooters o puzzles porque requieren física de gravedad, salto preciso, cámara que sigue al personaje y detección de colisiones con el terreno. Cerewro puede generar toda esta mecánica desde una descripción.
Crea un juego de plataformas 2D completo en HTML5 Canvas (800x500):
- Personaje con física: gravedad, salto doble, coyote time (100ms)
- Plataformas sólidas con tilemap 32x32px
- Plataformas móviles (horizontal y vertical)
- Enemigos que caminan de borde a borde (matar saltando encima)
- Monedas coleccionables
- Puntos de checkpoint
- Cámara que sigue al jugador con suavizado
- 3 niveles de dificultad progresiva
- Controles: flechas/WASD + Z para saltar, X para correr
- Sprite animado (idle, run, jump, die) desde spritesheet 64x64
- HUD: monedas, tiempo, vidas
- Efectos: polvo al aterrizar, flash al morir
const GRAVITY = 1500; // px/s²
const JUMP_FORCE = -600; // px/s (negativo = arriba)
const COYOTE_MS = 100; // ms después de caminar por el borde
class Player {
constructor(x, y) {
this.x = x; this.y = y;
this.vx = 0; this.vy = 0;
this.onGround = false;
this.lastOnGround = 0; // timestamp del último frame en suelo
this.jumpsLeft = 2; // doble salto
}
update(dt, keys) {
// Movimiento horizontal
if (keys['ArrowLeft']) this.vx = -200;
else if (keys['ArrowRight']) this.vx = 200;
else this.vx *= 0.8; // fricción
// Gravedad
this.vy += GRAVITY * dt;
// Salto: normal, coyote time o doble salto
const coyote = performance.now() - this.lastOnGround < COYOTE_MS;
if (keys['jump'] && (this.onGround || coyote || this.jumpsLeft > 0)) {
this.vy = JUMP_FORCE;
this.jumpsLeft--;
keys['jump'] = false;
}
this.x += this.vx * dt;
this.y += this.vy * dt;
}
}
class Camera {
constructor(canvas) {
this.x = 0; this.y = 0;
this.width = canvas.width; this.height = canvas.height;
}
follow(target, dt) {
const targetX = target.x - this.width / 2;
const targetY = target.y - this.height / 2;
// Lerp: suavizado exponencial
this.x += (targetX - this.x) * (1 - Math.exp(-8 * dt));
this.y += (targetY - this.y) * (1 - Math.exp(-8 * dt));
}
apply(ctx) { ctx.translate(-Math.round(this.x), -Math.round(this.y)); }
}