feat: 50 игр на Lua + импорт Roblox для всех + поддержка Lua в плеере #39

Merged
min merged 215 commits from feat/lua-50-games-bundle into main 2026-06-09 21:59:25 +00:00
2 changed files with 89 additions and 5 deletions
Showing only changes of commit f3b0cabdbd - Show all commits

View File

@ -2940,7 +2940,91 @@ end)`;
})(),
// ═══════════════════════════════════════════════════════════════
// ИГРЫ 33-50: явных Lua-версий пока нет.
// ИГРА 33 — «Платформер с боссом»
// ═══════════════════════════════════════════════════════════════
'boss-platformer': {
g33_main: `-- === ИГРА «ПЛАТФОРМЕР С БОССОМ» — главный скрипт (Lua) ===
${SNIPPET_BROADCAST}
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local won = false
local bossSpawned = false
local bossHp = 120
local MAX_HP = 120
local bossRef = nil
__rbxl_show_text("Пройди паркур до арены босса!", 3)
local hitSound = Instance.new("Sound", workspace)
hitSound.SoundId = "hit"; hitSound.Volume = 0.6
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
-- Клик по боссу (через __rbxl_npc_on_click при спавне)
local function onBossHit()
if won then return end
local pp_x = __rbxl_player_x()
local pp_z = __rbxl_player_z()
local bp_x = __rbxl_npc_x(bossRef)
local bp_z = __rbxl_npc_z(bossRef)
local dx = pp_x - bp_x
local dz = pp_z - bp_z
local dist = math.sqrt(dx*dx + dz*dz)
if dist < 5 then
bossHp = bossHp - 20
if bossHp < 0 then bossHp = 0 end
__rbxl_npc_damage(bossRef, 20)
__rbxl_set_label(bossRef, "БОСС HP: " .. bossHp, "#ff3333", 2.5)
__rbxl_spawn_particles("sparks", bp_x, 2, bp_z, 0.4, 1)
hitSound:Play()
end
end
-- Heartbeat: респаун при падении + спавн босса при подходе к арене
RunService.Heartbeat:Connect(function()
if won then return end
local py = __rbxl_player_y()
if py < -3 then
player:LoadCharacter()
loseSound:Play()
return
end
if not bossSpawned then
local pz = __rbxl_player_z()
if pz > 24 and py > 5 then
bossSpawned = true
bossRef = __rbxl_spawn_npc("character-b", 0, 7, 32, "БОСС", MAX_HP, 2)
task.delay(0.3, function()
__rbxl_npc_follow(bossRef, "player")
__rbxl_set_label(bossRef, "БОСС HP: " .. MAX_HP, "#ff3333", 2.5)
end)
__rbxl_show_text("БОСС! Кликай по нему!", 3)
-- Подписка на клик по боссу
__rbxl_npc_on_click(bossRef, onBossHit)
-- Подписка на смерть
__rbxl_npc_on_death(bossRef, function()
if won then return end
won = true
__rbxl_clear_label(bossRef)
__rbxl_show_text("Победа! Босс повержен!", 5)
winSound:Play()
local px = __rbxl_player_x()
local py2 = __rbxl_player_y()
local pz2 = __rbxl_player_z()
__rbxl_spawn_particles("confetti", px, py2 + 3, pz2, 3, 3)
end)
end
end
end)`,
},
// ═══════════════════════════════════════════════════════════════
// ИГРЫ 34-50: явных Lua-версий пока нет.
// buildGameProject в docsGamesBuilders.js использует generateFallbackLua
// (главный скрипт → показ подсказки + слушает FinishReached →
// победа+конфетти; скрипт на финиш-примитиве → шлёт FinishReached;

View File

@ -4509,7 +4509,7 @@ game.every(2, () => {
<h3 className="lessonH">Шаг 2. Главный скрипт</h3>
<ScriptKind kind="global" />
<Code>{`// === ИГРА «ГОНКА С КРУГАМИ» — главный скрипт ===
<CodeBoth game="lap-race" script="g32_main">{`// === ИГРА «ГОНКА С КРУГАМИ» — главный скрипт ===
const LAPS = 2; // сколько кругов проехать
const CP_COUNT = 4; // чекпоинтов на круге
@ -4552,7 +4552,7 @@ game.onMessage('checkpoint', (d) => {
game.ui.showText('Круг ' + lap + ' из ' + LAPS + '!', 2);
}
}
});`}</Code>
});`}</CodeBoth>
<p>Главное здесь порядок чекпоинтов:</p>
<ul>
<li><code>game.onMessage('checkpoint', (d) =&gt; {'{...}'})</code>
@ -4584,10 +4584,10 @@ game.onMessage('checkpoint', (d) => {
номер. Вот скрипт первого чекпоинта:
</p>
<ScriptKind kind="object" on=екпоинт_1" />
<Code>{`// === Скрипт чекпоинта 1 ===
<CodeBoth game="lap-race" script="g32_cp_1">{`// === Скрипт чекпоинта 1 ===
game.self.onTouch(() => {
game.broadcast('checkpoint', { num: 1 });
});`}</Code>
});`}</CodeBoth>
<p>
Чекпоинт шлёт сообщение
<code> game.broadcast('checkpoint', {'{ num: 1 }'})</code>: