From dc669a51f4727bca89eac4ba46c0b04d73dcec76 Mon Sep 17 00:00:00 2001 From: min Date: Tue, 9 Jun 2026 23:00:37 +0300 Subject: [PATCH] =?UTF-8?q?docs(43)=20+=20feat(g44):=20=C2=ABTower=20Defen?= =?UTF-8?q?se=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g43 docs: CodeBoth main+boost_1+spike_4+finish. g44 паритет: - GOAL=14, MAX_LEAK=8, killed/leaked counters - towers[] и enemies{} (ref-keyed) - BindableEvent TowerBuilt(x, z) - Heartbeat spawn: 2.2с → npc 'character-b' speed=2 hp=50 в (-0.5,1,-3), task.delay 0.3 moveTo (-0.5, 42), on_death → killed++ - Heartbeat fire: 0.8с → каждая башня бьёт ближайшего врага в r=7 (npc.damage 25 + sparks) - Heartbeat leak: 0.5с → ez>40 → npc.remove + leaked++ + lose - 4 g44_slot_N: Heartbeat distance(4) + '[E] Построить башню' E → Instance.new('Part') Cylinder жёлтый + TowerBuilt:Fire --- src/community/docsGamesBuildersLua.js | 172 +++++++++++++++++++++++++- src/community/docsLessons.jsx | 16 +-- 2 files changed, 179 insertions(+), 9 deletions(-) diff --git a/src/community/docsGamesBuildersLua.js b/src/community/docsGamesBuildersLua.js index d29a593..6f128a9 100644 --- a/src/community/docsGamesBuildersLua.js +++ b/src/community/docsGamesBuildersLua.js @@ -4058,7 +4058,177 @@ end)`; })(), // ═══════════════════════════════════════════════════════════════ - // ИГРЫ 44-50: явных Lua-версий пока нет. + // ИГРА 44 — «Tower Defense» + // ═══════════════════════════════════════════════════════════════ + 'tower-defense': (function() { + const SLOT_IDS = [1, 2, 3, 4]; + const overrides = { + g44_main: `-- === ИГРА «TOWER DEFENSE» — главный скрипт (Lua) === +${SNIPPET_BROADCAST} + +local RunService = game:GetService("RunService") +local MAX_LEAK = 8 +local GOAL = 14 +local leaked = 0 +local killed = 0 +local over = false + +-- Список башен ({x, z}) +local towers = {} +-- Все враги: ref → { ref, alive } +local enemies = {} + +__rbxl_score_set(0) +__rbxl_show_text("Ставь башни (E)! Не пропусти врагов", 4) + +local clickSound = Instance.new("Sound", workspace) +clickSound.SoundId = "click"; clickSound.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 + +-- Площадки шлют TowerBuilt:Fire(x, z) +local towerEvent = getEvent("TowerBuilt") +towerEvent.Event:Connect(function(x, z) + table.insert(towers, { x = x, z = z }) + clickSound:Play() + __rbxl_show_text("Башня построена!", 1.5) +end) + +-- Спавн врагов каждые 2.2с +local total = 0 +local spawnTimer = 0 +RunService.Heartbeat:Connect(function(dt) + if over then return end + if total >= GOAL + MAX_LEAK then return end + spawnTimer = spawnTimer + dt + if spawnTimer < 2.2 then return end + spawnTimer = 0 + total = total + 1 + local ref = __rbxl_spawn_npc("character-b", -0.5, 1, -3, "Враг", 50, 2) + local rec = { ref = ref, alive = true } + enemies[ref] = rec + task.delay(0.3, function() + __rbxl_npc_moveto(ref, -0.5, 42) + end) + __rbxl_npc_on_death(ref, function() + rec.alive = false + killed = killed + 1 + __rbxl_score_set(killed) + if killed >= GOAL and not over then + over = true + __rbxl_show_text("Победа! База защищена!", 5) + winSound:Play() + end + end) +end) + +-- Башни стреляют каждые 0.8с — бьют врага в радиусе 7 от любой башни +local fireTimer = 0 +RunService.Heartbeat:Connect(function(dt) + if over then return end + fireTimer = fireTimer + dt + if fireTimer < 0.8 then return end + fireTimer = 0 + for _, t in ipairs(towers) do + for _, e in pairs(enemies) do + if e.alive then + local ex = __rbxl_npc_x(e.ref) + local ez = __rbxl_npc_z(e.ref) + if not (ex == 0 and ez == 0) then + local dx = t.x - ex + local dz = t.z - ez + local dist = math.sqrt(dx*dx + dz*dz) + if dist < 7 then + __rbxl_npc_damage(e.ref, 25) + __rbxl_spawn_particles("sparks", ex, 2, ez, 0.3, 1) + break -- одна башня — один выстрел за тик + end + end + end + end + end +end) + +-- Прорыв врагов до базы (z > 40) каждые 0.5с +local leakTimer = 0 +RunService.Heartbeat:Connect(function(dt) + if over then return end + leakTimer = leakTimer + dt + if leakTimer < 0.5 then return end + leakTimer = 0 + for _, e in pairs(enemies) do + if e.alive then + local ez = __rbxl_npc_z(e.ref) + local ex = __rbxl_npc_x(e.ref) + if not (ex == 0 and ez == 0) and ez > 40 then + e.alive = false + __rbxl_npc_remove(e.ref) + leaked = leaked + 1 + loseSound:Play() + __rbxl_show_text("Враг прорвался! (" .. leaked .. "/" .. MAX_LEAK .. ")", 2) + if leaked >= MAX_LEAK and not over then + over = true + __rbxl_show_text("База разрушена! Поражение.", 5) + end + end + end + end +end)`, + }; + // 4 площадки — E ставит жёлтый цилиндр-башню сверху + for (const sid of SLOT_IDS) { + overrides['g44_slot_' + sid] = `-- === Скрипт площадки под башню (Lua) === +local UserInputService = game:GetService("UserInputService") +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local RunService = game:GetService("RunService") +local part = script.Parent +local built = false +local hintVisible = false + +RunService.Heartbeat:Connect(function() + if built then return end + local px = __rbxl_player_x() + local pz = __rbxl_player_z() + local dx = part.Position.X - px + local dz = part.Position.Z - pz + local dist = math.sqrt(dx*dx + dz*dz) + local near = dist <= 4 + if near ~= hintVisible then + hintVisible = near + if near then + __rbxl_hud_set("g44_slot_${sid}_hint", "[E] Построить башню", 50, 75, "#ffe44a", 20) + else + __rbxl_hud_set("g44_slot_${sid}_hint", nil) + end + end +end) + +UserInputService.InputBegan:Connect(function(input, gp) + if gp then return end + if not hintVisible then return end + if built then return end + if input.KeyCode ~= Enum.KeyCode.E then return end + built = true + __rbxl_hud_set("g44_slot_${sid}_hint", nil) + -- Создаём башню — жёлтый цилиндр над площадкой + local tower = Instance.new("Part") + tower.Shape = Enum.PartType.Cylinder + tower.Size = Vector3.new(1.5, 3, 1.5) + tower.Position = Vector3.new(part.Position.X, part.Position.Y + 2.5, part.Position.Z) + tower.Color = Color3.fromRGB(255, 204, 51) + tower.Anchored = true + tower.Parent = workspace + local ev = ReplicatedStorage:FindFirstChild("TowerBuilt") + if ev then ev:Fire(part.Position.X, part.Position.Z) end +end)`; + } + return overrides; + })(), + + // ═══════════════════════════════════════════════════════════════ + // ИГРЫ 45-50: явных Lua-версий пока нет. // buildGameProject в docsGamesBuilders.js использует generateFallbackLua // (главный скрипт → показ подсказки + слушает FinishReached → // победа+конфетти; скрипт на финиш-примитиве → шлёт FinishReached; diff --git a/src/community/docsLessons.jsx b/src/community/docsLessons.jsx index 00d3e74..fffb30a 100644 --- a/src/community/docsLessons.jsx +++ b/src/community/docsLessons.jsx @@ -6144,7 +6144,7 @@ game.self.onTouch(() => {

Шаг 2. Главный скрипт

- {`// === ИГРА «ГОНКА С ПРЕПЯТСТВИЯМИ» — главный скрипт === + {`// === ИГРА «ГОНКА С ПРЕПЯТСТВИЯМИ» — главный скрипт === let time = 0; let won = false; @@ -6185,7 +6185,7 @@ game.onMessage('finish', () => { const p = game.player.position; game.scene.spawnParticles('confetti', { x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 }); -});`} +});`}

Разберём: