feat: 50 игр на Lua + импорт Roblox для всех + поддержка Lua в плеере #39
@ -3125,7 +3125,73 @@ end)`;
|
|||||||
})(),
|
})(),
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
// ИГРЫ 35-50: явных Lua-версий пока нет.
|
// ИГРА 35 — «Прятки от NPC»
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
'hide-from-npc': {
|
||||||
|
g35_main: `-- === ИГРА «ПРЯТКИ ОТ NPC» — главный скрипт (Lua) ===
|
||||||
|
${SNIPPET_BROADCAST}
|
||||||
|
|
||||||
|
local Players = game:GetService("Players")
|
||||||
|
local RunService = game:GetService("RunService")
|
||||||
|
local player = Players.LocalPlayer
|
||||||
|
|
||||||
|
local SURVIVE = 40
|
||||||
|
local time = 0
|
||||||
|
local won = false
|
||||||
|
local lastCaughtTime = 0
|
||||||
|
|
||||||
|
__rbxl_timer_set(0)
|
||||||
|
__rbxl_show_text("Прячься за стенами 40 секунд!", 4)
|
||||||
|
|
||||||
|
local loseSound = Instance.new("Sound", workspace)
|
||||||
|
loseSound.SoundId = "lose"; loseSound.Volume = 0.7
|
||||||
|
local winSound = Instance.new("Sound", workspace)
|
||||||
|
winSound.SoundId = "win"; winSound.Volume = 1
|
||||||
|
|
||||||
|
-- NPC-искатель ходит за игроком
|
||||||
|
local seekerRef = __rbxl_spawn_npc("character-b", 0, 1, 10, "Искатель", 100, 3)
|
||||||
|
task.delay(0.3, function()
|
||||||
|
__rbxl_npc_follow(seekerRef, "player")
|
||||||
|
end)
|
||||||
|
|
||||||
|
RunService.Heartbeat:Connect(function(dt)
|
||||||
|
if won then return end
|
||||||
|
time = time + dt
|
||||||
|
__rbxl_timer_set(time)
|
||||||
|
|
||||||
|
-- Поймал — респаун
|
||||||
|
local px = __rbxl_player_x()
|
||||||
|
local pz = __rbxl_player_z()
|
||||||
|
local ex = __rbxl_npc_x(seekerRef)
|
||||||
|
local ez = __rbxl_npc_z(seekerRef)
|
||||||
|
if not (ex == 0 and ez == 0) then
|
||||||
|
local dx = px - ex
|
||||||
|
local dz = pz - ez
|
||||||
|
local dist = math.sqrt(dx*dx + dz*dz)
|
||||||
|
if dist < 1.7 then
|
||||||
|
local now = tick()
|
||||||
|
if now - lastCaughtTime > 2 then
|
||||||
|
lastCaughtTime = now
|
||||||
|
player:LoadCharacter()
|
||||||
|
__rbxl_show_text("Найден! Прячься снова!", 1.5)
|
||||||
|
loseSound:Play()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Продержался 40 секунд — победа
|
||||||
|
if time >= SURVIVE then
|
||||||
|
won = true
|
||||||
|
__rbxl_npc_stop(seekerRef)
|
||||||
|
__rbxl_show_text("Победа! Ты прятался 40 секунд!", 5)
|
||||||
|
winSound:Play()
|
||||||
|
__rbxl_spawn_particles("confetti", px, 1, pz, 3, 3)
|
||||||
|
end
|
||||||
|
end)`,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ═══════════════════════════════════════════════════════════════
|
||||||
|
// ИГРЫ 36-50: явных Lua-версий пока нет.
|
||||||
// buildGameProject в docsGamesBuilders.js использует generateFallbackLua
|
// buildGameProject в docsGamesBuilders.js использует generateFallbackLua
|
||||||
// (главный скрипт → показ подсказки + слушает FinishReached →
|
// (главный скрипт → показ подсказки + слушает FinishReached →
|
||||||
// победа+конфетти; скрипт на финиш-примитиве → шлёт FinishReached;
|
// победа+конфетти; скрипт на финиш-примитиве → шлёт FinishReached;
|
||||||
|
|||||||
@ -4811,7 +4811,7 @@ game.onTick(() => {
|
|||||||
|
|
||||||
<h3 className="lessonH">Шаг 2. Главный скрипт</h3>
|
<h3 className="lessonH">Шаг 2. Главный скрипт</h3>
|
||||||
<ScriptKind kind="global" />
|
<ScriptKind kind="global" />
|
||||||
<Code>{`// === ИГРА «СБОР УРОЖАЯ» — главный скрипт ===
|
<CodeBoth game="harvest" script="g34_main">{`// === ИГРА «СБОР УРОЖАЯ» — главный скрипт ===
|
||||||
|
|
||||||
let harvested = 0;
|
let harvested = 0;
|
||||||
const GOAL = 6;
|
const GOAL = 6;
|
||||||
@ -4831,7 +4831,7 @@ game.onMessage('harvested', () => {
|
|||||||
game.scene.spawnParticles('confetti',
|
game.scene.spawnParticles('confetti',
|
||||||
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
|
{ x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 });
|
||||||
}
|
}
|
||||||
});`}</Code>
|
});`}</CodeBoth>
|
||||||
<p>
|
<p>
|
||||||
Главный скрипт считает собранные растения и проверяет
|
Главный скрипт считает собранные растения и проверяет
|
||||||
победу. Каждое растение работает в своей «песочнице»,
|
победу. Каждое растение работает в своей «песочнице»,
|
||||||
@ -4845,7 +4845,7 @@ game.onMessage('harvested', () => {
|
|||||||
<h3 className="lessonH">Шаг 3. Скрипт растения</h3>
|
<h3 className="lessonH">Шаг 3. Скрипт растения</h3>
|
||||||
<p>Этот скрипт вешается на <b>каждое</b> растение.</p>
|
<p>Этот скрипт вешается на <b>каждое</b> растение.</p>
|
||||||
<ScriptKind kind="object" on="каждое растение" />
|
<ScriptKind kind="object" on="каждое растение" />
|
||||||
<Code>{`// === Скрипт растения ===
|
<CodeBoth game="harvest" script="g34_plant_1">{`// === Скрипт растения ===
|
||||||
|
|
||||||
let ripe = false; // растение выросло (спелое)?
|
let ripe = false; // растение выросло (спелое)?
|
||||||
let picked = false;
|
let picked = false;
|
||||||
@ -4870,7 +4870,7 @@ game.self.onInteract(() => {
|
|||||||
picked = true;
|
picked = true;
|
||||||
game.self.delete();
|
game.self.delete();
|
||||||
game.broadcast('harvested');
|
game.broadcast('harvested');
|
||||||
}, { text: 'Собрать', distance: 3 });`}</Code>
|
}, { text: 'Собрать', distance: 3 });`}</CodeBoth>
|
||||||
<p>Разберём:</p>
|
<p>Разберём:</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>game.tween(ref, {'{ sx, sy, sz, y }'}, опции)</code> —
|
<li><code>game.tween(ref, {'{ sx, sy, sz, y }'}, опции)</code> —
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user