diff --git a/src/community/docsLessons.jsx b/src/community/docsLessons.jsx
index 66d563f..6261197 100644
--- a/src/community/docsLessons.jsx
+++ b/src/community/docsLessons.jsx
@@ -1,5 +1,24 @@
import React from 'react';
import { Code, ScriptKind, Step, Note, Try, Shot } from './docsData';
+import { LangTabs } from './docsLang';
+import { LUA_OVERRIDES } from './docsGamesBuildersLua';
+
+/**
+ * Хелпер: оборачивает JS-код в LangTabs с Lua-параллелью из LUA_OVERRIDES.
+ * {luaResolved} : null}
+ />
+ );
+}
/**
* docsLessons.jsx — тексты уроков для 50 мини-игр (раздел K вики).
@@ -104,7 +123,7 @@ export const LESSONS = {
Главный скрипт считает монетки и проверяет победу.
{`// === ИГРА «СОБЕРИ МОНЕТКИ» — главный скрипт ===
+ {`// === ИГРА «СОБЕРИ МОНЕТКИ» — главный скрипт ===
// Этот скрипт глобальный: считает собранные монетки и проверяет победу.
let score = 0; // сколько монеток собрано
@@ -131,7 +150,7 @@ game.onMessage('coin', () => {
{ x: p.x, y: p.y + 3, z: p.z },
{ duration: 3, count: 3 });
}
-});`}
+});`}
Разберём построчно:
@@ -154,14 +173,14 @@ game.onMessage('coin', () => { касание и сообщает главному скрипту: меня собрали.{`// === Скрипт монетки ===
+ {`// === Скрипт монетки ===
// game.self — это сама монетка, на которой висит скрипт.
game.self.onTouch(() => {
// игрок коснулся монетки — сообщаем главному скрипту
game.broadcast('coin');
game.self.delete(); // монетка исчезает со сцены
-});`}
+});`}
Что происходит: onTouch срабатывает, когда
игрок дотронулся до монетки. Внутри мы шлём
@@ -274,7 +293,7 @@ game.self.onTouch(() => {
Главный скрипт следит за падением и обрабатывает победу.
{`// === ИГРА «ПРЫГАЙ ПО ПЛАТФОРМАМ» — главный скрипт ===
+ {`// === ИГРА «ПРЫГАЙ ПО ПЛАТФОРМАМ» — главный скрипт ===
let won = false; // победа уже была?
@@ -304,7 +323,7 @@ game.onMessage('finish', () => {
game.scene.spawnParticles('confetti',
{ x: p.x, y: p.y + 3, z: p.z },
{ duration: 3, count: 3 });
-});`}
+});`}
Что тут важно:
game.onTick(...) — функция внутри
@@ -320,13 +339,13 @@ game.onMessage('finish', () => {
{`// === Скрипт финиша ===
+ {`// === Скрипт финиша ===
// Висит на невидимой зоне над зелёной площадкой.
// Игрок встал на площадку — его тело внутри зоны — победа.
game.self.onTouch(() => {
game.broadcast('finish'); // сообщаем главному скрипту о победе
-});`}
+});`}
Когда игрок касается финиша, скрипт шлёт
game.broadcast('finish'). Главный скрипт ловит
@@ -401,7 +420,7 @@ game.self.onTouch(() => {
Следит за падением и победой — как в уроке 2.
{`// === ИГРА «НЕ УПАДИ» — главный скрипт ===
+ {`// === ИГРА «НЕ УПАДИ» — главный скрипт ===
let won = false;
@@ -428,7 +447,7 @@ game.onMessage('finish', () => {
const p = game.player.position;
game.scene.spawnParticles('confetti',
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
-});`}
+});`}
@@ -436,7 +455,7 @@ game.onMessage('finish', () => { который убирает её через секунду после касания.
{`// === Скрипт исчезающей плитки ===
+ {`// === Скрипт исчезающей плитки ===
let triggered = false; // плитка уже запущена на исчезновение?
@@ -448,7 +467,7 @@ game.self.onTouch(() => {
game.after(1.2, () => {
game.self.delete();
});
-});`}
+});`}
Разберём:
triggered — флажок-защёлка. Игрок может
@@ -532,7 +551,7 @@ game.self.onTouch(() => {
{`// === ИГРА «КНОПКА-ОТКРЫВАШКА» — главный скрипт ===
+ {`// === ИГРА «КНОПКА-ОТКРЫВАШКА» — главный скрипт ===
game.ui.showText('Подойди к красной кнопке и нажми E', 4);
@@ -544,7 +563,7 @@ game.onMessage('win', () => {
const p = game.player.position;
game.scene.spawnParticles('confetti',
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
-});`}
+});`}
@@ -552,7 +571,7 @@ game.onMessage('win', () => { открывает дверь.
{`// === Скрипт кнопки ===
+ {`// === Скрипт кнопки ===
let opened = false;
@@ -570,7 +589,7 @@ game.self.onInteract(() => {
}, {
text: 'Открыть дверь', // подсказка над кнопкой
distance: 4 // на сколько метров подойти
-});`}
+});`}
Разберём:
game.self.onInteract(fn, опции) — это
@@ -592,10 +611,10 @@ game.self.onInteract(() => {
{`// === Скрипт финиша ===
+ {`// === Скрипт финиша ===
game.self.onTouch(() => {
game.broadcast('win'); // сообщаем главному скрипту о победе
-});`}
+});`}
Запусти игру:
Скрипты совсем простые — лабиринт держится на постройке.
{`// === ИГРА «ЛАБИРИНТ» — главный скрипт ===
+ {`// === ИГРА «ЛАБИРИНТ» — главный скрипт ===
game.ui.showText('Найди выход из лабиринта!', 3);
@@ -700,12 +719,12 @@ game.onMessage('win', () => {
const p = game.player.position;
game.scene.spawnParticles('confetti',
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
-});`}
+});`}
{`// === Скрипт финиша ===
+ {`// === Скрипт финиша ===
game.self.onTouch(() => {
game.broadcast('win'); // сообщаем главному скрипту о победе
-});`}
+});`}
{`// === ИГРА «ЦВЕТНЫЕ ПЛИТКИ» — главный скрипт ===
+ {`// === ИГРА «ЦВЕТНЫЕ ПЛИТКИ» — главный скрипт ===
let painted = 0; // сколько плиток раскрашено
const TOTAL = 36; // всего плиток (6×6)
@@ -785,7 +804,7 @@ game.onMessage('paint', () => {
game.scene.spawnParticles('confetti',
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
}
-});`}
+});`}
36 на столько плиток, сколько
реально поставил. Если сетка 5×5 — будет 25.
@@ -793,7 +812,7 @@ game.onMessage('paint', () => {
{`// === Скрипт цветной плитки ===
+ {`// === Скрипт цветной плитки ===
let painted = false; // плитка уже раскрашена?
@@ -803,7 +822,7 @@ game.self.onTouch(() => {
// меняем цвет плитки на ярко-зелёный
game.scene.setColor(game.self.ref, '#33dd55');
game.broadcast('paint'); // сообщаем главному скрипту о покраске
-});`}
+});`}
Главное здесь:
game.scene.setColor(ref, цвет) — меняет
@@ -874,7 +893,7 @@ game.self.onTouch(() => {
{`// === ИГРА «ПОЙМАЙ ПАДАЮЩЕЕ» — главный скрипт ===
+ {`// === ИГРА «ПОЙМАЙ ПАДАЮЩЕЕ» — главный скрипт ===
let score = 0;
const GOAL = 15; // сколько кубов нужно поймать
@@ -922,7 +941,7 @@ game.onPlayerTouch((e) => {
game.scene.spawnParticles('confetti',
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
}
-});`}
+});`}
Разберём по частям:
game.every(1.5, fn) — каждые 1.5 секунды
@@ -1005,7 +1024,7 @@ game.onPlayerTouch((e) => {
{`// === ИГРА «БЕГИ К ФИНИШУ» — главный скрипт ===
+ {`// === ИГРА «БЕГИ К ФИНИШУ» — главный скрипт ===
let finished = false;
let time = 0; // прошло секунд
@@ -1032,7 +1051,7 @@ game.onMessage('finish', () => {
const p = game.player.position;
game.scene.spawnParticles('confetti',
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
-});`}
+});`}
Главное здесь — измерение времени:
game.onTick((dt) => {'{...}'}) —
@@ -1048,10 +1067,10 @@ game.onMessage('finish', () => {
{`// === Скрипт финиша ===
+ {`// === Скрипт финиша ===
game.self.onTouch(() => {
game.broadcast('finish'); // сообщаем главному скрипту о финише
-});`}
+});`}