Some checks failed
Плеер отстал на несколько задач — игры из студии не открывались с механиками. Перенёс из rublox-studio в движок плеера: Новые файлы движка: - engine/ModalManager.js (задача 04 — модальные сцены) - engine/BillboardUiManager.js (задача 01 — 3D-таблички) Точечный перенос в существующие файлы: - ScriptSandboxWorker.js: namespace game.modal/billboard/environment, скины в game.player, game.gui.tween, _guiHandlerKeys(localId), события modalOpened/modalClosed/skinChanged/billboardClick - GameRuntime.js: команды modal.*/billboard.*/player.setSkin.*/gui.tween + _broadcastSkinsSnapshot/_ensureSkinState + routeGlobalEvent с localId - PlayerController.js: non-humanoid скины (loadNonHumanoid+reloadSkin+ процедурная анимация+pivot-центрирование), setInputBlocked/focusOnTarget, камера задачи 02 (zoom/shift-lock), клавиша B (магазин) - BabylonScene.js: init modalManager/billboardUiManager, методы магазина скинов, чтение scene.skins, modalManager.tick, Esc-приоритет - ScriptSandbox.js: sendSkinsSnapshot - GuiManager.js: поля анимаций задачи 03 (синхронизирован со студией) - PrimitiveTypes.js / PrimitiveManager.js: тип billboard + рендер React-слой (editor-shared): - ModalOverlay.jsx, SkinShopOverlay.jsx (новые) + подключены в KubikonPlayer - GuiOverlay.jsx, GameHud.jsx синхронизированы со студией eslint.config: послабления стилевых правил (no-empty off и т.п.). Локальный build зелёный. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
120 lines
7.9 KiB
JavaScript
120 lines
7.9 KiB
JavaScript
/**
|
||
* 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)
|
||
);
|