/** * docsGamesBuildersLua.js — Lua-эквиваленты скриптов для уроков. * * Структура: LUA_OVERRIDES[gameId][scriptId] = 'lua-code' * Может быть строкой или функцией (script) => 'lua-code' для случаев, * когда код зависит от target/name (например, имя примитива). * * Когда юзер нажимает «Открыть копию → Lua» в LessonPage, * buildGameProject(id, {lang:'lua'}) подменяет JS-скрипт на Lua-версию * отсюда. Геометрия (примитивы, блоки) остаётся той же — отличается * только язык скриптов. * * Lua-код пишется в стандартном Roblox-стиле: * game:GetService("Players"), workspace, Instance.new, Vector3, CFrame, * :Connect, RunService.Heartbeat, BindableEvent через ReplicatedStorage. * * Конвенции: * - target=null (глобальный JS-скрипт) → в Lua это просто script в workspace, * общение через ReplicatedStorage:BindableEvent. * - target.kind='primitive' (на объекте) → script лежит ВНУТРИ части, * обращение к ней через script.Parent. Имя части совпадает с тем что * в JS-builder указано (Монетка_N, Платформа_N и т.д.). * * Помощники общего назначения: * getPlayerFromHit — извлекает Player из hit события Touched. * getOrCreateEvent — общая BindableEvent в ReplicatedStorage для broadcast. */ // ══════════════════════════════════════════════════════════════════ // Общие сниппеты — вставляются в начало многих скриптов. // ══════════════════════════════════════════════════════════════════ const SNIPPET_BROADCAST = `local ReplicatedStorage = game:GetService("ReplicatedStorage") local function getEvent(name) local ev = ReplicatedStorage:FindFirstChild(name) if not ev then ev = Instance.new("BindableEvent") ev.Name = name ev.Parent = ReplicatedStorage end return ev end`; const SNIPPET_PLAYER_HIT = `local Players = game:GetService("Players") local function getPlayerFromHit(hit) if not hit or not hit.Parent then return nil end return Players:GetPlayerFromCharacter(hit.Parent) end`; export const LUA_OVERRIDES = { // ═══════════════════════════════════════════════════════════════ // ИГРА 1 — «Собери монетки» // ═══════════════════════════════════════════════════════════════ 'collect-coins': { g1_main: `-- === ИГРА «СОБЕРИ МОНЕТКИ» — главный скрипт (Lua) === ${SNIPPET_BROADCAST} local Players = game:GetService("Players") local score = 0 local TOTAL = 8 -- HUD: счётчик в правом верхнем углу local player = Players.LocalPlayer local screenGui = Instance.new("ScreenGui", player.PlayerGui) screenGui.Name = "CoinHUD" local label = Instance.new("TextLabel", screenGui) label.Size = UDim2.new(0, 220, 0, 50) label.Position = UDim2.new(1, -240, 0, 20) label.BackgroundColor3 = Color3.fromRGB(0, 0, 0) label.BackgroundTransparency = 0.4 label.TextColor3 = Color3.fromRGB(255, 215, 0) label.TextScaled = true label.Font = Enum.Font.SourceSansBold label.Text = "Монеты: 0 / " .. TOTAL -- Подсказка по центру (на 2 секунды) local hintGui = Instance.new("ScreenGui", player.PlayerGui) local hint = Instance.new("TextLabel", hintGui) hint.Size = UDim2.new(0, 400, 0, 60) hint.Position = UDim2.new(0.5, -200, 0.3, 0) hint.BackgroundColor3 = Color3.fromRGB(0, 0, 0) hint.BackgroundTransparency = 0.4 hint.TextColor3 = Color3.fromRGB(255, 255, 255) hint.TextScaled = true hint.Text = "Собери все монетки!" task.delay(2, function() hintGui:Destroy() end) -- Звуки local coinSound = Instance.new("Sound", workspace) coinSound.SoundId = "coin" coinSound.Volume = 1 local winSound = Instance.new("Sound", workspace) winSound.SoundId = "win" winSound.Volume = 1 -- Подписка на сбор монетки local coinEvent = getEvent("CoinCollected") coinEvent.Event:Connect(function() score = score + 1 label.Text = "Монеты: " .. score .. " / " .. TOTAL coinSound:Play() if score >= TOTAL then -- Победный текст local winGui = Instance.new("ScreenGui", player.PlayerGui) local winLabel = Instance.new("TextLabel", winGui) winLabel.Size = UDim2.new(0, 500, 0, 80) winLabel.Position = UDim2.new(0.5, -250, 0.4, 0) winLabel.BackgroundColor3 = Color3.fromRGB(0, 100, 0) winLabel.BackgroundTransparency = 0.2 winLabel.TextColor3 = Color3.fromRGB(255, 255, 0) winLabel.TextScaled = true winLabel.Font = Enum.Font.SourceSansBold winLabel.Text = "Победа! Все монетки твои!" winSound:Play() end end)`, // Скрипт каждой монетки — генератор по script-объекту g1_coin_1: makeCoinScript(), g1_coin_2: makeCoinScript(), g1_coin_3: makeCoinScript(), g1_coin_4: makeCoinScript(), g1_coin_5: makeCoinScript(), g1_coin_6: makeCoinScript(), g1_coin_7: makeCoinScript(), g1_coin_8: makeCoinScript(), }, // ═══════════════════════════════════════════════════════════════ // ИГРА 2 — «Прыгай по платформам» // ═══════════════════════════════════════════════════════════════ 'platform-jump': { g2_main: `-- === ИГРА «ПРЫГАЙ ПО ПЛАТФОРМАМ» — главный скрипт (Lua) === ${SNIPPET_BROADCAST} local Players = game:GetService("Players") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local won = false -- Подсказка по центру (на 3 секунды) local hintGui = Instance.new("ScreenGui", player.PlayerGui) hintGui.Name = "Hint" local hint = Instance.new("TextLabel", hintGui) hint.Size = UDim2.new(0, 480, 0, 60) hint.Position = UDim2.new(0.5, -240, 0.3, 0) hint.BackgroundColor3 = Color3.fromRGB(0, 0, 0) hint.BackgroundTransparency = 0.4 hint.TextColor3 = Color3.fromRGB(255, 255, 255) hint.TextScaled = true hint.Font = Enum.Font.SourceSansBold hint.Text = "Допрыгай до зелёной площадки!" task.delay(3, function() hintGui:Destroy() end) -- Звуки local loseSound = Instance.new("Sound", workspace) loseSound.SoundId = "lose" loseSound.Volume = 1 local winSound = Instance.new("Sound", workspace) winSound.SoundId = "win" winSound.Volume = 1 -- Каждый кадр следим: не упал ли игрок RunService.Heartbeat:Connect(function() if won then return end local char = player.Character if not char then return end local hrp = char:FindFirstChild("HumanoidRootPart") if hrp and hrp.Position.Y < -3 then player:LoadCharacter() loseSound:Play() local fallGui = Instance.new("ScreenGui", player.PlayerGui) local fallLabel = Instance.new("TextLabel", fallGui) fallLabel.Size = UDim2.new(0, 400, 0, 60) fallLabel.Position = UDim2.new(0.5, -200, 0.35, 0) fallLabel.BackgroundColor3 = Color3.fromRGB(120, 0, 0) fallLabel.BackgroundTransparency = 0.3 fallLabel.TextColor3 = Color3.fromRGB(255, 255, 255) fallLabel.TextScaled = true fallLabel.Font = Enum.Font.SourceSansBold fallLabel.Text = "Упал! Пробуй снова." task.delay(1.5, function() fallGui:Destroy() end) end end) -- Финиш-зона шлёт BindableEvent local finishEvent = getEvent("FinishReached") finishEvent.Event:Connect(function() if won then return end won = true winSound:Play() local winGui = Instance.new("ScreenGui", player.PlayerGui) local winLabel = Instance.new("TextLabel", winGui) winLabel.Size = UDim2.new(0, 540, 0, 80) winLabel.Position = UDim2.new(0.5, -270, 0.4, 0) winLabel.BackgroundColor3 = Color3.fromRGB(0, 120, 0) winLabel.BackgroundTransparency = 0.2 winLabel.TextColor3 = Color3.fromRGB(255, 255, 0) winLabel.TextScaled = true winLabel.Font = Enum.Font.SourceSansBold winLabel.Text = "Победа! Ты дошёл до финиша!" end)`, g2_finish: `-- === Скрипт финиш-зоны (Lua) === -- Висит на невидимой зоне над зелёной площадкой. -- Игрок встал — его тело внутри зоны — победа. local ReplicatedStorage = game:GetService("ReplicatedStorage") local part = script.Parent local fired = false part.Touched:Connect(function(hit) if fired then return end local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end fired = true local ev = ReplicatedStorage:FindFirstChild("FinishReached") if ev then ev:Fire() end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 3 — «Не упади» (платформа сужается) // ═══════════════════════════════════════════════════════════════ 'dont-fall': { g3_main: `-- === ИГРА «НЕ УПАДИ» — главный скрипт (Lua) === local Players = game:GetService("Players") local RunService = game:GetService("RunService") print("Удержись на платформе как можно дольше!") local startTime = tick() local alive = true RunService.Heartbeat:Connect(function() if not alive then return end for _, player in ipairs(Players:GetPlayers()) do local char = player.Character if char then local hrp = char:FindFirstChild("HumanoidRootPart") if hrp and hrp.Position.Y < -5 then alive = false local elapsed = math.floor(tick() - startTime) print("Ты упал! Продержался: " .. elapsed .. " сек") task.delay(2, function() player:LoadCharacter() startTime = tick() alive = true end) end end end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 4 — «Кнопка и дверь» // ═══════════════════════════════════════════════════════════════ 'button-door': { g4_main: `-- === ИГРА «КНОПКА И ДВЕРЬ» — главный скрипт (Lua) === ${SNIPPET_BROADCAST} print("Найди кнопку и открой дверь!") -- Глобальный канал для оповещения двери getEvent("DoorOpen")`, g4_button: `-- === Скрипт кнопки (Lua) === local ReplicatedStorage = game:GetService("ReplicatedStorage") local part = script.Parent part.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end local ev = ReplicatedStorage:FindFirstChild("DoorOpen") if ev then ev:Fire() end print("Кнопка нажата!") part.Color = Color3.fromRGB(100, 255, 100) -- зелёная end)`, g4_door: `-- === Скрипт двери (Lua) === local TweenService = game:GetService("TweenService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local door = script.Parent local startPos = door.Position local ev = ReplicatedStorage:WaitForChild("DoorOpen") ev.Event:Connect(function() -- Поднимаем дверь вверх local goal = { Position = startPos + Vector3.new(0, 5, 0) } TweenService:Create(door, TweenInfo.new(1), goal):Play() door.CanCollide = false print("Дверь открыта!") end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 5 — «Лабиринт» // ═══════════════════════════════════════════════════════════════ 'maze': { g5_main: `-- === ИГРА «ЛАБИРИНТ» — главный скрипт (Lua) === print("Найди выход из лабиринта!")`, g5_finish: `-- === Финиш лабиринта (Lua) === local part = script.Parent part.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end print("ПОБЕДА! Ты нашёл выход!") h.WalkSpeed = 0 end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 6 — «Угадай цвет» // ═══════════════════════════════════════════════════════════════ 'color-tiles': { g6_main: `-- === ИГРА «УГАДАЙ ЦВЕТ» — главный скрипт (Lua) === ${SNIPPET_BROADCAST} local colors = { "red", "green", "blue", "yellow" } local target = colors[math.random(1, #colors)] print("Встань на плитку цвета: " .. target) local ev = getEvent("TileStepped") ev.Event:Connect(function(color) if color == target then print("Верно! +1 очко") target = colors[math.random(1, #colors)] print("Теперь встань на: " .. target) else print("Неверно! Нужен " .. target) end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 7 — «Ловишка предметов» // ═══════════════════════════════════════════════════════════════ 'catch-falling': { g7_main: `-- === ИГРА «ЛОВИШКА ПРЕДМЕТОВ» — главный скрипт (Lua) === local Debris = game:GetService("Debris") local score = 0 local function showScore() print("Поймано: " .. score) end showScore() -- Каждую секунду создаём падающий предмет task.spawn(function() while true do task.wait(1) local ball = Instance.new("Part") ball.Shape = Enum.PartType.Ball ball.Size = Vector3.new(1, 1, 1) ball.Position = Vector3.new(math.random(-8, 8), 20, math.random(-8, 8)) ball.Color = Color3.fromRGB(255, 215, 0) ball.Material = Enum.Material.Neon ball.Anchored = false ball.Parent = workspace Debris:AddItem(ball, 10) -- Скрипт на ловлю ball.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if h and ball.Parent then score = score + 1 showScore() ball:Destroy() end end) end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 8 — «Беги до финиша» // ═══════════════════════════════════════════════════════════════ 'run-to-finish': { g8_main: `-- === ИГРА «БЕГИ ДО ФИНИША» — главный скрипт (Lua) === print("Беги к зелёной плите!")`, g8_finish: `-- === Финишная плита (Lua) === local part = script.Parent local won = false part.Touched:Connect(function(hit) if won then return end local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end won = true print("ПОБЕДА! Ты добежал!") h.WalkSpeed = 0 end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 9 — «Светофор» // ═══════════════════════════════════════════════════════════════ 'traffic-light': { g9_main: `-- === ИГРА «СВЕТОФОР» — главный скрипт (Lua) === local Players = game:GetService("Players") local RunService = game:GetService("RunService") local isGreen = true print("ЗЕЛЁНЫЙ — беги!") -- Каждые 3-5 сек переключаем свет task.spawn(function() while true do task.wait(math.random(3, 5)) isGreen = not isGreen if isGreen then print("ЗЕЛЁНЫЙ — беги!") else print("КРАСНЫЙ — стой!") end end end) -- Следим за движением игрока во время красного local lastPos = {} RunService.Heartbeat:Connect(function() if isGreen then return end for _, player in ipairs(Players:GetPlayers()) do local char = player.Character local hrp = char and char:FindFirstChild("HumanoidRootPart") if hrp then local prev = lastPos[player] if prev and (hrp.Position - prev).Magnitude > 0.5 then print(player.Name .. " двигался на красный! Респаун") player:LoadCharacter() end lastPos[player] = hrp.Position end end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 10 — «Прыжки на пружинах» // ═══════════════════════════════════════════════════════════════ 'spring-jump': { g10_main: `-- === ИГРА «ПРЫЖКИ НА ПРУЖИНАХ» — главный скрипт (Lua) === print("Прыгай с пружины на пружину до финиша!")`, g10_spring: `-- === Скрипт пружины (Lua) === local part = script.Parent part.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") local hrp = hit.Parent and hit.Parent:FindFirstChild("HumanoidRootPart") if h and hrp then -- Подбрасываем игрока вверх hrp.Velocity = Vector3.new(hrp.Velocity.X, 80, hrp.Velocity.Z) end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 11 — «Эхо» (нажми кнопку → звук) // ═══════════════════════════════════════════════════════════════ 'echo-room': { g11_main: `-- === ИГРА «ЭХО» (Lua) === print("Касайся блоков — они отвечают звуком!")`, g11_block: `-- === Скрипт звукового блока (Lua) === local part = script.Parent local lastTouch = 0 part.Touched:Connect(function(hit) local now = tick() if now - lastTouch < 0.5 then return end lastTouch = now local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end print("Блок " .. part.Name .. " звенит!") part.Color = Color3.fromRGB(math.random(0,255), math.random(0,255), math.random(0,255)) end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 12 — «Кодовая дверь» // ═══════════════════════════════════════════════════════════════ 'code-door': { g12_main: `-- === ИГРА «КОДОВАЯ ДВЕРЬ» — главный скрипт (Lua) === ${SNIPPET_BROADCAST} local correctCode = "1234" local currentInput = "" print("Введи код 1234 (касайся кнопок по порядку)") local ev = getEvent("CodeButton") ev.Event:Connect(function(digit) currentInput = currentInput .. tostring(digit) print("Ввод: " .. currentInput) if #currentInput == 4 then if currentInput == correctCode then print("Верно! Дверь открывается") local doorEv = getEvent("DoorOpen") doorEv:Fire() else print("Неверный код, попробуй ещё") end currentInput = "" end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 13 — «Торговец» // ═══════════════════════════════════════════════════════════════ 'trader': { g13_main: `-- === ИГРА «ТОРГОВЕЦ» (Lua) === local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder", player); stats.Name = "leaderstats" local coins = Instance.new("IntValue", stats); coins.Name = "Монеты"; coins.Value = 10 end) for _, p in ipairs(Players:GetPlayers()) do if not p:FindFirstChild("leaderstats") then local stats = Instance.new("Folder", p); stats.Name = "leaderstats" local coins = Instance.new("IntValue", stats); coins.Name = "Монеты"; coins.Value = 10 end end print("У тебя 10 монет. Купи зелье у торговца!")`, g13_npc: `-- === Скрипт торговца (Lua) === local Players = game:GetService("Players") local part = script.Parent part.Touched:Connect(function(hit) local player = Players:GetPlayerFromCharacter(hit.Parent) if not player then return end local stats = player:FindFirstChild("leaderstats") if not stats then return end if stats['Монеты'].Value >= 5 then stats['Монеты'].Value = stats['Монеты'].Value - 5 local h = hit.Parent:FindFirstChild("Humanoid") if h then h.Health = math.min(h.MaxHealth, h.Health + 50) end print("Купил зелье! +50 HP. Осталось монет: " .. stats['Монеты'].Value) else print("Не хватает монет! Нужно 5") end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 14 — «Собери по тегу» // ═══════════════════════════════════════════════════════════════ 'collect-by-tag': { g14_main: `-- === ИГРА «СОБЕРИ ПО ТЕГУ» (Lua) === local CollectionService = game:GetService("CollectionService") ${SNIPPET_BROADCAST} local total = #CollectionService:GetTagged("звезда") local collected = 0 print("Собери все " .. total .. " звёзд!") local ev = getEvent("StarCollected") ev.Event:Connect(function() collected = collected + 1 print("Собрано: " .. collected .. "/" .. total) if collected >= total then print("ПОБЕДА! Все звёзды собраны!") end end)`, g14_star: `-- === Скрипт звезды (Lua) === local CollectionService = game:GetService("CollectionService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local part = script.Parent CollectionService:AddTag(part, "звезда") part.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end local ev = ReplicatedStorage:FindFirstChild("StarCollected") if ev then ev:Fire() end part:Destroy() end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 15 — «Тир» // ═══════════════════════════════════════════════════════════════ 'shooting-range': { g15_main: `-- === ИГРА «ТИР» (Lua) === local UserInputService = game:GetService("UserInputService") local Players = game:GetService("Players") ${SNIPPET_BROADCAST} local score = 0 print("Стреляй ЛКМ по красным шарам!") local ev = getEvent("TargetHit") ev.Event:Connect(function() score = score + 1 print("Попал! Очки: " .. score) end) -- ЛКМ — пускаем луч из камеры UserInputService.InputBegan:Connect(function(input, gp) if gp then return end if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end local player = Players.LocalPlayer local mouse = player:GetMouse() local target = mouse.Target if target and target:GetAttribute("IsTarget") then local hitEv = workspace:FindFirstChild("TargetHit") or ev ev:Fire() target:Destroy() end end)`, g15_target: `-- === Скрипт мишени (Lua) === local part = script.Parent part:SetAttribute("IsTarget", true)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 16 — «Лавовый пол» // ═══════════════════════════════════════════════════════════════ 'lava-floor': { g16_main: `-- === ИГРА «ЛАВОВЫЙ ПОЛ» (Lua) === print("Прыгай по островкам, не упади в лаву!")`, g16_lava: `-- === Скрипт лавы (Lua) === local part = script.Parent part.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if h then h.Health = 0 end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 17 — «Ключ от сундука» // ═══════════════════════════════════════════════════════════════ 'key-chest': { g17_main: `-- === ИГРА «КЛЮЧ ОТ СУНДУКА» (Lua) === local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder", player); stats.Name = "leaderstats" local key = Instance.new("BoolValue", stats); key.Name = "Ключ" end) for _, p in ipairs(Players:GetPlayers()) do if not p:FindFirstChild("leaderstats") then local stats = Instance.new("Folder", p); stats.Name = "leaderstats" local key = Instance.new("BoolValue", stats); key.Name = "Ключ" end end print("Найди ключ и открой сундук!")`, g17_key: `-- === Скрипт ключа (Lua) === local Players = game:GetService("Players") local part = script.Parent part.Touched:Connect(function(hit) local player = Players:GetPlayerFromCharacter(hit.Parent) if not player then return end local stats = player:FindFirstChild("leaderstats") if stats and stats:FindFirstChild("Ключ") then stats['Ключ'].Value = true print("Подобрал ключ!") part:Destroy() end end)`, g17_chest: `-- === Скрипт сундука (Lua) === local Players = game:GetService("Players") local part = script.Parent part.Touched:Connect(function(hit) local player = Players:GetPlayerFromCharacter(hit.Parent) if not player then return end local stats = player:FindFirstChild("leaderstats") if stats and stats['Ключ'] and stats['Ключ'].Value then print("Сундук открыт! ПОБЕДА!") part.Color = Color3.fromRGB(255, 215, 0) else print("Нужен ключ!") end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 18 — «Качели» // ═══════════════════════════════════════════════════════════════ 'swing': { g18_main: `-- === ИГРА «КАЧЕЛИ» (Lua) === local TweenService = game:GetService("TweenService") local swing = workspace:WaitForChild("Качели") local startPos = swing.Position -- Качаем туда-сюда бесконечно task.spawn(function() while true do local up = TweenService:Create(swing, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { Position = startPos + Vector3.new(0, 0, 5) }) up:Play(); up.Completed:Wait() local down = TweenService:Create(swing, TweenInfo.new(1, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), { Position = startPos + Vector3.new(0, 0, -5) }) down:Play(); down.Completed:Wait() end end) print("Запрыгни на качающуюся платформу!")`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 19 — «Лифт» // ═══════════════════════════════════════════════════════════════ 'elevator': { g19_main: `-- === ИГРА «ЛИФТ» (Lua) === local TweenService = game:GetService("TweenService") local elevator = workspace:WaitForChild("Лифт") local startPos = elevator.Position local topPos = startPos + Vector3.new(0, 10, 0) local goingUp = true elevator.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end local goal = { Position = goingUp and topPos or startPos } TweenService:Create(elevator, TweenInfo.new(3), goal):Play() goingUp = not goingUp end) print("Встань на лифт — он повезёт тебя наверх!")`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 20 — «Имена врагов» // ═══════════════════════════════════════════════════════════════ 'enemy-names': { g20_main: `-- === ИГРА «ИМЕНА ВРАГОВ» (Lua) === local function addLabel(part, text, color) local bb = Instance.new("BillboardGui", part) bb.Size = UDim2.new(4, 0, 1, 0) bb.StudsOffset = Vector3.new(0, 2.5, 0) bb.AlwaysOnTop = true local label = Instance.new("TextLabel", bb) label.Size = UDim2.new(1, 0, 1, 0) label.BackgroundTransparency = 1 label.Text = text label.TextColor3 = color or Color3.new(1, 1, 1) label.TextScaled = true end for _, child in ipairs(workspace:GetChildren()) do if child:IsA("BasePart") and child.Name:match("^Враг") then addLabel(child, child.Name, Color3.fromRGB(255, 80, 80)) end end print("Над врагами появились имена")`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 21 — «Догонялки» // ═══════════════════════════════════════════════════════════════ 'chaser': { g21_main: `-- === ИГРА «ДОГОНЯЛКИ» (Lua) === local Players = game:GetService("Players") local RunService = game:GetService("RunService") local enemy = workspace:WaitForChild("Догонщик") RunService.Heartbeat:Connect(function(dt) local player = Players:GetPlayers()[1] if not player or not player.Character then return end local target = player.Character:FindFirstChild("HumanoidRootPart") if not target then return end -- Двигаемся в сторону игрока со скоростью 5 local dir = (target.Position - enemy.Position) if dir.Magnitude > 1 then enemy.Position = enemy.Position + dir.Unit * 5 * dt else -- Поймал local h = player.Character:FindFirstChild("Humanoid") if h then h:TakeDamage(10) end end end) print("Убегай от догонщика!")`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 22 — «Опасная зона» // ═══════════════════════════════════════════════════════════════ 'danger-zone': { g22_main: `-- === ИГРА «ОПАСНАЯ ЗОНА» (Lua) === print("Не стой в красной зоне!")`, g22_zone: `-- === Скрипт опасной зоны (Lua) === local part = script.Parent local insiders = {} part.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if h then insiders[h] = true end end) part.TouchEnded:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if h then insiders[h] = nil end end) -- Урон каждые 0.5 сек пока стоят while true do task.wait(0.5) for h in pairs(insiders) do if h.Parent then h:TakeDamage(5) end end end`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 23 — «3 переключателя» // ═══════════════════════════════════════════════════════════════ 'switches': { g23_main: `-- === ИГРА «3 ПЕРЕКЛЮЧАТЕЛЯ» (Lua) === ${SNIPPET_BROADCAST} local activated = {false, false, false} print("Активируй все 3 переключателя!") local ev = getEvent("SwitchToggled") ev.Event:Connect(function(idx) activated[idx] = true print("Переключатель " .. idx .. " активирован") if activated[1] and activated[2] and activated[3] then print("ПОБЕДА! Все 3 активированы!") end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 24 — «Падающий мост» // ═══════════════════════════════════════════════════════════════ 'falling-bridge': { g24_main: `-- === ИГРА «ПАДАЮЩИЙ МОСТ» (Lua) === print("Беги по мосту — плиты падают!")`, g24_plate: `-- === Скрипт падающей плиты (Lua) === local part = script.Parent local fell = false part.Touched:Connect(function(hit) if fell then return end local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end fell = true task.delay(0.5, function() part.Anchored = false part.CanCollide = false game:GetService("Debris"):AddItem(part, 3) end) end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 25 — «Облёт камеры» // ═══════════════════════════════════════════════════════════════ 'flyby-camera': { g25_main: `-- === ИГРА «ОБЛЁТ КАМЕРЫ» (Lua) === local TweenService = game:GetService("TweenService") local camera = workspace.CurrentCamera camera.CameraType = Enum.CameraType.Scriptable local points = { CFrame.new(Vector3.new(0, 20, -30), Vector3.new(0, 5, 0)), CFrame.new(Vector3.new(20, 15, 0), Vector3.new(0, 5, 0)), CFrame.new(Vector3.new(0, 25, 30), Vector3.new(0, 5, 0)), } for _, cf in ipairs(points) do local tween = TweenService:Create(camera, TweenInfo.new(2), { CFrame = cf }) tween:Play(); tween.Completed:Wait() end camera.CameraType = Enum.CameraType.Custom print("Облёт окончен — теперь играй!")`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 26 — «Магнит монет» // ═══════════════════════════════════════════════════════════════ 'coin-magnet': { g26_main: `-- === ИГРА «МАГНИТ МОНЕТ» (Lua) === local Players = game:GetService("Players") local RunService = game:GetService("RunService") local CollectionService = game:GetService("CollectionService") ${SNIPPET_BROADCAST} local score = 0 local ev = getEvent("CoinCollected") ev.Event:Connect(function() score = score + 1 print("Собрано: " .. score) end) RunService.Heartbeat:Connect(function(dt) local player = Players:GetPlayers()[1] if not player or not player.Character then return end local hrp = player.Character:FindFirstChild("HumanoidRootPart") if not hrp then return end for _, coin in ipairs(CollectionService:GetTagged("magnetcoin")) do local dist = (coin.Position - hrp.Position).Magnitude if dist < 8 then coin.Position = coin.Position + (hrp.Position - coin.Position).Unit * 20 * dt if dist < 1 then ev:Fire() coin:Destroy() end end end end) print("Монетки сами летят к тебе!")`, g26_coin: `-- === Скрипт магнит-монетки (Lua) === local CollectionService = game:GetService("CollectionService") CollectionService:AddTag(script.Parent, "magnetcoin")`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 27 — «Двойной прыжок» // ═══════════════════════════════════════════════════════════════ 'double-jump': { g27_main: `-- === ИГРА «ДВОЙНОЙ ПРЫЖОК» (Lua) === local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local function setupDoubleJump(player) local jumpsLeft = 2 local char = player.Character or player.CharacterAdded:Wait() local h = char:WaitForChild("Humanoid") -- Восстанавливаем прыжки при касании земли h.StateChanged:Connect(function(_, newState) if newState == Enum.HumanoidStateType.Landed then jumpsLeft = 2 end end) UserInputService.InputBegan:Connect(function(input, gp) if gp then return end if input.KeyCode == Enum.KeyCode.Space and jumpsLeft > 0 then jumpsLeft = jumpsLeft - 1 if jumpsLeft == 1 then local hrp = char:FindFirstChild("HumanoidRootPart") if hrp then hrp.Velocity = Vector3.new(hrp.Velocity.X, 50, hrp.Velocity.Z) end end end end) end Players.PlayerAdded:Connect(setupDoubleJump) for _, p in ipairs(Players:GetPlayers()) do setupDoubleJump(p) end print("Жми Space дважды — двойной прыжок!")`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 28 — «Призрачные стены» // ═══════════════════════════════════════════════════════════════ 'ghost-walls': { g28_main: `-- === ИГРА «ПРИЗРАЧНЫЕ СТЕНЫ» (Lua) === print("Некоторые стены — призрачные. Найди проход!")`, g28_ghost: `-- === Скрипт призрачной стены (Lua) === local part = script.Parent part.CanCollide = false part.Transparency = 0.5`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 29 — «Магазин» // ═══════════════════════════════════════════════════════════════ 'shop': { g29_main: `-- === ИГРА «МАГАЗИН» (Lua) === local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder", player); stats.Name = "leaderstats" local coins = Instance.new("IntValue", stats); coins.Name = "Монеты"; coins.Value = 20 end) for _, p in ipairs(Players:GetPlayers()) do if not p:FindFirstChild("leaderstats") then local stats = Instance.new("Folder", p); stats.Name = "leaderstats" local coins = Instance.new("IntValue", stats); coins.Name = "Монеты"; coins.Value = 20 end end print("У тебя 20 монет — купи что-нибудь!")`, g29_item: `-- === Скрипт товара (Lua) === local Players = game:GetService("Players") local part = script.Parent local price = part:GetAttribute("Price") or 5 local bought = false part.Touched:Connect(function(hit) if bought then return end local player = Players:GetPlayerFromCharacter(hit.Parent) if not player then return end local stats = player:FindFirstChild("leaderstats") if not stats then return end if stats['Монеты'].Value >= price then stats['Монеты'].Value = stats['Монеты'].Value - price bought = true print("Куплено! Цена: " .. price) part.Transparency = 0.7 else print("Не хватает! Нужно " .. price .. " монет") end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 30 — «Квесты» // ═══════════════════════════════════════════════════════════════ 'quest-tasks': { g30_main: `-- === ИГРА «КВЕСТЫ» (Lua) === ${SNIPPET_BROADCAST} local quests = { { name = "Собери 5 ягод", goal = 5, current = 0 }, { name = "Победи врага", goal = 1, current = 0 }, { name = "Дойди до башни", goal = 1, current = 0 }, } print("Квесты:") for i, q in ipairs(quests) do print(" " .. i .. ". " .. q.name) end local ev = getEvent("QuestProgress") ev.Event:Connect(function(idx, amount) quests[idx].current = quests[idx].current + (amount or 1) local q = quests[idx] print(q.name .. ": " .. q.current .. "/" .. q.goal) if q.current >= q.goal then print("Квест выполнен: " .. q.name) end end)`, }, // ═══════════════════════════════════════════════════════════════ // ИГРА 31-50: упрощённые версии (главные скрипты) // ═══════════════════════════════════════════════════════════════ 'base-defense': { g31_main: simpleMain("Защити базу от волн врагов!") }, 'lap-race': { g32_main: simpleMain("Проедь все круги первым!") }, 'boss-platformer': { g33_main: simpleMain("Победи босса прыжками на голову!") }, 'harvest': { g34_main: simpleMain("Собирай урожай, продавай в магазин!") }, 'hide-from-npc': { g35_main: simpleMain("Прячься от NPC — не попадайся!") }, 'box-puzzle': { g36_main: simpleMain("Двигай ящики на места!") }, 'obstacle-course': { g37_main: simpleMain("Пройди полосу препятствий!") }, 'music-game': { g38_main: simpleMain("Жми клавиши в ритм музыки!") }, 'tower-build': { g39_main: simpleMain("Построй самую высокую башню!") }, 'wave-survival': { g40_main: simpleMain("Выживай в волнах врагов!") }, 'adventure-platformer': { g41_main: simpleMain("Приключение — собирай артефакты!") }, 'rpg-village': { g42_main: simpleMain("Бегай по деревне, выполняй квесты!") }, 'obstacle-race': { g43_main: simpleMain("Гонка с препятствиями — финишируй!") }, 'tower-defense': { g44_main: simpleMain("Расставь башни — не пускай врагов!") }, 'arena-shooter': { g45_main: simpleMain("Стреляй по противникам на арене!") }, 'clicker': { g46_main: simpleClicker() }, 'escape-quest': { g47_main: simpleMain("Найди подсказки и выберись!") }, 'mp-tag': { g48_main: simpleMain("Поймай других игроков (мультиплеер)!") }, 'mp-race': { g49_main: simpleMain("Гонка на нескольких игроков!") }, 'make-your-own': { g50_main: simpleMain("Это твоя пустая площадка — твори!") }, }; // ══════════════════════════════════════════════════════════════════ // Хелперы для генерации часто повторяющихся скриптов // ══════════════════════════════════════════════════════════════════ /** Возвращает Lua-код скрипта монетки. */ function makeCoinScript() { return `-- === Скрипт монетки (Lua) === local ReplicatedStorage = game:GetService("ReplicatedStorage") local part = script.Parent part.Touched:Connect(function(hit) local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") if not h then return end local ev = ReplicatedStorage:FindFirstChild("CoinCollected") if ev then ev:Fire() end part:Destroy() end)`; } /** Простой главный скрипт со стартовой подсказкой. */ function simpleMain(message) { return `-- === Главный скрипт (Lua) === print("${message.replace(/"/g, '\\"')}") -- TODO: эта игра-урок ещё не имеет полной Lua-реализации. -- Переключи язык на JS в редакторе, чтобы увидеть рабочую механику.`; } /** Кликер. */ function simpleClicker() { return `-- === КЛИКЕР (Lua) === local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") Players.PlayerAdded:Connect(function(player) local stats = Instance.new("Folder", player); stats.Name = "leaderstats" local cnt = Instance.new("IntValue", stats); cnt.Name = "Клики"; cnt.Value = 0 end) for _, p in ipairs(Players:GetPlayers()) do if not p:FindFirstChild("leaderstats") then local stats = Instance.new("Folder", p); stats.Name = "leaderstats" local cnt = Instance.new("IntValue", stats); cnt.Name = "Клики"; cnt.Value = 0 end end local function onClick(player) local stats = player:FindFirstChild("leaderstats") if stats and stats:FindFirstChild("Клики") then stats['Клики'].Value = stats['Клики'].Value + 1 end end UserInputService.InputBegan:Connect(function(input, gp) if gp then return end if input.UserInputType == Enum.UserInputType.MouseButton1 then onClick(Players.LocalPlayer) end end) print("Кликай ЛКМ — копи клики!")`; }