feat(wiki): урок «Туториал — собери монетки» (стрелка-указатель) в Разбор готовых игр
All checks were successful
CI / Lint (pull_request) Successful in 1m6s
CI / Build (pull_request) Successful in 1m55s
CI / Secret scan (pull_request) Successful in 2m31s
CI / PR size check (pull_request) Successful in 7s
CI / Deploy to S1 + S2 (pull_request) Has been skipped

- docsLessons.jsx: полный урок guide-strelka (game.fx.pointer, presets,
  setTarget/update, onTouch) → hasLesson=true → карточка #55 активна.
- KubikonDocs.jsx: onError-фолбэк на превью карточки (нет скрина → иконка,
  не битый img); .gameCard__noimg absolute-фон под img.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
МИН 2026-05-31 05:09:24 +03:00
parent fdbd8a7b10
commit d9a3cd73df
2 changed files with 143 additions and 7 deletions

View File

@ -224,12 +224,21 @@ const GamesGrid = ({ onOpenLesson }) => (
Если урока ещё нет иконка-плейсхолдер. */} Если урока ещё нет иконка-плейсхолдер. */}
<div className="gameCard__preview"> <div className="gameCard__preview">
{ready ? ( {ready ? (
<>
{/* Фолбэк-иконка под картинкой: если превью-файл
отсутствует (урок есть, но скрин ещё не снят)
onError прячет битый img и показывает иконку. */}
<div className="gameCard__noimg">
<DocIcon name={g.icon} size={40} />
</div>
<img <img
className="gameCard__img" className="gameCard__img"
src={`/wiki/${g.previewShot || `lesson${g.num}-result.png`}`} src={`/wiki/${g.previewShot || `lesson${g.num}-result.png`}`}
alt={g.title} alt={g.title}
loading="lazy" loading="lazy"
onError={(e) => { e.currentTarget.style.display = 'none'; }}
/> />
</>
) : ( ) : (
<div className="gameCard__noimg"> <div className="gameCard__noimg">
<DocIcon name={g.icon} size={40} /> <DocIcon name={g.icon} size={40} />
@ -981,14 +990,22 @@ const INLINE_STYLES = `
} }
.gameCard--ready:hover .gameCard__img { transform: scale(1.04); } .gameCard--ready:hover .gameCard__img { transform: scale(1.04); }
.gameCard__img { transition: transform 300ms ease; } .gameCard__img { transition: transform 300ms ease; }
/* плейсхолдер, если урока ещё нет */ /* плейсхолдер, если урока ещё нет ИЛИ превью-файл не загрузился.
absolute+inset:0 лежит фоном под <img>; если img есть и загрузился,
он перекрывает иконку; если img.onError спрятал его видна иконка. */
.gameCard__noimg { .gameCard__noimg {
position: absolute;
inset: 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 100%; height: 100%; width: 100%; height: 100%;
color: #3357ff; color: #3357ff;
} }
.gameCard__img {
position: relative;
z-index: 1;
}
/* плашки поверх превью */ /* плашки поверх превью */
.gameCard__num { .gameCard__num {
position: absolute; position: absolute;

View File

@ -7776,6 +7776,125 @@ game.player.setSkinCoins(500); // задать баланс рубликов
), ),
}, },
//
// РАЗБОР ИГР · Туториал собери монетки (оригинал id=333)
//
'guide-strelka': {
body: (
<>
<h3 className="lessonH">Что получится</h3>
<p>
Простой туториал-уровень: ровный газон и три цели
<b> красный куб</b>, <b>синяя сфера</b> и <b>золотой сундук</b>.
Над целью парит светящаяся <b>стрелка-указатель «иди сюда»</b>,
а к ней по земле бежит дорожка из шевронов точь-в-точь как
маркеры заданий в Roblox. Дошёл до цели стрелка сама
перепрыгивает на следующую и меняет цвет.
</p>
<h3 className="lessonH">Чему научишься</h3>
<ul>
<li><b>game.fx.pointer</b> создавать 3D-указатель к цели
(лента шевронов + парящий маркер над объектом);</li>
<li><b>пресеты стрелки</b> готовые стили
<code> guide</code> (красная), <code>quest</code> (жёлтая),
<code> gift</code> (радужная);</li>
<li><b>setTarget / update</b> перенацеливать стрелку на новую
цель и менять её стиль на лету;</li>
<li><b>onTouch</b> ловить, когда игрок дошёл до цели.</li>
</ul>
<h3 className="lessonH">Шаг 1. Сцена</h3>
<Step n="1">
Инструментом <kbd className="kbd">Примитив</kbd> положи большой
плоский <b>куб</b> это газон (пол).
</Step>
<Step n="2">
Поставь три примитива-цели и дай им <b>имена</b> в инспекторе:
<code> red-cube</code> (куб), <code>blue-sphere</code> (сфера),
<code> gold-chest</code> (куб). Имя это как раз то, по чему
скрипт найдёт объект.
</Step>
<Step n="3">
На вкладке <b>Игра</b> поставь <b>точку спавна</b> перед целями.
</Step>
<h3 className="lessonH">Шаг 2. Стрелка к первой цели</h3>
<p>
Стрелку создаёт одна команда. <b>Важно:</b> ищем цель не сразу,
а через <code>game.after</code> на старте объекты сцены ещё
могут быть не готовы.
</p>
<ScriptKind kind="global" />
<Code>{`// === ТУТОРИАЛ — СОБЕРИ МОНЕТКИ — главный скрипт ===
const targets = ['red-cube', 'blue-sphere', 'gold-chest'];
const presets = ['guide', 'quest', 'gift']; // цвета стрелки по очереди
let step = 0;
let arrow = null;
game.ui.set('hint', 'Иди за стрелкой к цели!', { x: 50, y: 6, anchor: 'top' });
// Через 0.4 сек создаём стрелку от игрока к первой цели.
game.after(0.4, () => {
const first = game.scene.findOne(targets[0]);
arrow = game.fx.pointer({ from: 'player', to: first, preset: 'guide' });
});`}</Code>
<p>
<code>game.fx.pointer(&#123; from, to, preset &#125;)</code>
<code> from: 'player'</code> значит «от игрока»,
<code> to</code> объект-цель (нашли через
<code> findOne</code>), <code>preset</code> стиль.
</p>
<h3 className="lessonH">Шаг 3. Переход к следующей цели</h3>
<p>
На каждую цель вешаем <code>onTouch</code>: дошёл берём
следующую и перенацеливаем ту же стрелку через
<code> setTarget</code>, а стиль меняем через
<code> update</code>.
</p>
<Code>{`for (let i = 0; i < targets.length; i++) {
const obj = game.scene.findOne(targets[i]);
if (!obj) continue;
obj.onTouch(() => {
if (i !== step) return; // только текущая по порядку цель
step++;
if (step >= targets.length) {
if (arrow) arrow.remove(); // все цели собраны убираем стрелку
game.ui.set('hint', 'Молодец! Все цели собраны!', { x: 50, y: 6, anchor: 'top' });
return;
}
const next = game.scene.findOne(targets[step]);
arrow.setTarget(next); // стрелка теперь ведёт к следующей
arrow.update({ preset: presets[step] }); // и меняет цвет
});
}`}</Code>
<h3 className="lessonH">Шаг 4. Проверка</h3>
<Step n="1">
Нажми <kbd className="kbd">Играть</kbd>. Над красным кубом
появится парящая красная стрелка и дорожка-шевроны к нему.
</Step>
<Step n="2">
Подойди к кубу стрелка перепрыгнет на синюю сферу (станет
жёлтой), потом на сундук (радужная).
</Step>
<Note>
Стрелка-указатель лучший способ вести новичка по твоей игре:
куда идти, что нажать, где следующее задание.
</Note>
<Try>
сделай «кастомную» стрелку: добавь GUI-кнопку и по нажатию
создай <code>game.fx.pointer</code> с
<code> texture: 'lightning'</code>, <code>color: '#22ff66'</code>
и <code>curved: true</code> получится изогнутая зелёная
молниевая стрелка.
</Try>
</>
),
},
}; };
/** Есть ли готовый текст урока для игры с таким id. */ /** Есть ли готовый текст урока для игры с таким id. */