feat(wiki): ���� �������-��������� � ������ ������� ��� #17
@ -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;
|
||||
|
||||
@ -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({ from, to, preset })</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. */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user