Jugable
Apuntarme
Fundamentos

Game feel: por qué tu juego funciona pero se siente muerto

Screenshake, easing, hitstop, coyote time. Los detalles que separan un prototipo funcional de un juego que da gusto jugar.

Tienes el movimiento, las colisiones y el score. Todo funciona. Y se siente como mover un rectángulo por una hoja de cálculo.

Lo que falta no es contenido. Es feedback.

La regla

Cada acción del jugador debe producir más de una respuesta perceptible. Un disparo no es "sale una bala". Un disparo es: la bala sale, el arma retrocede, la cámara tiembla un poco, suena, sale un destello, y el casquillo cae.

Ninguna de esas cosas cambia la lógica del juego. Todas cambian cómo se siente.

Screenshake

El más barato y el más efectivo:

this.cameras.main.shake(100, 0.008)   // duración ms, intensidad

Dos advertencias. Primero, menos es más: 0.008 ya se nota, 0.05 marea. Segundo, escala la intensidad con la importancia del evento — si el disparo tiembla igual que la explosión, dejas de comunicar nada.

Easing

Nada en la naturaleza se mueve a velocidad constante. Si tu UI aparece con un alpha lineal, se ve barata.

this.tweens.add({
  targets: menu,
  y: 200,
  duration: 300,
  ease: 'Back.easeOut'   // se pasa un poco y vuelve
})

Back.easeOut y Elastic.easeOut para cosas que aparecen, Cubic.easeIn para cosas que se van. Esa sola regla ya mejora cualquier menú.

Hitstop

Cuando algo recibe un golpe fuerte, congela el juego 50-80 ms. Suena absurdo y es el truco más poderoso de todos — es de donde sale el peso en los juegos de pelea y en Zelda.

hitstop(ms) {
  this.physics.pause()
  this.time.delayedCall(ms, () => this.physics.resume())
}

El cerebro lo lee como impacto, no como lag.

Coyote time

Este no es estético, es de diseño, y es el que más quejas te ahorra.

Deja que el jugador salte hasta ~100 ms después de haberse caído de la plataforma:

update(time, delta) {
  if (this.player.body.onFloor()) this.coyote = 100
  else this.coyote -= delta

  if (saltoPresionado && this.coyote > 0) {
    this.player.setVelocityY(-450)
    this.coyote = 0
  }
}

Nadie lo nota, todos lo agradecen. Su hermano es el jump buffer: si el jugador pulsa saltar 80 ms antes de tocar el suelo, guarda la intención y salta al aterrizar.

Ambos existen porque el jugador tiene una intención y tu juego debería obedecerla, no castigar 3 frames de imprecisión.

Por dónde empezar

Si sólo vas a añadir tres cosas: easing en todo lo que se mueve en UI, screenshake sutil en los impactos, y coyote time. Es media hora de trabajo y cambia por completo la primera impresión.


La sesión 7 del curso presencial es entera de esto.