Cómo añadir un cursor personalizado
Este tutorial fue escrito en febrero de 2026, para la v2 del motor.
La mayoría de los juegos se ven mejor con un cursor personalizado. La flecha predeterminada del navegador grita "página web" — rompe toda la estética pixel-art. Cambiarla por tu propio sprite es rápido y marca una gran diferencia.
Necesitamos tres cosas: ocultar el cursor predeterminado, definir un sprite de cursor y dibujarlo en la posición del ratón en cada frame.
Ocultar el cursor predeterminado
Llama a cursor(false) en tu función init() para ocultar el cursor del navegador. Internamente, establece cursor: none en el CSS del canvas.
// inside init()
cursor(false);
// the browser cursor is now hidden over the canvas
// call cursor() to restore it, or cursor('pointer') for a CSS cursor
Puedes restaurarlo en cualquier momento — cursor() devuelve la flecha predeterminada, y cursor('pointer') o cualquier otro valor CSS de cursor también funciona. Útil si tu juego tiene menús que se sienten mejor con un cursor normal.
Definir un sprite de cursor
Los sprites en Floaty son arrays de 8x8 valores de color. Cada número corresponde a un color de la paleta (0–15), y -1 significa transparente. Aquí hay un cursor de flecha — 7 (blanco) rellena la forma, 0 (negro) la delinea:
const sprites = {
cursor: [
7, 0, -1, -1, -1, -1, -1, -1,
7, 7, 0, -1, -1, -1, -1, -1,
7, 7, 7, 0, -1, -1, -1, -1,
7, 7, 7, 7, 0, -1, -1, -1,
7, 7, 7, 7, 7, 0, -1, -1,
7, 7, 0, 0, 0, 0, -1, -1,
7, 0, 0, -1, -1, -1, -1, -1,
0, 0, -1, -1, -1, -1, -1, -1,
],
};
Lee el array de arriba a abajo, de izquierda a derecha, y verás cómo la flecha toma forma: un solo píxel en la esquina superior izquierda, ensanchándose fila por fila, y luego estrechándose. Pasamos el objeto sprites a start() para que el motor lo conozca.
Consejo: Puedes diseñar sprites visualmente en el editor de sprites — dibuja tu cursor píxel a píxel, luego copia el array con Ctrl+C (o Cmd+C en Mac).
Dibujar el cursor
Solo queda dibujarlo. Llama a mouse() para obtener la posición actual como { x, y }, luego spr() para dibujar el sprite ahí:
engine.scope(({ start, cls, spr, mouse, cursor }) => {
const sprites = {
cursor: [
7, 0, -1, -1, -1, -1, -1, -1,
7, 7, 0, -1, -1, -1, -1, -1,
7, 7, 7, 0, -1, -1, -1, -1,
7, 7, 7, 7, 0, -1, -1, -1,
7, 7, 7, 7, 7, 0, -1, -1,
7, 7, 0, 0, 0, 0, -1, -1,
7, 0, 0, -1, -1, -1, -1, -1,
0, 0, -1, -1, -1, -1, -1, -1,
],
};
function init() {
cursor(false);
}
function draw() {
cls(12);
const pos = mouse();
spr('cursor', pos.x, pos.y);
}
start({ sprites, sounds: {}, init, draw, target });
});
El motor convierte las coordenadas de pantalla a coordenadas del canvas por ti, así que mouse() devuelve valores en el mismo espacio de 128x128 píxeles en el que dibujas. La esquina superior izquierda del sprite cae en la posición del ratón — se siente natural para una flecha ya que la "punta" está arriba a la izquierda.
Para ir más allá
No todas las formas de cursor funcionan con alineación arriba-izquierda. Una cruceta debería estar centrada en la posición del ratón — resta la mitad del tamaño del sprite de cada coordenada:
const sprites = {
crosshair: [
-1, -1, -1, 7, -1, -1, -1, -1,
-1, -1, -1, 7, -1, -1, -1, -1,
-1, -1, -1, 7, -1, -1, -1, -1,
7, 7, 7, -1, 7, 7, 7, -1,
-1, -1, -1, 7, -1, -1, -1, -1,
-1, -1, -1, 7, -1, -1, -1, -1,
-1, -1, -1, 7, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
],
};
// in draw(), center the crosshair on the mouse position:
const pos = mouse();
spr('crosshair', pos.x - 3, pos.y - 3);
Algunas direcciones que podrías tomar:
- Cursores animados — define múltiples frames de sprite y alterna entre ellos con un contador
- Cursores sensibles al contexto — cambia el sprite según sobre qué se encuentra el ratón (una mano para botones, una cruceta al apuntar)
- Estelas de cursor — almacena las últimas posiciones del ratón en un array y dibuja copias desvanecidas del sprite en cada una