feat(lua-games): полный паритет для игры 9 «Светофор»
JS:
- showText 'Зелёный — беги! Красный — замри!'
- light=findOne('Светофор'), green/red/green циклически (3с/2.5с)
- setColor light на красный/зелёный + showText
- onTick: если красный и moved/dt>0.8 — respawn + lose sound
- onMessage 'win' → showText + win + confetti
- g9_finish: onTouch → broadcast 'win'
Lua (паритет):
- __rbxl_show_text для всех подсказок
- Heartbeat-таймер фазы (task.spawn не умеет yield) — переключает
phase 'green'/'red' каждые GREEN_TIME/RED_TIME
- light=workspace:FindFirstChild('Светофор'), .Color = Color3.fromRGB
- Heartbeat: prevX/prevZ, при phase=red и moved/dt>0.8 → LoadCharacter
+ lose Sound + 'Двинулся на красный!'
- BindableEvent WinReached
- g9_finish: Touched → ev:Fire с fired-флагом
- При победе: win Sound + confetti
This commit is contained in:
parent
41e0f7b6a4
commit
bec3c478e7
@ -632,41 +632,89 @@ end)`,
|
|||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
'traffic-light': {
|
'traffic-light': {
|
||||||
g9_main: `-- === ИГРА «СВЕТОФОР» — главный скрипт (Lua) ===
|
g9_main: `-- === ИГРА «СВЕТОФОР» — главный скрипт (Lua) ===
|
||||||
|
${SNIPPET_BROADCAST}
|
||||||
|
|
||||||
local Players = game:GetService("Players")
|
local Players = game:GetService("Players")
|
||||||
local RunService = game:GetService("RunService")
|
local RunService = game:GetService("RunService")
|
||||||
|
local player = Players.LocalPlayer
|
||||||
|
local won = false
|
||||||
|
local phase = "green" -- "green" (беги) или "red" (замри)
|
||||||
|
local phaseTimer = 0
|
||||||
|
local GREEN_TIME = 3
|
||||||
|
local RED_TIME = 2.5
|
||||||
|
|
||||||
local isGreen = true
|
__rbxl_show_text("Зелёный — беги! Красный — замри!", 3)
|
||||||
print("ЗЕЛЁНЫЙ — беги!")
|
|
||||||
|
|
||||||
-- Каждые 3-5 сек переключаем свет
|
local loseSound = Instance.new("Sound", workspace)
|
||||||
task.spawn(function()
|
loseSound.SoundId = "lose"; loseSound.Volume = 1
|
||||||
while true do
|
local winSound = Instance.new("Sound", workspace)
|
||||||
task.wait(math.random(3, 5))
|
winSound.SoundId = "win"; winSound.Volume = 1
|
||||||
isGreen = not isGreen
|
|
||||||
if isGreen then
|
-- Находим светофор и сразу красим в зелёный
|
||||||
print("ЗЕЛЁНЫЙ — беги!")
|
local light = workspace:FindFirstChild("Светофор")
|
||||||
else
|
if light then light.Color = Color3.fromRGB(34, 221, 85) end
|
||||||
print("КРАСНЫЙ — стой!")
|
__rbxl_show_text("ЗЕЛЁНЫЙ — беги!", 1.2)
|
||||||
|
|
||||||
|
-- Каждый кадр считаем таймер фазы и проверяем движение
|
||||||
|
local prevX, prevZ = nil, nil
|
||||||
|
RunService.Heartbeat:Connect(function(dt)
|
||||||
|
if won then return end
|
||||||
|
dt = dt or 0.016
|
||||||
|
|
||||||
|
-- Переключение фаз
|
||||||
|
phaseTimer = phaseTimer + dt
|
||||||
|
if phase == "green" and phaseTimer >= GREEN_TIME then
|
||||||
|
phaseTimer = 0
|
||||||
|
phase = "red"
|
||||||
|
if light then light.Color = Color3.fromRGB(226, 59, 59) end
|
||||||
|
__rbxl_show_text("КРАСНЫЙ — замри!", 1.2)
|
||||||
|
elseif phase == "red" and phaseTimer >= RED_TIME then
|
||||||
|
phaseTimer = 0
|
||||||
|
phase = "green"
|
||||||
|
if light then light.Color = Color3.fromRGB(34, 221, 85) end
|
||||||
|
__rbxl_show_text("ЗЕЛЁНЫЙ — беги!", 1.2)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Если красный и игрок шевелится — респаун
|
||||||
|
local px = __rbxl_player_x()
|
||||||
|
local pz = __rbxl_player_z()
|
||||||
|
if prevX and phase == "red" then
|
||||||
|
local dx = px - prevX
|
||||||
|
local dz = pz - prevZ
|
||||||
|
local moved = math.sqrt(dx*dx + dz*dz)
|
||||||
|
if moved / dt > 0.8 then
|
||||||
|
player:LoadCharacter()
|
||||||
|
loseSound:Play()
|
||||||
|
__rbxl_show_text("Двинулся на красный! На старт.", 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
prevX, prevZ = px, pz
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Следим за движением игрока во время красного
|
-- Финиш-зона шлёт BindableEvent
|
||||||
local lastPos = {}
|
local winEvent = getEvent("WinReached")
|
||||||
RunService.Heartbeat:Connect(function()
|
winEvent.Event:Connect(function()
|
||||||
if isGreen then return end
|
if won then return end
|
||||||
for _, player in ipairs(Players:GetPlayers()) do
|
won = true
|
||||||
local char = player.Character
|
winSound:Play()
|
||||||
local hrp = char and char:FindFirstChild("HumanoidRootPart")
|
__rbxl_show_text("Победа! Ты дошёл до финиша!", 5)
|
||||||
if hrp then
|
local px = __rbxl_player_x()
|
||||||
local prev = lastPos[player]
|
local py = __rbxl_player_y()
|
||||||
if prev and (hrp.Position - prev).Magnitude > 0.5 then
|
local pz = __rbxl_player_z()
|
||||||
print(player.Name .. " двигался на красный! Респаун")
|
__rbxl_spawn_particles("confetti", px, py + 3, pz, 3, 3)
|
||||||
player:LoadCharacter()
|
end)`,
|
||||||
end
|
g9_finish: `-- === Скрипт финиша (Lua) ===
|
||||||
lastPos[player] = hrp.Position
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||||
end
|
local part = script.Parent
|
||||||
end
|
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("WinReached")
|
||||||
|
if ev then ev:Fire() end
|
||||||
end)`,
|
end)`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user