Merge pull request 'feat(wiki): ���� �������-��������� � ������ ������� ���' (#17) from feat/wiki-strelka-lesson into main
This commit is contained in:
commit
6bf9fe9e31
@ -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;
|
||||||
|
|||||||
@ -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. */
|
/** Есть ли готовый текст урока для игры с таким id. */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user