Todos los capítulos · Capítulo 4/9

Que la muevas tú

Arrancando

Haz clic en el juego y pulsa ← y →. Ya la controlas tú.

const keys = useKeyboard();
 
useUpdate((dt) => {
    if (keys.isDown('ArrowLeft')) paddle.transform.x -= PADDLE_SPEED * dt;
    if (keys.isDown('ArrowRight')) paddle.transform.x += PADDLE_SPEED * dt;
 
    paddle.transform.x = Math.min(Math.max(paddle.transform.x, 0), WIDTH - PADDLE_W);
});

El teclado se pregunta, no se escucha

useKeyboard no te avisa cuando alguien pulsa una tecla. Te da un objeto al que preguntas por su estado cuando te venga bien:

keys.isDown('ArrowLeft')   // ¿está pulsada AHORA MISMO?

Esto se llama sondeo, y es lo que quieres en un juego. Con eventos tendrías que apuntarte en algún sitio que la tecla está pulsada, borrarlo al soltarla, y acordarte de limpiarlo si la ventana pierde el foco. Preguntando, la respuesta es siempre la verdad del fotograma que estás dibujando.

Los nombres son los del navegador: 'ArrowLeft', 'ArrowRight', 'Enter', ' ' para el espacio. Las letras sueltas no distinguen mayúsculas: isDown('a') es lo mismo que isDown('A').

Hay dos preguntas más que te van a hacer falta pronto: justPressed(tecla), que es cierta durante un solo fotograma por pulsación, y justReleased(tecla). Con isDown, un disparo saldría sesenta veces por segundo mientras dejas el dedo apoyado; con justPressed, sale una vez por pulsación.

La línea que no parece importante

paddle.transform.x = Math.min(Math.max(paddle.transform.x, 0), WIDTH - PADDLE_W);

Quita esa línea y mantén pulsada la flecha izquierda: la pala se va de la pantalla y no vuelve. Es el tipo de fallo que no rompe nada, no da ningún error, y arruina la partida.

Léela de dentro hacia fuera:

Y el borde derecho es WIDTH - PADDLE_W, no WIDTH, por lo del capítulo 2: la x es la esquina izquierda de la pala, así que hay que dejarle sitio a su propio ancho.

Esto se llama acotar un valor, y lo vas a escribir muchísimas veces.

¿Qué es un `if`?

Un if ejecuta algo solo cuando se cumple una condición:

if (keys.isDown('ArrowLeft')) paddle.transform.x -= 5;

Se lee tal cual: si la flecha izquierda está pulsada, réstale 5 a la x. Si no lo está, esa línea se salta y no pasa nada.

Fíjate en que aquí hay dos if seguidos, no un if/else. Es deliberado: así, si alguien pulsa las dos flechas a la vez, se ejecutan las dos y la pala se queda quieta, que es razonable. Con else, ganaría siempre la izquierda.

Ahora tú

Cambia 'ArrowLeft' y 'ArrowRight' por 'a' y 'd'. Añade un tercer if con la barra espaciadora (' ') que haga la pala más ancha mientras la mantienes pulsada.

Y quita la línea de Math.min/Math.max una vez, a ver la cara que se le queda.