feat(wiki): ���� �������-��������� � ������ ������� ��� #17

Merged
min merged 1 commits from feat/wiki-strelka-lesson into main 2026-05-31 02:15:59 +00:00
2 changed files with 143 additions and 7 deletions
Showing only changes of commit d9a3cd73df - Show all commits

View File

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