diff --git a/src/community/docsData.jsx b/src/community/docsData.jsx index e802e4c..f51c53c 100644 --- a/src/community/docsData.jsx +++ b/src/community/docsData.jsx @@ -1248,9 +1248,11 @@ end)`}} нужен скрипт.
- Скрипты пишут на языке JavaScript — одном из самых - популярных языков в мире. Не пугайся: начнём с простого, - а редактор подсказывает команды по ходу набора. + Скрипты пишут на одном из двух языков: JavaScript + или Lua. Оба работают одинаково. Подробнее про + выбор языка — статья D0 выше. В этом уроке покажем + пример на обоих языках — переключай вкладки, чтобы видеть + нужный.
Как создать первый скрипт:
{`game.log('Привет! Игра запустилась.');`}
+ {`print("Привет! Игра запустилась.")`}}
+ />
- Это твой первый работающий скрипт. Команда
- game.log(...) печатает сообщение в консоль.
+ Это твой первый работающий скрипт.
; — как точка в конце предложения. Текст
- пишут в кавычках: 'привет'. Забыл кавычки
- или точку с запятой — будет ошибка.
- game.log(...) печатает в консоль.
+ Каждая команда в JavaScript заканчивается точкой с запятой
+ ; — как точка в предложении. Текст пишут
+ в кавычках: 'привет'.
+ }
+ lua={print(...) печатает в консоль.
+ В Lua точку с запятой ставить не нужно.
+ Текст пишут в кавычках: "привет" или
+ 'привет'. Lua использует ..
+ (две точки) для склейки текста: "А=" .. 5.
+
Скрипт на объекте относится к конкретному кубу, модели
или кнопке. Внутри такого скрипта работает волшебное слово
- game.self — это и есть тот объект, на котором
- висит скрипт. Через него ловят клик по объекту или касание
- игроком.
+ (своё для каждого языка):
{`// JS: game.self — это и есть тот объект, на котором висит скрипт
+game.self.onClick(() => {
+ game.log('Кликнули по мне!');
+});`}
+ >}
+ lua={<>
+ {`-- Lua: script.Parent — это и есть тот объект, на котором висит скрипт
+local part = script.Parent
+
+part.Touched:Connect(function(hit)
+ print("Касание объекта " .. part.Name)
+end)`}
+ >}
+ />
Как привязать скрипт к объекту: выдели объект на сцене, потом создай скрипт — он автоматически привяжется к выделенному объекту. Или укажи носителя в настройках скрипта.
- game.self — это скрипт на объекте.
- Если game.self нет — скрипт глобальный.
- Плашка в начале каждого урока всегда подскажет.
- game.self — это скрипт на объекте.
+ Если game.self нет — скрипт глобальный.
+ Плашка в начале каждого урока всегда подскажет.
+ }
+ lua={ script.Parent — это скрипт на объекте.
+ Если только game — глобальный.
+ В Lua глобальные скрипты обычно работают со списком
+ игроков: game:GetService("Players").
+ {`// Создаём переменную и кладём в неё число
+ {`// JS: создаём переменную через let
let score = 0;
// Меняем значение
score = score + 10; // теперь в score лежит 10
score = score + 5; // теперь 15
-game.log('Очков:', score); // напечатает: Очков: 15`}
-
- let — это слово «создать переменную». Пишут
- его только один раз, когда коробочку заводят. Дальше
- меняют значение уже без let.
-
{`-- Lua: создаём переменную через local
+local score = 0
+
+-- Меняем значение
+score = score + 10 -- теперь в score лежит 10
+score = score + 5 -- теперь 15
+
+print("Очков:", score) -- напечатает: Очков: 15`}}
+ />
+ let — это слово «создать переменную». Пишут
+ его только один раз, когда коробочку заводят. Дальше
+ меняют значение уже без let.
+ }
+ lua={
+ local — это слово «создать переменную внутри
+ скрипта». Пишут его только один раз. Если опустить
+ local — переменная станет глобальной (доступна
+ всем скриптам), это редко нужно.
+
В переменную можно класть не только числа:
-{`let name = 'Герой'; // текст — в кавычках
+ {`let name = 'Герой'; // текст — в кавычках
let isWin = false; // да/нет — true или false
-let coinCount = 0; // число — без кавычек`}
- let можно писать const
- («постоянная»). Например, найденную один раз дверь:
- const door = game.scene.findOne('Дверь');
- {`local name = "Герой" -- текст — в кавычках
+local isWin = false -- да/нет — true или false
+local coinCount = 0 -- число — без кавычек`}}
+ />
+ let можно писать const
+ («постоянная»). Например, найденную один раз дверь:
+ const door = game.scene.findOne('Дверь');
+ }
+ lua={local. Если хочешь явно показать
+ что значение не меняется, пиши имя ЗАГЛАВНЫМИ:
+ local DOOR = workspace.Дверь.
+ Это договорённость, а не правило Lua.
+
В каждом скрипте есть одно главное волшебное слово —
game. Через него ты управляешь всей игрой.
- У game много «отделов»:
+ Но «отделы» у JS и Lua разные:
game.player | управление игроком |
game.scene | объекты сцены |
game.ui | счётчики и текст на экране |
game.gui | кнопки и меню |
game.sound | звуки |
game.physics | лучи, импульсы, взрывы |
game.self | объект-носитель скрипта |
game.player | управление игроком |
game.scene | объекты сцены |
game.ui | счётчики и текст на экране |
game.gui | кнопки и меню |
game.sound | звуки |
game.physics | лучи, импульсы, взрывы |
game.self | объект-носитель скрипта |
+ Запись через точку читается слева направо.
+ game.player.teleport(0, 5, 0) читается так:
+ «у игры, у игрока, выполни телепорт
+ в точку 0, 5, 0».
+
workspace | 3D-объекты сцены |
game:GetService("Players") | список игроков |
game.Workspace | то же что workspace |
script.Parent | объект-носитель скрипта |
game:GetService("RunService") | каждый кадр (Heartbeat) |
game:GetService("UserInputService") | клавиши и мышь |
game:GetService("TweenService") | плавные движения |
+ Знак : (двоеточие) в Lua — это вызов
+ метода объекта. game:GetService("Players")
+ читается так: «у game вызови GetService
+ и дай ему текст Players».
+
+ Точка . — это доступ к полю объекта.
+ workspace.Floor.BrickColor — у workspace
+ взять Floor, у него взять BrickColor.
+
- Запись через точку читается слева направо.
- game.player.teleport(0, 5, 0) читается так:
- «у игры, у игрока, выполни телепорт
- в точку 0, 5, 0».
-
- Полный список всех команд каждого отдела — в Справочнике - (раздел H). Не нужно его заучивать: при наборе кода - редактор сам показывает подсказки. + Полный список всех команд — в Справочнике (раздел H). Не нужно + его заучивать: при наборе кода редактор сам показывает подсказки.
> ), }, { id: 'log-console', - title: 'D5. game.log, консоль, отладка', + title: 'D5. log/print, консоль, отладка', body: ( <>Консоль — окошко в правом нижнем углу редактора. Туда выводятся все сообщения и ошибки скриптов.
-
- Команда game.log(...) печатает в консоль
- что угодно. Это главный инструмент отладки —
- проверки, что код работает правильно:
-
game.log(...) печатает в консоль
+ что угодно. Это главный инструмент отладки —
+ проверки, что код работает правильно:
+ }
+ lua={
+ Команда print(...) печатает в консоль
+ что угодно. Это главный инструмент отладки —
+ проверки, что код работает правильно:
+
{`let score = 0;
+ {`let score = 0;
score = score + 10;
game.log('Очки сейчас:', score); // Очки сейчас: 10
let pos = game.player.position;
-game.log('Игрок стоит в точке:', pos);`}
-
- Если игра ведёт себя странно — расставь
- game.log по коду и посмотри, какие значения
- печатаются. Так ты увидишь, где именно что-то пошло не так.
-
{`local score = 0
+score = score + 10
+print("Очки сейчас:", score) -- Очки сейчас: 10
+
+local pos = game.Players.LocalPlayer.Character.HumanoidRootPart.Position
+print("Игрок стоит в точке:", pos)`}}
+ />
+ game.log по коду и посмотри, какие значения
+ печатаются. Так ты увидишь, где именно что-то пошло не так.
+ }
+ lua={
+ Если игра ведёт себя странно — расставь
+ print по коду и посмотри, какие значения
+ печатаются. Так ты увидишь, где именно что-то пошло не так.
+
Событие — это «что-то случилось». Скрипт может ждать событие и реагировать на него. Самые важные:
-game.onTick(fn) | каждый кадр (60 раз в секунду) |
game.onKey('space', fn) | игрок нажал клавишу |
game.self.onClick(fn) | игрок кликнул по объекту |
game.self.onTouch(fn) | игрок коснулся объекта |
game.onTick(fn)game.onKey('space', fn)game.self.onClick(fn)game.self.onTouch(fn)RunService.Heartbeat:Connect(fn) | каждый кадр |
UserInputService.InputBegan:Connect(fn) | любая клавиша |
part.ClickDetector.MouseClick:Connect(fn) | клик по объекту |
part.Touched:Connect(fn) | касание объекта |
Пример — куб, который исчезает по клику:
{`game.self.onClick(() => {
+ {`game.self.onClick(() => {
game.self.delete(); // удалить сам себя
game.log('Куб удалён!');
-});`}
-
- Что такое {`() => { ... }`}? Это
- «функция» — набор команд, упакованных вместе. Команды
- внутри фигурных скобок выполнятся не сразу, а только
- когда случится событие. То есть «когда кликнули — тогда
- удалить и напечатать».
-
onTick выполняется ОЧЕНЬ часто — 60 раз
- в секунду. Не делай внутри него тяжёлых вещей. Подробнее
- об этой ошибке — раздел J4.
- {`local part = script.Parent
+local clickDetector = Instance.new("ClickDetector")
+clickDetector.Parent = part
+
+clickDetector.MouseClick:Connect(function(player)
+ part:Destroy() -- удалить сам себя
+ print("Куб удалён!")
+end)`}}
+ />
+ {`() => { ... }`}? Это
+ «функция» — набор команд, упакованных вместе. Команды
+ внутри фигурных скобок выполнятся не сразу, а только
+ когда случится событие. То есть «когда кликнули — тогда
+ удалить и напечатать».
+ }
+ lua={
+ Что такое function() ... end? Это
+ «функция» — набор команд, упакованных вместе. Команды
+ между function() и end выполнятся
+ не сразу, а только когда случится событие. То есть
+ «когда кликнули — тогда удалить и напечатать».
+ Метод :Connect «подключает» функцию
+ к событию.
+
onTick выполняется ОЧЕНЬ часто — 60 раз
+ в секунду. Не делай внутри него тяжёлых вещей. Подробнее
+ об этой ошибке — раздел J4.
+ Heartbeat выполняется ОЧЕНЬ часто — 60 раз
+ в секунду. Не делай внутри тяжёлых вычислений. Подробнее
+ об этой ошибке — раздел J4.
+
Условие — это развилка: «если что-то верно —
- сделай одно, иначе — другое». В JavaScript это
+ сделай одно, иначе — другое». В обоих языках это
слова if («если») и else
- («иначе»).
+ («иначе»), но запись чуть отличается.
{`let coins = 7;
+ {`let coins = 7;
if (coins >= 10) {
game.ui.showText('Хватает на покупку!', 2);
} else {
game.ui.showText('Нужно больше монет', 2);
-}`}
+}`}}
+ lua={{`local coins = 7
+
+if coins >= 10 then
+ print("Хватает на покупку!")
+else
+ print("Нужно больше монет")
+end`}}
+ />
Тут проверяется: coins {'>'}= 10 — «монет
10 или больше?». Сейчас монет 7, значит условие неверно,
и сработает ветка else.
Знаки сравнения:
-a === b | a равно b |
a !== b | a не равно b |
a {'>'} b | a больше b |
a {'<'} b | a меньше b |
a {'>'}= b | a больше или равно b |
a {'<'}= b | a меньше или равно b |
===, а не один. Один знак = —
- это «положить значение в переменную», совсем другое
- действие.
- a === ba !== ba {'>'} ba {'<'} ba {'>'}= ba {'<'}= ba == b | a равно b |
a ~= b | a не равно b |
a {'>'} b | a больше b |
a {'<'} b | a меньше b |
a {'>'}= b | a больше или равно b |
a {'<'}= b | a меньше или равно b |
===, а не один. Один знак = —
+ это «положить значение в переменную», совсем другое
+ действие. И не равно — это !==.
+ }
+ lua={ ==. А «не равно» — это ~=
+ (тильда + равно). Запомни этот значок — он встречается
+ только в Lua.
+ Таймеры запускают команды не сразу, а потом:
-game.after(сек, fn) — выполнить
- один раз через несколько секунд;
- game.every(сек, fn) — выполнять
- снова и снова каждые несколько секунд;
- game.cancel(id) — остановить таймер.
- game.after(сек, fn) — выполнить
+ один раз через несколько секунд;
+ game.every(сек, fn) — выполнять
+ снова и снова каждые несколько секунд;
+ game.cancel(id) — остановить таймер.
+ task.delay(сек, fn) — выполнить
+ один раз через несколько секунд;
+ task.wait(сек) — приостановить скрипт
+ на N секунд (внутри цикла или функции);
+ while true do task.wait(1); ... end
+ в отдельной корутине через task.spawn.
+ {`// Через 3 секунды показать текст
+ {`// Через 3 секунды показать текст
game.after(3, () => {
game.ui.showText('Игра началась!', 2);
});
@@ -1546,12 +1749,42 @@ const ticker = game.every(1, () => {
game.after(10, () => {
game.cancel(ticker);
game.ui.showText('Время вышло!', 2);
-});`}
-
- Запись (game.ui.score || 0) читается так:
- «возьми счёт, а если его ещё нет — возьми 0». Это защита
- от ошибки в самом начале, когда счётчик ещё пустой.
-
{`-- Через 3 секунды показать текст
+task.delay(3, function()
+ print("Игра началась!")
+end)
+
+-- Каждую секунду прибавлять очко.
+-- Запускаем в отдельной корутине чтобы не блокировать скрипт.
+local score = 0
+local running = true
+task.spawn(function()
+ while running do
+ task.wait(1)
+ score = score + 1
+ end
+end)
+
+-- Через 10 секунд остановить начисление очков
+task.delay(10, function()
+ running = false
+ print("Время вышло! Набрано очков:", score)
+end)`}}
+ />
+ (game.ui.score || 0) читается так:
+ «возьми счёт, а если его ещё нет — возьми 0». Это защита
+ от ошибки в самом начале, когда счётчик ещё пустой.
+ }
+ lua={
+ В Lua переменная running — флаг работы цикла.
+ Когда нужно остановить таймер, ставим running = false,
+ и цикл сам завершится после task.wait(1).
+ Это проще, чем хранить номер таймера.
+