Cuando jugamos a nuestros juegos favoritos, rara vez pensamos en lo que hay detrás del movimiento suave del personaje, los saltos realistas o las colisiones con obstáculos. Pero detrás de todo esto se esconde el fascinante mundo de la física del juego: un modelo simplificado del mundo real que los programadores crean con la ayuda de las matemáticas y el código.

Fundamentos del movimiento: velocidad y posición
En la base de cualquier movimiento en el juego se encuentran dos conceptos simples: la posición del objeto y su velocidad. Imagina que tu personaje tiene coordenadas X e Y en la pantalla. Cada fotograma del juego (generalmente ocurre 60 veces por segundo) actualizamos estas coordenadas, agregándoles el valor de la velocidad.
// El movimiento más simple
player.x += player.velocityX;
player.y += player.velocityY;Pero en los juegos reales todo es un poco más complicado. Tenemos que tener en cuenta el tiempo entre fotogramas (deltaTime) para que el movimiento sea fluido independientemente del rendimiento del ordenador:
player.x += player.velocityX * deltaTime;
player.y += player.velocityY * deltaTime;Ahora, si el juego funciona a 30 o 120 FPS, el personaje se moverá a la misma velocidad en tiempo real.
Gravedad: lo que hace que todo caiga
La gravedad en los juegos es una aceleración constante hacia abajo. En cada cuadro, añadimos un pequeño valor a la velocidad vertical del objeto, creando el efecto de caída:
const GRAVITY = 0.5;
// En cada fotograma
player.velocityY += GRAVITY;
player.y += player.velocityY;
// Comprobamos si el personaje ha caído al suelo
if (player.y >= ground.y) {
player.y = ground.y;
player.velocityY = 0;
player.isOnGround = true;
}Es interesante que en la mayoría de los juegos la gravedad es mucho más fuerte que la física real. Esto hace que el juego sea más dinámico y sensible. Mario, por ejemplo, cae cuatro veces más rápido de lo que lo haría en la realidad.
Saltos: impulso y control en el aire
El salto es simplemente un cambio instantáneo de la velocidad vertical en la dirección negativa (hacia arriba). Cuando el jugador pulsa el botón de salto, establecemos velocityY en un valor negativo, y la gravedad ralentiza gradualmente el ascenso, despliega al personaje y hace que caiga hacia atrás.
function jump() {
if (player.isOnGround) {
player.velocityY = -12; // Fuerza de salto
player.isOnGround = false;
}
}Pero un simple salto puede parecer "de madera". En los videojuegos de plataformas buenos se utilizan técnicas adicionales: salto de altura variable (cuanto más tiempo mantienes pulsado el botón, más alto saltas), «tiempo de coyote» (puedes saltar una fracción de segundo después de haber salido de la plataforma) y control en el aire (una pequeña oportunidad para controlar al personaje durante el vuelo).
// Salto de altura variable
function updateJump() {
if (!jumpButtonHeld && player.velocityY < 0) {
player.velocityY *= 0.5; // Dejamos de subir más rápido
}
}Colisiones: cómo los objetos detectan una colisión
Las colisiones son una comprobación de si dos objetos se cruzan en el espacio. La forma más fácil es usar bordes rectangulares (bounding boxes). Dos rectángulos se cruzan si sus lados se superponen:
function checkCollision(rect1, rect2) {
return rect1.x < rect2.x + rect2.width &&
rect1.x + rect1.width > rect2.x &&
rect1.y < rect2.y + rect2.height &&
rect1.y + rect1.height > rect2.y;
}Pero detectar una colisión es solo la mitad de la batalla. También es necesario reaccionar correctamente ante ella. Esto se denomina resolución de colisiones (collision resolution). La forma más fácil es mover el objeto hacia atrás para que no se cruce con el obstáculo:
if (checkCollision(player, wall)) {
// Determinamos de qué lado ocurrió la colisión
const overlapX = Math.min(
player.x + player.width - wall.x,
wall.x + wall.width - player.x
);
const overlapY = Math.min(
player.y + player.height - wall.y,
wall.y + wall.height - player.y
);
// Repelimos a lo largo del eje con menos superposición
if (overlapX < overlapY) {
player.x += player.velocityX > 0 ? -overlapX : overlapX;
player.velocityX = 0;
} else {
player.y += player.velocityY > 0 ? -overlapY : overlapY;
player.velocityY = 0;
}
}Conceptos avanzados
Cuando se domina la física básica, se abre todo un mundo de posibilidades. Se puede añadir la fricción, que ralentiza los objetos con el tiempo. Se pueden realizar colisiones elásticas, donde los objetos rebotan entre sí, teniendo en cuenta su masa y velocidad. Se puede crear un sistema de partículas para efectos como humo, chispas o salpicaduras de agua.
Muchos motores modernos proporcionan sistemas físicos listos para usar: Unity usa PhysX, Godot tiene un motor físico incorporado y para el desarrollo web están Matter.js y Cannon.js. Pero comprender los principios básicos te ayudará a usar estas herramientas de manera efectiva y resolver problemas no estándar.
Consejos prácticos
Empieza con algo simple: crea un cuadrado que caiga y pueda saltar. A continuación, añade plataformas y colisiones. Experimenta con las constantes: cambia la fuerza de la gravedad, la altura del salto, la velocidad de movimiento. Te sorprenderá cómo los pequeños cambios afectan la sensación del juego.
La física del juego no tiene que ser realista, debe ser divertida y predecible. Angry Birds, por ejemplo, ignora por completo la resistencia del aire, porque así es más interesante jugar. Tu tarea como desarrollador es encontrar un equilibrio entre la credibilidad y la jugabilidad.
¿Quieres profundizar en el desarrollo de juegos y aprender a crear tus propios proyectos desde cero?
En Codice hemos preparado cursos prácticos de programación, donde pasarás de los conceptos básicos a la creación de juegos completos. Aprende JavaScript, Python, Lua y mucho más en un formato cómodo con explicaciones paso a paso.
Y también tenemos un genial canal de Telegram ¡con una comunidad de desarrolladores amigable! Allí discutimos tecnologías interesantes, compartimos experiencias, nos ayudamos mutuamente con las tareas y simplemente hablamos sobre temas de programación.
¡Únete a nosotros y crece junto a personas afines! 🚀
