Cómo añadir un cursor personalizado
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. Lee la posición del ratón con mouse() en update(), luego dibuja el sprite ahí en draw():
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,
],
};
let pos = { x: 0, y: 0 };
function init() {
cursor(false);
}
function update() {
pos = mouse();
}
function draw() {
cls(12);
spr('cursor', pos.x, pos.y);
}
start({ sprites, sounds: {}, init, update, 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 update(), read the mouse position:
pos = mouse();
// in draw(), center the crosshair on it:
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