Cómo evitar que los controles de teclado interfieran con el deslizamiento de un rompecabezas controlado por ratón
Si está creando un rompecabezas deslizante basado en navegador como apoyo para juegos de rol de mesa, haga que el arrastre con el ratón y los movimientos con el teclado operen sobre el mismo estado del rompecabezas, manteniendo al mismo tiempo los atajos de teclado limitados al rompecabezas. Las comprobaciones clave son el foco, la gestión de eventos y la finalización del arrastre: pulsar una tecla en un campo de texto no debería mover una pieza, y un arrastre no debería interrumpirse ni perderse cuando el cursor cruce el límite de una pieza.
Comience por identificar qué está moviendo el rompecabezas de forma inesperada
Cuando un rompecabezas reacciona a una tecla de flecha durante una operación con el ratón, la causa suele ser un detector de eventos de teclado (listener) demasiado amplio. Un manejador asignado a document o window puede recibir eventos de las teclas de flecha incluso cuando el jugador está escribiendo en un campo de pistas, usando un menú o interactuando con otro control. También puede desencadenar comportamientos del navegador, como el desplazamiento de la página (scroll), al mismo tiempo que modifica el rompecabezas.
Reproduzca el problema con una breve lista de comprobación: haga clic en una pieza y arrástrela; arrástrela más allá del límite del rompecabezas; pulse una tecla de flecha mientras el rompecabezas tiene el foco; luego pulse una mientras un campo de entrada de pistas, un botón o un menú tenga el foco. Observe si el tablero cambia, la página se desplaza, el foco se mueve o el arrastre se detiene. Estas observaciones permiten distinguir un problema en el manejador del rompecabezas del seguimiento del puntero o del comportamiento predeterminado del navegador.
Establezca un límite de foco explícito para el rompecabezas
Trate el tablero como un control con un punto de entrada de teclado claro. Utilice un contenedor de tablero que pueda recibir el foco y procese las teclas del rompecabezas únicamente cuando ese tablero esté activo, o cuando el foco esté en una pieza que pertenezca al tablero. Mantenga los controles no relacionados, como los botones de pistas y los campos de texto, fuera de ese límite de gestión de teclas. Haga visible la ubicación del foco para que el jugador pueda saber cuándo responderá el tablero.
Compruebe el destino del evento (event target) antes de interpretar una tecla. Si el foco está en un campo de entrada, un área de texto, un elemento editable o un botón independiente, no procese la tecla. En una herramienta de aventuras cooperativa, esto es fundamental cuando un jugador está introduciendo una runa, un nombre o una pista mientras otra persona manipula el rompecabezas: escribir no debería traducirse en un movimiento accidental de piezas.
El manejo mediante teclado sigue siendo necesario. La guía del W3C explica que la funcionalidad debe estar disponible a través de una interfaz de teclado siempre que sea posible, e identifica el desplazamiento de objetos a una ubicación como una acción que se puede operar mediante el teclado. Delimite con cuidado el alcance de las teclas en lugar de eliminarlas por completo. W3C: Understanding Success Criterion 2.1.1: Keyboard
Separe los comandos del rompecabezas de las acciones predeterminadas del navegador
Elija un conjunto pequeño y documentado de teclas para el tablero, como las teclas de flecha cuando el tablero tiene el foco. En el manejador, confirme primero que la tecla sea una de las que utiliza el rompecabezas y que el tablero sea el objetivo activo. Solo entonces aplique el movimiento y, si es necesario, cancele la acción predeterminada del navegador para esa tecla. Evite suprimir todas las teclas de forma global: los jugadores pueden necesitar escribir con normalidad, navegar por el navegador y utilizar controles situados fuera del rompecabezas.
preventDefault() cancela la acción predeterminada del navegador cuando el evento es cancelable, pero no impide que el evento se propague a otros manejadores. Eso significa que puede evitar el desplazamiento de la página sin solucionar que un segundo detector también mueva una pieza. Localice y restrinja el manejador que altera el estado del juego; no utilice la cancelación generalizada como sustituto de una asignación clara de eventos. MDN: Event: preventDefault() method
Mantenga intacto el arrastre del puntero por todo el tablero
Para una interacción de arrastre, rastree un único puntero activo desde la pulsación que inicia el arrastre hasta que se suelta o se cancela. Los eventos de puntero (pointer events) proporcionan pointerdown, pointermove, pointerup y pointercancel; la captura de puntero (pointer capture) puede mantener los eventos de puntero posteriores dirigidos al tablero incluso cuando el puntero sale de su área de impacto original. Cancele el arrastre activo tanto en pointerup como en pointercancel, para que un gesto interrumpido no deje el rompecabezas atascado en estado de arrastre. MDN: Pointer events
Evite reconstruir o sustituir la pieza arrastrada de forma que se pierda el seguimiento del puntero. Si la interfaz mueve un elemento en el DOM durante el arrastre, MDN señala que la captura de puntero debe configurarse después de dicho movimiento. Decida qué sucede cuando se suelta el puntero sobre una posición no válida: en un rompecabezas deslizante, restaurar la pieza a su posición anterior o ajustarla a una posición válida resulta más fácil de entender que modificar de forma imprevista piezas no relacionadas.
Haga que el mismo movimiento esté disponible sin necesidad de arrastrar
Un rompecabezas puede admitir la entrada combinada de ratón, teclado y gestos simples de puntero. Por ejemplo, hacer clic o tocar una pieza adyacente al espacio vacío podría moverla; arrastrar esa pieza podría seguir siendo un gesto opcional de manipulación directa; y las teclas de flecha con el tablero enfocado podrían proporcionar el manejo por teclado. Todas estas entradas deben invocar la misma lógica de validación de movimientos, de modo que un movimiento se considere válido o se rechace de manera coherente, independientemente de cómo se haya solicitado.
Esto también proporciona un criterio de diseño útil: ¿puede un jugador completar el rompecabezas mediante clics o toques sin arrastrar? Las directrices WCAG 2.2 del W3C tratan el acceso mediante teclado y la alternativa de puntero único al arrastre como requisitos independientes. Entre sus ejemplos se incluye la sustitución del arrastre por clics en controles direccionales. Una alternativa exclusiva para teclado no satisface por sí misma dicha alternativa de puntero. W3C: Understanding Success Criterion 2.5.7: Dragging Movements
En un rompecabezas deslizante, hacer clic en una pieza adyacente por vez suele ser una alternativa natural porque preserva la regla de movimiento a posiciones contiguas. Si esa interacción pudiera resultar confusa, el uso de botones de movimiento visibles puede indicar claramente la dirección disponible. La técnica G219 del W3C ofrece ejemplos de controles de puntero único que ejecutan la misma acción subyacente sin necesidad de arrastrar. W3C: G219: Ensuring that an alternative is available for dragging movements that operate on content
Pruebe con una matriz de entrada breve
Antes de utilizar el rompecabezas en una partida, compruebe cada vía de entrada con la misma disposición del tablero y el mismo estado inicial. Confirme que un movimiento válido actualice el tablero una sola vez, que un movimiento no válido lo deje sin cambios y que los controles no relacionados conserven su comportamiento normal.
Ratón: arrastre una pieza válida, suéltela fuera del tablero e intente un movimiento no válido. Confirme que el tablero no pierde el arrastre ni cambia de manera imprevista.
Teclado: sitúe el foco en el tablero, use cada dirección admitida, luego traslade el foco a un campo de texto y escriba. Confirme que solo las teclas con el tablero enfocado mueven piezas y que escribir no desplaza la página ni modifica el tablero.
Puntero sin arrastre: haga clic o toque en una pieza adyacente válida. Confirme que produce el mismo movimiento que los otros métodos de entrada.
Interrupción: cancele o abandone un arrastre y luego inicie otro. Confirme que no quede ninguna selección residual.
Si una prueba falla, inspeccione primero la capa pertinente más específica: el elemento de destino del evento (event target) y el estado de foco para el comportamiento del teclado; la captura de puntero y la limpieza de eventos para los arrastres interrumpidos; y el validador de movimientos compartido para reglas inconsistentes. Esta secuencia ofrece al creador una forma concreta de localizar el problema sin transformar el accesorio de la aventura en un tutorial general sobre controles.
