Un solo desarrollador puede crear un juego en cuestión de minutos, mientras que un gran equipo puede llevar muchos años, todo depende del alcance, principalmente.
Decidí probarlo y escribí esto en unos 20 minutos: Editar violín – JSFiddle
El objetivo es evitar la colisión entre las cajas blancas y las verdes. Por supuesto, esto no es perfecto: el código es desordenado y solo lo probé en Chrome y una vez que está cargado no se puede cambiar el tamaño de la pantalla sin estirar los gráficos, pero es un juego y solo me llevó 20-25 minutos.

Lo que lleva mucho tiempo es ajustar la configuración hasta que tengas algo que se sienta bien: trabajé en el siguiente juego durante un par de meses, aunque no parece mucho más complicado que el anterior, implica mucho más código:
Aquí está el código completo del juego que creé para esta respuesta:
var lienzo, ctx; // el lienzo en el que se dibujará el juego
var enemigos = []; // todos los enemigos se almacenarán en esta matriz
var startEnemies = 10; // cuantos enemigos al inicio del juego
var maxEnemies = 100; // cantidad máxima de enemigos
var maxEnemySpeed = 5; // qué tan rápido pueden ir
var player = {// el objeto player contiene posición y tamaño
posición: {},
tamaño: 20,
};
puntos var = 0; // Autoexplicativo
var isRunning = true; // ¿se está ejecutando el juego?
var startBtn = document.querySelectorAll (“. start”) [0]; // un par de referencias a las diferentes superposiciones y elementos de la interfaz de usuario
var restartBtn = document.querySelectorAll (“. restart”) [0];
var startOverlay = document.querySelectorAll (“. start-overlay”) [0];
var gameOverOverlay = document.querySelectorAll (“. gameOver-overlay”) [0];
var pointsDisplay = document.querySelectorAll (“. points”) [0];
function Enemy () {// esta función devuelve un nuevo enemigo generado aleatoriamente
regreso {
posición: {
x: Math.random () * canvas.width,
y: 0
},
tamaño: Math.random () * 20,
velocidad: Math.random () * maxEnemySpeed
}
}
función createNewEnemy () {// esto agrega un enemigo a la matriz de enemigos
enemigos.push (nuevo enemigo ());
}
function generateEnemies () {// crea los enemigos iniciales
for (var i = 0; i createNewEnemy ();
}
}
función init () {
lienzo = document.querySelectorAll (“lienzo”) [0]; // obtener una referencia al lienzo
canvas.width = window.innerWidth; // cambia el tamaño del lienzo para que se ajuste a la ventana
canvas.height = window.innerHeight;
ctx = canvas.getContext (“2d”);
player.position = {// establece la posición inicial del jugador
x: canvas.width / 2 – player.size,
y: canvas.height – 100
}
canvas.onmousemove = function (e) {// cuando mueves el mouse cambia la posición del jugador
player.position = {
x: e.pageX,
y: e.pageY
}
}
generateEnemies ();
requestAnimationFrame (paso);
};
function moveEnemies () {// mueve a los enemigos
para (var i = 0, l = enemigos.length; i var enemigo = enemigos [i];
if (enemy.position.y> canvas.height) {// si el enemigo llegó al fondo, muévelo hacia arriba
enemigo.posición.y = 0;
if (enemigos.length createNewEnemy ();
}
puntos ++; // aumentar puntos
} más {
enemigo.posición.y + = enemigo.velocidad; // si no, solo muévelo hacia abajo un poco
}
}
}
function drawEnemies () {// recorre el conjunto de enemigos y dibuja cada uno en el lienzo
ctx.fillStyle = “blanco”;
para (var i = 0, l = enemigos.length; i var enemigo = enemigos [i];
ctx.fillRect (enemigo.posición.x – tamaño.enemigo / 2, enemigo.posición.y – tamaño.enemigo / 2, tamaño.enemigo, tamaño.enemigo);
}
}
function drawPoints () {// escribe en la cantidad de puntos en el fondo
ctx.fillStyle = ‘blanco’;
ctx.font = “60px Helvética”;
ctx.textAlign = “centro”;
ctx.fillText (puntos, canvas.width / 2, canvas.height / 2);
}
function drawPlayer () {// dibuja al jugador al lienzo
ctx.fillStyle = “# bada55”;
ctx.fillRect (player.position.x – player.size / 2, player.position.y – player.size / 2, player.size, player.size);
}
function checkSingleCollision (a, b) {// comprueba si dos cuadrados se cruzan
return (Math.abs (a.position.x – b.position.x) * 2 <(a.size + b.size)) &&
(Math.abs (a.position.y – b.position.y) * 2 <(a.size + b.size));
}
función checkCollisions () {
para (var i = 0, l = enemigos.length; i var enemigo = enemigos [i];
var collide = checkSingleCollision (jugador, enemigo);
si (colisionar) {
juego terminado();
}
}
}
paso de función () {
ctx.clearRect (0, 0, canvas.width, canvas.height);
moveEnemies ();
drawPoints ();
drawPlayer ()
checkCollisions ();
drawEnemies ();
if (isRunning) {
requestAnimationFrame (paso);
}
}
function gameOver () {// cuando se llama a la función gameOver
isRunning = false; // detiene el juego
pointsDisplay.innerHTML = puntos; // establece la cantidad de puntos en la interfaz de usuario
gameOverOverlay.classList.remove (‘oculto’); // muestra el juego superpuesto
}
función start () {
startOverlay.classList.add (‘oculto’); // al inicio ocultar la superposición de inicio
isRunning = true; // comienza el juego
en eso(); // inicializa el juego
}
startBtn.onclick = function () {
comienzo();
}
function cleanUp () {// esto limpia el juego anterior y restablece las variables
puntos = 0;
enemigos = [];
ctx.clearRect (0, 0, canvas.width, canvas.height); // borra el lienzo
}
restartBtn.onclick = function () {
gameOverOverlay.classList.add (‘oculto’);
startOverlay.classList.remove (‘oculto’);
limpiar();
}