47. Aplicaciones en animaciones, interfaces y videojuegos 2D

Una aplicación 2D combina geometría, tiempo y estado. Vectores, matrices, interpolación, curvas y colisiones dejan de ser temas aislados y forman un sistema interactivo coherente.

47.1 Introducción

Una escena interactiva recibe entradas, actualiza su estado, resuelve restricciones y presenta un resultado. La calidad depende tanto de las fórmulas como del orden en que se ejecutan.

Separar lógica, representación y tiempo facilita depurar el sistema y reutilizarlo en interfaces, visualizaciones o juegos.

47.2 El ciclo de una aplicación 2D

entrada → actualización → colisiones → cámara → presentación

Cada cuadro usa el estado anterior para producir uno nuevo. La representación debe leer ese estado sin introducir reglas físicas ocultas.

47.3 Estado y representación

El estado contiene posiciones, velocidades, salud, objetivos y temporizadores. Los elementos SVG representan esos datos mediante atributos como transform, x, y, opacity o d.

estado lógico → atributos visuales

Modificar únicamente la apariencia sin actualizar el estado provoca desincronización con colisiones y controles.

47.4 Delta time y actualización

posición += velocidad·Δt

Δt se mide en segundos y se limita para evitar saltos después de una pausa. Las velocidades se expresan en unidades por segundo, no por fotograma.

47.5 Entrada y movimiento

Las entradas horizontales y verticales forman un vector. Si su longitud supera 1, se normaliza para evitar que el movimiento diagonal sea más rápido:

dirección=input/|input|
velocidad=dirección·rapidez

La entrada describe intención; la velocidad describe el movimiento producido.

47.6 Orientación hacia un objetivo

Para mirar desde P hacia O:

d=O−P
ángulo=atan2(dy,dx)

Si el eje frontal del sprite no apunta hacia la derecha, se agrega una corrección angular fija.

47.7 Cámaras 2D

Una cámara convierte posiciones del mundo en posiciones de pantalla:

Ppantalla=(Pmundo−Ccámara)·zoom+centroPantalla

El seguimiento suavizado usa un factor exponencial para no depender del frame rate. Los límites del mapa evitan mostrar regiones exteriores.

47.8 Interfaces adaptables

Una interfaz mezcla coordenadas absolutas, proporciones y anclajes. Un elemento puede mantenerse a 20 píxeles del borde o centrarse usando la mitad del tamaño disponible.

Anclaje
referencia dentro del contenedor
Pivote
punto local usado para colocar
Escala
adaptación a resolución o densidad

47.9 Barras, medidores y transiciones

Salud, energía y progreso se normalizan al intervalo [0,1]. Ese valor controla ancho, arco, color u opacidad:

progreso=limitar(valor/máximo,0,1)

Interpolar el valor mostrado reduce saltos sin modificar el valor real usado por la lógica.

47.10 Colisiones y respuesta

La detección responde si existe contacto; la respuesta decide qué hacer. Una secuencia robusta es:

  1. Fase amplia con límites simples.
  2. Prueba precisa.
  3. Cálculo de normal y penetración.
  4. Corrección posicional.
  5. Actualización de velocidad y eventos.

47.11 Proyectiles y tiempo de vida

Un proyectil combina posición, dirección, rapidez, radio y duración. Se elimina al impactar, salir del mundo o agotar su tiempo.

vida -= Δt
activo = vida>0 y dentroDelMapa

Reutilizar objetos mediante un pool evita crear y destruir grandes cantidades de memoria.

47.12 Partículas y efectos

Las partículas son pequeños estados independientes con vida limitada. Su opacidad y escala suelen depender de la edad normalizada:

edad=1−vidaRestante/vidaInicial
opacidad=1−edad

Ruido controlado, gravedad y colores interpolados producen explosiones, humo, chispas y estelas.

47.13 Laboratorio: integra movimiento, cámara e interfaz

Controla el objetivo de la nave. La cámara la sigue con suavizado y la interfaz permanece anclada a la pantalla aunque el mundo se desplace.

ENERGÍAHUD anclado a pantalla
Nave · mundo(0,0)
Cámara · mundo(0,0)
Distancia al objetivo0

47.14 Bucle de actualización en JavaScript

let anterior=performance.now();
const jugador={x:0,y:0,vx:120,vy:40};

function actualizar(ahora) {
  const dt=Math.min((ahora-anterior)/1000,0.05);
  anterior=ahora;
  jugador.x+=jugador.vx*dt;
  jugador.y+=jugador.vy*dt;
  console.log(`Posición: (${jugador.x.toFixed(2)}, ${jugador.y.toFixed(2)})`);
}

actualizar(anterior+16.67);

La llamada simula un cuadro y muestra la nueva posición sin iniciar un ciclo infinito en el ejecutor.

47.15 Movimiento normalizado y cámara

function mover(pos,input,rapidez,dt) {
  const longitud=Math.hypot(input.x,input.y);
  if (longitud>0) {
    pos.x+=input.x/longitud*rapidez*dt;
    pos.y+=input.y/longitud*rapidez*dt;
  }
}

function seguir(actual,objetivo,respuesta,dt) {
  const k=1-Math.exp(-respuesta*dt);
  return actual+(objetivo-actual)*k;
}

const jugador={x:0,y:0};
mover(jugador,{x:1,y:1},120,1/60);
const camara={x:seguir(0,jugador.x,4,1/60),y:seguir(0,jugador.y,4,1/60)};
console.log({jugador,camara});

La normalización evita ventaja diagonal y el seguimiento se mantiene estable frente al frame rate.

47.16 Actualizar una interfaz

function limitar(v,min,max) {
  return Math.max(min,Math.min(max,v));
}

function datosBarra(valor,maximo,ancho) {
  const progreso=limitar(valor/maximo,0,1);
  return {
    progreso,
    anchoVisible:ancho*progreso,
    porcentaje:Math.round(progreso*100)
  };
}

console.log(datosBarra(68,100,240));
// {progreso:0.68, anchoVisible:163.2, porcentaje:68}

La lógica devuelve datos neutrales que luego pueden aplicarse a SVG, HTML u otro sistema de presentación.

47.17 Aplicación animada: misión de rescate

La nave patrulla, detecta objetivos circulares, dispara pulsos y actualiza el HUD. La escena reúne curvas, orientación, cámara, colisiones puntuales y partículas.

Objetivos rescatados: 0/3Estado: patrullando

47.18 Arquitectura, errores y conclusión

Una aplicación mantenible separa datos, sistemas y presentación. Movimiento, colisiones, cámara y HUD leen y escriben partes bien definidas del estado.

  • Mezclar unidades por segundo con unidades por cuadro.
  • Actualizar la representación pero no la región de colisión.
  • Usar coordenadas de pantalla como si fueran coordenadas del mundo.
  • Ejecutar la cámara antes de actualizar al objetivo.
  • Acumular un Δt enorme después de una pausa.
  • Crear objetos indefinidamente para partículas y proyectiles.
  • Resolver la misma colisión varias veces sin separar cuerpos.
  • Acoplar reglas del juego a elementos visuales concretos.

Recuerda: entrada, simulación y presentación cumplen responsabilidades distintas; Δt estabiliza el movimiento; las transformaciones conectan espacios; y una arquitectura clara permite combinar todas las herramientas matemáticas.

En el próximo tema construiremos el proyecto integrador de gráficos 2D.