From e3e596024143bfdffd537f209690b9d5db32f9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=98=D0=9D?= Date: Sat, 30 May 2026 21:45:57 +0300 Subject: [PATCH 1/2] =?UTF-8?q?feat:=203D-=D1=81=D1=82=D1=80=D0=B5=D0=BB?= =?UTF-8?q?=D0=BA=D0=B0-=D1=83=D0=BA=D0=B0=D0=B7=D0=B0=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=20(game.fx.pointer)=20+=20is=5Ftest=20+=20Ctrl+V=20?= =?UTF-8?q?=D0=B2=20=D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B5?= =?UTF-8?q?=20+=20=D0=B2=D0=B8=D0=BA=D0=B8-=D0=BA=D0=B0=D1=80=D1=82=D0=BE?= =?UTF-8?q?=D1=87=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - game.fx.pointer: лента бегущих шевронов + парящий quest-marker над целью (конус остриём вниз, свечение, bob+вращение, обводка); presets guide/quest/ danger/gift/custom; расширенный game.fx.beam (8 текстур, curved, градиент). - Примитив pointer в палитре (Геймплей) + инспектор + _activatePointers при Play. - is_test: переключатель «Тестовая игра» в GameSettingsModal (не течёт в каталог). - Ctrl+V в Monaco-редакторе скриптов (guard на .monaco-editor + activeElement). - Вики: карточка g5 «Туториал — собери монетки» (Разбор готовых игр). Co-Authored-By: Claude Opus 4.8 --- src/community/docsGames.js | 5 + src/editor/GameSettingsModal.jsx | 23 + src/editor/InspectorPanel.jsx | 94 +++ src/editor/KubikonEditor.jsx | 2 + src/editor/engine/BabylonScene.js | 70 ++- src/editor/engine/BeamManager.js | 711 +++++++++++++++++++++-- src/editor/engine/GameRuntime.js | 58 ++ src/editor/engine/PrimitiveManager.js | 39 +- src/editor/engine/PrimitiveTypes.js | 9 +- src/editor/engine/ScriptSandboxWorker.js | 72 ++- 10 files changed, 1015 insertions(+), 68 deletions(-) diff --git a/src/community/docsGames.js b/src/community/docsGames.js index 3e577db..3c2b525 100644 --- a/src/community/docsGames.js +++ b/src/community/docsGames.js @@ -318,4 +318,9 @@ export const GAMES = [ desc: 'Кастомные скины: герой превращается в пончик, машину, пришельца. Магазин скинов на B.', mechanics: ['game.player.setSkin', 'non-humanoid скины', 'магазин скинов', 'таблички'], previewShot: 'guide-zoo-scene.png', openProjectId: 2046, ready: true }, + { id: 'guide-strelka', num: 55, group: 'g5', stars: 1, icon: 'gamepad', + title: 'Туториал — собери монетки', + desc: '3D-стрелка-указатель «иди сюда»: дорожка из бегущих шевронов + парящий маркер над целью. Дошёл — стрелка прыгает на следующую.', + mechanics: ['game.fx.pointer', 'preset стрелки', 'setTarget/update', 'onTouch цели'], + previewShot: 'guide-strelka-scene.png', openProjectId: 333, ready: true }, ]; diff --git a/src/editor/GameSettingsModal.jsx b/src/editor/GameSettingsModal.jsx index 96f8dbb..fdfa26c 100644 --- a/src/editor/GameSettingsModal.jsx +++ b/src/editor/GameSettingsModal.jsx @@ -44,6 +44,7 @@ const GameSettingsModal = ({ open, initial, onClose, onSave, onCaptureScreenshot const [isPublic, setIsPublic] = useState(false); const [multiplayer, setMultiplayer] = useState(false); const [maxPlayers, setMaxPlayers] = useState(10); + const [isTest, setIsTest] = useState(false); const [error, setError] = useState(''); const fileInputRef = useRef(null); @@ -58,6 +59,7 @@ const GameSettingsModal = ({ open, initial, onClose, onSave, onCaptureScreenshot setThumbnail(initial?.thumbnail || ''); setIsPublic(!!initial?.is_public); setMultiplayer(!!initial?.multiplayer); + setIsTest(!!initial?.is_test); setMaxPlayers( typeof initial?.max_players === 'number' ? Math.max(2, Math.min(50, initial.max_players)) @@ -117,6 +119,7 @@ const GameSettingsModal = ({ open, initial, onClose, onSave, onCaptureScreenshot is_public: isPublic, multiplayer, max_players: Math.max(2, Math.min(50, Number(maxPlayers) || 10)), + is_test: isTest, }); }; @@ -252,6 +255,26 @@ const GameSettingsModal = ({ open, initial, onClose, onSave, onCaptureScreenshot + {/* Тестовая игра — для разработки/проверки в плеере. + Не попадает в каталог (лента/поиск/профиль). */} + + {multiplayer && (