Newer
Older
rpg / v2 / apps / game / src / deer.ts
/**
 * Воксельный олень (безгласная фауна v1, воксельная версия): тихая
 * серо-бурая живность у прудов. Модель строится по мировому центру (cx, cz)
 * вдоль оси X; шаг (step) поднимает диагональные пары ног — грубый, но
 * живой walk-цикл. Ориентация по направлению не крутится (визуальное
 * приближение допустимо: у v1 спрайт всего с 2 кадрами).
 */
import { GROUND_Y } from './areas';

/** Воксель позы: позиция в мире + цвет-строка (как у VoxelCloud). */
export interface DeerVoxel {
    pos: [number, number, number];
    color: string;
}

const BODY = '#6e6156'; // серо-бурый бок
const DARK = '#54493f'; // копыта, нос, тень брюха
const LIGHT = '#7d7264'; // спина, хвост
const ANTLER = '#8a7a66'; // рога (сухое дерево)

/**
 * Олень в мировых координатах: тело вдоль X, ноги на земле (GROUND_Y),
 * высота ~7 вокселей (герой — 10). step — фаза шага (0/1), поднимает
 * диагональные пары ног.
 */
export function deerVoxels(cx: number, cz: number, step: boolean): DeerVoxel[] {
    const out: DeerVoxel[] = [];
    const put = (dx: number, dy: number, dz: number, color: string) => {
        out.push({ pos: [cx + dx, dy, cz + dz], color });
    };
    // Ноги: диагональные пары (перед-лево + зад-право) поднимаются на шаге.
    const lift = step ? 1 : 0;
    for (const [lx, lz] of [[-1, -1], [2, 1], [-1, 1], [2, -1]] as const) {
        const up = (lx === -1) === (lz === -1) ? lift : 0; // диагональ шагает
        put(lx, GROUND_Y + up, lz, DARK);
        put(lx, GROUND_Y + 1 + up, lz, DARK);
    }
    // Туловище: 5×2×3, спина светлее.
    for (let dx = -2; dx <= 2; dx++)
        for (let dz = -1; dz <= 1; dz++) {
            put(dx, GROUND_Y + 2, dz, dx % 2 === 0 ? BODY : DARK);
            put(dx, GROUND_Y + 3, dz, LIGHT);
        }
    // Шея и голова: вперед-вверх, нос темный, уши-рожки.
    put(3, GROUND_Y + 3, 0, BODY);
    put(3, GROUND_Y + 4, 0, BODY);
    put(4, GROUND_Y + 5, 0, BODY);
    put(5, GROUND_Y + 5, 0, DARK); // нос
    put(3, GROUND_Y + 6, 0, LIGHT);
    put(4, GROUND_Y + 6, -1, ANTLER);
    put(4, GROUND_Y + 6, 1, ANTLER);
    // Хвост.
    put(-3, GROUND_Y + 3, 0, LIGHT);
    return out;
}