feat(g19): полный паритет «Лифт» — Heartbeat yo-yo

Игра 19 падала на WaitForChild + Vector3 + (оператор не поддержан).

Lua паритет с JS:
- showText 'Встань на синий лифт — он повезёт наверх'
- task.delay 0.2c для FindFirstChild('Лифт') (WaitForChild может зависать)
- Heartbeat yo-yo по Y: startY (1) ↔ TOP_Y (12.3) с периодом 7с
  (3.5с вверх + 3.5с вниз через треугольную функцию)
- Vector3.new напрямую (без +)
- Респаун при y<-3
- BindableEvent WinReached + g19_finish.Touched → ev:Fire
- При победе: showText 'Победа!' + win Sound + confetti
This commit is contained in:
min 2026-06-09 20:26:19 +03:00
parent 98e92b23a7
commit c489a31854

View File

@ -1638,21 +1638,82 @@ end)`,
// ИГРА 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)
g19_main: `-- === ИГРА «ЛИФТ» — главный скрипт (Lua) ===
${SNIPPET_BROADCAST}
local goingUp = true
elevator.Touched:Connect(function(hit)
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local won = false
__rbxl_show_text("Встань на синий лифт — он повезёт наверх", 3)
local winSound = Instance.new("Sound", workspace)
winSound.SoundId = "win"; winSound.Volume = 1
-- Лифт ездит вверх-вниз. WaitForChild зависает, поэтому FindFirstChild
-- с задержкой через task.delay.
local lift = nil
local startY = 1
local TOP_Y = 12.3
local PERIOD = 7 -- полный цикл внизвверхвниз (3.5с вверх + 3.5с вниз)
local elapsed = 0
task.delay(0.2, function()
lift = workspace:FindFirstChild("Лифт")
if lift then startY = lift.Position.Y end
end)
RunService.Heartbeat:Connect(function(dt)
if won then return end
dt = dt or 0.016
-- Лифт двигается
if lift then
elapsed = elapsed + dt
-- Yo-yo: 0..PERIOD/2 вверх, PERIOD/2..PERIOD вниз
local t = (elapsed % PERIOD) / PERIOD
local k
if t < 0.5 then
k = t * 2 -- 0..1
else
k = (1 - t) * 2 -- 1..0
end
local y = startY + (TOP_Y - startY) * k
local pos = lift.Position
lift.Position = Vector3.new(pos.X, y, pos.Z)
end
-- Падение
local py = __rbxl_player_y()
if py < -3 then
player:LoadCharacter()
end
end)
-- Финиш
local winEvent = getEvent("WinReached")
winEvent.Event:Connect(function()
if won then return end
won = true
winSound:Play()
__rbxl_show_text("Победа! Ты поднялся на лифте!", 5)
local px = __rbxl_player_x()
local py = __rbxl_player_y()
local pz = __rbxl_player_z()
__rbxl_spawn_particles("confetti", px, py + 3, pz, 3, 3)
end)`,
g19_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
local goal = { Position = goingUp and topPos or startPos }
TweenService:Create(elevator, TweenInfo.new(3), goal):Play()
goingUp = not goingUp
end)
print("Встань на лифт — он повезёт тебя наверх!")`,
fired = true
local ev = ReplicatedStorage:FindFirstChild("WinReached")
if ev then ev:Fire() end
end)`,
},
// ═══════════════════════════════════════════════════════════════