/** * PrimitiveTypes — параметрические 3D-примитивы (как Part в Roblox). * * Каждый тип: * id — стабильный ключ * name — отображаемое имя * icon — emoji для палитры * defaultScale — стартовый размер (X, Y, Z) * defaultColor — цвет * * kind: * geometry — обычная видимая фигура (cube/sphere/cylinder/...) * trigger — невидимый объём, события на касание * checkpoint — точка респавна (подсвечена) * * Создание mesh идёт в PrimitiveManager._createMeshForType. */ export const PRIMITIVE_TYPES = [ // === Геометрия === { id: 'cube', name: 'Куб', icon: 'prim-cube', kind: 'geometry', defaultScale: { x: 1, y: 1, z: 1 }, defaultColor: '#9ca3af' }, { id: 'sphere', name: 'Сфера', icon: 'prim-sphere', kind: 'geometry', defaultScale: { x: 1, y: 1, z: 1 }, defaultColor: '#3b82f6' }, { id: 'cylinder', name: 'Цилиндр', icon: 'prim-cylinder', kind: 'geometry', defaultScale: { x: 1, y: 2, z: 1 }, defaultColor: '#f59e0b' }, { id: 'cone', name: 'Конус', icon: 'prim-cone', kind: 'geometry', defaultScale: { x: 1, y: 2, z: 1 }, defaultColor: '#a83232' }, { id: 'plane', name: 'Плоскость', icon: 'prim-plane', kind: 'geometry', defaultScale: { x: 4, y: 0.1, z: 4 }, defaultColor: '#7a8071' }, { id: 'torus', name: 'Тор', icon: 'prim-torus', kind: 'geometry', defaultScale: { x: 1, y: 0.4, z: 1 }, defaultColor: '#22d3ee' }, // Клин — куб со срезанной верхней гранью (наклонная плоскость). // Для пандусов, рамп, крыш. Скос идёт по оси Z (выше при +Z). { id: 'wedge', name: 'Клин', icon: 'prim-wedge', kind: 'geometry', defaultScale: { x: 1, y: 1, z: 1 }, defaultColor: '#9ca3af' }, // Угловой клин — клин со скосом по двум осям (внутренний угол крыши). { id: 'cornerwedge', name: 'Угловой клин', icon: 'prim-cornerwedge', kind: 'geometry', defaultScale: { x: 1, y: 1, z: 1 }, defaultColor: '#9ca3af' }, // === Триггер — невидимая зона === { id: 'trigger', name: 'Триггер', icon: 'prim-trigger', kind: 'trigger', defaultScale: { x: 2, y: 2, z: 2 }, defaultColor: '#ffeb3b' }, // === Чекпоинт — точка респавна === { id: 'checkpoint', name: 'Чек-поинт', icon: 'prim-checkpoint', kind: 'checkpoint', defaultScale: { x: 1, y: 1, z: 1 }, defaultColor: '#10b981' }, // === Лампа — источник света (PointLight) === // Маленькая светящаяся сфера-маркер + привязанный точечный свет. // Свет настраивается в инспекторе: цвет, яркость, радиус. { id: 'light', name: 'Лампа', icon: 'prim-light', kind: 'light', defaultScale: { x: 0.4, y: 0.4, z: 0.4 }, defaultColor: '#ffe9a0' }, // === Эмиттер — постоянный источник частиц (костёр/дым/искры/магия) === // Маркер-сфера + ParticleSystem. Эффект выбирается в инспекторе. { id: 'emitter', name: 'Эмиттер частиц', icon: 'prim-emitter', kind: 'emitter', defaultScale: { x: 0.4, y: 0.4, z: 0.4 }, defaultColor: '#ff8833' }, // === Табличка — 3D-карточка с GUI (как BillboardGui в Roblox) === // Плоскость с натянутой DynamicTexture, на которой рендерится контент // (заголовок, иконка, кнопка). Поддерживает 4 пресета (см. BillboardUiManager): // shop-item, shop-purchase, banner, sign. Может смотреть на камеру // (face=camera) или быть фиксированной (face=fixed). Клик по кнопке // эмитит событие через game.billboard.onClick. { id: 'billboard', name: '3D-табличка', icon: 'prim-billboard', kind: 'billboard', defaultScale: { x: 2, y: 1.2, z: 0.05 }, defaultColor: '#1a1a2e' }, // === GD-порталы (Geometry Dash 2.0) — переключают гейммод игрока === // Все цилиндры-«столбы» с neon-материалом. Цвета и gdMode задают режим. { id: 'gd_cube', name: 'Портал: Куб', icon: 'prim-portal', kind: 'gd_portal', gdMode: 'cube', defaultScale: { x: 0.5, y: 7, z: 0.5 }, defaultColor: '#3366ff' }, { id: 'gd_ship', name: 'Портал: Корабль', icon: 'prim-portal', kind: 'gd_portal', gdMode: 'ship', defaultScale: { x: 0.5, y: 7, z: 0.5 }, defaultColor: '#ff8833' }, { id: 'gd_ball', name: 'Портал: Шар', icon: 'prim-portal', kind: 'gd_portal', gdMode: 'ball', defaultScale: { x: 0.5, y: 7, z: 0.5 }, defaultColor: '#22ff66' }, { id: 'gd_ufo', name: 'Портал: НЛО', icon: 'prim-portal', kind: 'gd_portal', gdMode: 'ufo', defaultScale: { x: 0.5, y: 7, z: 0.5 }, defaultColor: '#44ccff' }, { id: 'gd_wave', name: 'Портал: Волна', icon: 'prim-portal', kind: 'gd_portal', gdMode: 'wave', defaultScale: { x: 0.5, y: 7, z: 0.5 }, defaultColor: '#bb44ff' }, { id: 'gd_robot', name: 'Портал: Робот', icon: 'prim-portal', kind: 'gd_portal', gdMode: 'robot', defaultScale: { x: 0.5, y: 7, z: 0.5 }, defaultColor: '#22ccaa' }, // === GD-объекты уровня === // Шип (cone) — касание = смерть. Можно ставить на полу (остриём вверх) или вращать на потолок. { id: 'gd_spike', name: 'GD: Шип', icon: 'prim-spike', kind: 'gd_spike', defaultScale: { x: 1.3, y: 1.6, z: 1.3 }, defaultColor: '#ff3344' }, // Финиш (cylinder neon) — касание = победа (триггерит showWinScreen в скрипте через событие). { id: 'gd_finish', name: 'GD: Финиш', icon: 'prim-finish', kind: 'gd_finish', defaultScale: { x: 1.2, y: 8, z: 1.2 }, defaultColor: '#ffe44a' }, // Монета (sphere) — касание = +1 монета. { id: 'gd_coin', name: 'GD: Монета', icon: 'prim-coin', kind: 'gd_coin', defaultScale: { x: 0.6, y: 0.6, z: 0.6 }, defaultColor: '#ffd700' }, ]; /** Категории для группировки в палитре. */ export const PRIMITIVE_CATEGORIES = [ { id: 'geometry', name: 'Фигуры', ids: ['cube','sphere','cylinder','cone','plane','torus','wedge','cornerwedge'] }, { id: 'gameplay', name: 'Геймплей', ids: ['trigger', 'checkpoint', 'light', 'emitter', 'billboard'] }, { id: 'gd-portals', name: 'GD-порталы', ids: ['gd_cube','gd_ship','gd_ball','gd_ufo','gd_wave','gd_robot'] }, { id: 'gd-objects', name: 'GD-объекты', ids: ['gd_spike','gd_finish','gd_coin'] }, ]; export function getPrimitiveType(id) { return PRIMITIVE_TYPES.find(t => t.id === id) || PRIMITIVE_TYPES[0]; } // kind-ы примитивов Geometry Dash. Эти типы остаются в PRIMITIVE_TYPES // (нужны движку для загрузки старых GD-проектов и getPrimitiveType), // но НЕ показываются в палитре инструментов. const GD_KINDS = new Set(['gd_portal', 'gd_spike', 'gd_finish', 'gd_coin']); /** * Список примитивов для ПАЛИТРЫ редактора — без GD-инструментов. * Палитра должна рендерить именно его, а не полный PRIMITIVE_TYPES. */ export const PALETTE_PRIMITIVE_TYPES = PRIMITIVE_TYPES.filter( t => !GD_KINDS.has(t.kind) );