From 1c5e5fe5bbce7192b253de5ede0ff04646b9f218 Mon Sep 17 00:00:00 2001
From: min
Date: Tue, 9 Jun 2026 23:04:21 +0300
Subject: [PATCH] =?UTF-8?q?docs(44)=20+=20feat(g45):=20=C2=AB=D0=A1=D1=82?=
=?UTF-8?q?=D1=80=D0=B5=D0=BB=D1=8F=D0=BB=D0=BA=D0=B0-=D0=B0=D1=80=D0=B5?=
=?UTF-8?q?=D0=BD=D0=B0=C2=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
g44 docs: CodeBoth main+slot_1.
g45 паритет:
- GOAL=15, score/over
- Humanoid.Died → 'Поражение!'
- BindableEvent EnemyClicked(ref)
- Heartbeat spawn 1.8с: радиус=11 cos/sin → npc 'character-b'
hp=30 speed=2.2 follow('player')
- npc_on_click → EnemyClicked:Fire(ref)
- Главный: dist<6 → npc.remove + explosion + score++
- 15 → 'Победа!' + confetti
- Heartbeat damage: каждый враг dist<1.8 + last>0.7 → damage_player(10) + hit
---
src/community/docsGamesBuildersLua.js | 117 +++++++++++++++++++++++++-
src/community/docsLessons.jsx | 8 +-
2 files changed, 120 insertions(+), 5 deletions(-)
diff --git a/src/community/docsGamesBuildersLua.js b/src/community/docsGamesBuildersLua.js
index 6f128a9..f526c48 100644
--- a/src/community/docsGamesBuildersLua.js
+++ b/src/community/docsGamesBuildersLua.js
@@ -4228,7 +4228,122 @@ end)`;
})(),
// ═══════════════════════════════════════════════════════════════
- // ИГРЫ 45-50: явных Lua-версий пока нет.
+ // ИГРА 45 — «Стрелялка-арена»
+ // ═══════════════════════════════════════════════════════════════
+ 'arena-shooter': {
+ g45_main: `-- === ИГРА «СТРЕЛЯЛКА-АРЕНА» — главный скрипт (Lua) ===
+${SNIPPET_BROADCAST}
+
+local Players = game:GetService("Players")
+local RunService = game:GetService("RunService")
+local player = Players.LocalPlayer
+
+local GOAL = 15
+local score = 0
+local over = false
+
+-- Враги: { ref → { ref, alive, lastDmg } }
+local enemies = {}
+
+__rbxl_score_set(0)
+__rbxl_show_text("Перебей 15 врагов! Кликай по ним", 3)
+
+local hitSound = Instance.new("Sound", workspace)
+hitSound.SoundId = "hit"; hitSound.Volume = 0.6
+local winSound = Instance.new("Sound", workspace)
+winSound.SoundId = "win"; winSound.Volume = 1
+
+-- Подписка на смерть игрока
+task.delay(0.5, function()
+ local char = player.Character or player.CharacterAdded:Wait()
+ local h = char:WaitForChild("Humanoid", 2)
+ if h then
+ h.Died:Connect(function()
+ if over then return end
+ over = true
+ __rbxl_show_text("Поражение! Тебя одолели враги.", 5)
+ end)
+ end
+end)
+
+-- Клик по врагу: EnemyClicked:Fire(ref)
+local clickEvent = getEvent("EnemyClicked")
+clickEvent.Event:Connect(function(localRef)
+ if over then return end
+ local e = enemies[localRef]
+ if not e or not e.alive then return end
+ local px = __rbxl_player_x()
+ local pz = __rbxl_player_z()
+ local ex = __rbxl_npc_x(localRef)
+ local ez = __rbxl_npc_z(localRef)
+ if ex == 0 and ez == 0 then return end
+ local dx = px - ex
+ local dz = pz - ez
+ local dist = math.sqrt(dx*dx + dz*dz)
+ if dist < 6 then
+ e.alive = false
+ __rbxl_npc_remove(localRef)
+ __rbxl_spawn_particles("explosion", ex, 2, ez, 0.4, 1)
+ hitSound:Play()
+ score = score + 1
+ __rbxl_score_set(score)
+ if score >= GOAL and not over then
+ over = true
+ __rbxl_show_text("Победа! Арена зачищена!", 5)
+ winSound:Play()
+ __rbxl_spawn_particles("confetti", px, 3, pz, 3, 3)
+ end
+ end
+end)
+
+-- Спавн каждые 1.8с
+local spawnTimer = 0
+RunService.Heartbeat:Connect(function(dt)
+ if over or score >= GOAL then return end
+ spawnTimer = spawnTimer + dt
+ if spawnTimer < 1.8 then return end
+ spawnTimer = 0
+ local angle = math.random() * math.pi * 2
+ local ex = math.cos(angle) * 11
+ local ez = math.sin(angle) * 11
+ local ref = __rbxl_spawn_npc("character-b", ex, 1, ez, "Враг", 30, 2.2)
+ enemies[ref] = { ref = ref, alive = true, lastDmg = 0 }
+ task.delay(0.3, function()
+ __rbxl_npc_follow(ref, "player")
+ end)
+ __rbxl_npc_on_click(ref, function()
+ local ev = game:GetService("ReplicatedStorage"):FindFirstChild("EnemyClicked")
+ if ev then ev:Fire(ref) end
+ end)
+end)
+
+-- Враги бьют игрока вблизи (каждые 0.7с)
+RunService.Heartbeat:Connect(function()
+ if over then return end
+ local px = __rbxl_player_x()
+ local pz = __rbxl_player_z()
+ local now = tick()
+ 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 = px - ex
+ local dz = pz - ez
+ local dist = math.sqrt(dx*dx + dz*dz)
+ if dist < 1.8 and now - e.lastDmg > 0.7 then
+ e.lastDmg = now
+ __rbxl_damage_player(10)
+ hitSound:Play()
+ end
+ end
+ end
+ end
+end)`,
+ },
+
+ // ═══════════════════════════════════════════════════════════════
+ // ИГРЫ 46-50: явных Lua-версий пока нет.
// buildGameProject в docsGamesBuilders.js использует generateFallbackLua
// (главный скрипт → показ подсказки + слушает FinishReached →
// победа+конфетти; скрипт на финиш-примитиве → шлёт FinishReached;
diff --git a/src/community/docsLessons.jsx b/src/community/docsLessons.jsx
index fffb30a..c04cc64 100644
--- a/src/community/docsLessons.jsx
+++ b/src/community/docsLessons.jsx
@@ -6291,7 +6291,7 @@ game.self.onTouch(() => {
стрелять и проверяет, кто победил.
- {`// === ИГРА «TOWER DEFENSE» — главный скрипт ===
+ {`// === ИГРА «TOWER DEFENSE» — главный скрипт ===
let leaked = 0; // врагов прошло до базы
const MAX_LEAK = 8;
@@ -6374,7 +6374,7 @@ game.every(0.5, () => {
}
}
}
-});`}
+});`}
Разберём: