feat(g15): полный паритет «Тир» + ClickDetector в shim
JS:
- 8 мишеней-сфер на постаментах
- ui.score, showText 'Кликай по красным мишеням!'
- target: onClick → explosion particles + delete + broadcast 'hit'
- main: onMessage 'hit' → score++ + hit sound + при 8 победа+confetti
Lua-shim расширение:
- Instance.new('ClickDetector') создаёт инстанс с MouseClick signal
- Когда clickDet.Parent = part → Proxy.set регистрирует
part._clickDetector = clickDet
- fireTargetEvent при kind='click' фейерит part._clickDetector.MouseClick.Fire
Lua-скрипт игры 15:
- ScreenGui 'Мишени: N / 8'
- BindableEvent TargetHit
- 8 g15_target_N (ids 2,4,6,8,10,12,14,16): ClickDetector с
MaxActivationDistance=50 → MouseClick → spawn explosion + Destroy + Fire
- main: hit Sound, при 8 — win Sound + showText + confetti
This commit is contained in:
parent
2e1ee87ed6
commit
8abbde9d67
@ -1277,38 +1277,83 @@ end)`;
|
|||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
// ИГРА 15 — «Тир»
|
// ИГРА 15 — «Тир»
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
'shooting-range': {
|
'shooting-range': (function() {
|
||||||
g15_main: `-- === ИГРА «ТИР» (Lua) ===
|
// Мишени имеют id 2, 4, 6, 8, 10, 12, 14, 16 (постамент → нечётный, мишень → чётный)
|
||||||
local UserInputService = game:GetService("UserInputService")
|
const TARGET_IDS = [2, 4, 6, 8, 10, 12, 14, 16];
|
||||||
local Players = game:GetService("Players")
|
const TOTAL = TARGET_IDS.length;
|
||||||
|
const overrides = {
|
||||||
|
g15_main: `-- === ИГРА «ТИР» — главный скрипт (Lua) ===
|
||||||
${SNIPPET_BROADCAST}
|
${SNIPPET_BROADCAST}
|
||||||
|
|
||||||
local score = 0
|
local Players = game:GetService("Players")
|
||||||
print("Стреляй ЛКМ по красным шарам!")
|
|
||||||
|
|
||||||
local ev = getEvent("TargetHit")
|
|
||||||
ev.Event:Connect(function()
|
|
||||||
score = score + 1
|
|
||||||
print("Попал! Очки: " .. score)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- ЛКМ — пускаем луч из камеры
|
|
||||||
UserInputService.InputBegan:Connect(function(input, gp)
|
|
||||||
if gp then return end
|
|
||||||
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
|
|
||||||
local player = Players.LocalPlayer
|
local player = Players.LocalPlayer
|
||||||
local mouse = player:GetMouse()
|
local score = 0
|
||||||
local target = mouse.Target
|
local TOTAL = ${TOTAL}
|
||||||
if target and target:GetAttribute("IsTarget") then
|
local won = false
|
||||||
local hitEv = workspace:FindFirstChild("TargetHit") or ev
|
|
||||||
ev:Fire()
|
__rbxl_show_text("Кликай по красным мишеням!", 3)
|
||||||
target:Destroy()
|
|
||||||
|
-- Счётчик в правом верхнем углу
|
||||||
|
local screenGui = Instance.new("ScreenGui", player.PlayerGui)
|
||||||
|
local label = Instance.new("TextLabel", screenGui)
|
||||||
|
label.Size = UDim2.new(0, 220, 0, 50)
|
||||||
|
label.Position = UDim2.new(1, -240, 0, 20)
|
||||||
|
label.BackgroundColor3 = Color3.fromRGB(0, 0, 0)
|
||||||
|
label.BackgroundTransparency = 0.4
|
||||||
|
label.TextColor3 = Color3.fromRGB(255, 100, 100)
|
||||||
|
label.TextScaled = true
|
||||||
|
label.Font = Enum.Font.SourceSansBold
|
||||||
|
label.Text = "Мишени: 0 / " .. TOTAL
|
||||||
|
|
||||||
|
local hitSound = Instance.new("Sound", workspace)
|
||||||
|
hitSound.SoundId = "hit"; hitSound.Volume = 0.7
|
||||||
|
local winSound = Instance.new("Sound", workspace)
|
||||||
|
winSound.SoundId = "win"; winSound.Volume = 1
|
||||||
|
|
||||||
|
local hitEvent = getEvent("TargetHit")
|
||||||
|
hitEvent.Event:Connect(function()
|
||||||
|
if won then return end
|
||||||
|
score = score + 1
|
||||||
|
label.Text = "Мишени: " .. score .. " / " .. TOTAL
|
||||||
|
hitSound:Play()
|
||||||
|
if score >= TOTAL then
|
||||||
|
won = true
|
||||||
|
winSound:Play()
|
||||||
|
__rbxl_show_text("Победа! Все мишени выбиты!", 5)
|
||||||
|
local px = __rbxl_player_x()
|
||||||
|
local py = __rbxl_player_y()
|
||||||
|
local pz = __rbxl_player_z()
|
||||||
|
__rbxl_spawn_particles("confetti", px, py + 3, pz, 3, 3)
|
||||||
end
|
end
|
||||||
end)`,
|
end)`,
|
||||||
g15_target: `-- === Скрипт мишени (Lua) ===
|
};
|
||||||
|
// Скрипт каждой мишени — ClickDetector + взрыв искр + сообщение
|
||||||
|
const targetScript = `-- === Скрипт мишени (Lua) ===
|
||||||
|
-- Клик ЛКМ по мишени = выстрел. ClickDetector ловит клик в 3D.
|
||||||
|
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||||||
local part = script.Parent
|
local part = script.Parent
|
||||||
part:SetAttribute("IsTarget", true)`,
|
local hit = false
|
||||||
},
|
|
||||||
|
local clickDet = Instance.new("ClickDetector", part)
|
||||||
|
clickDet.MaxActivationDistance = 50
|
||||||
|
|
||||||
|
clickDet.MouseClick:Connect(function()
|
||||||
|
if hit then return end
|
||||||
|
hit = true
|
||||||
|
-- Взрыв искр на месте мишени
|
||||||
|
local pos = part.Position
|
||||||
|
__rbxl_spawn_particles("explosion", pos.X, pos.Y, pos.Z, 0.5, 1)
|
||||||
|
-- Сообщаем главному скрипту
|
||||||
|
local ev = ReplicatedStorage:FindFirstChild("TargetHit")
|
||||||
|
if ev then ev:Fire() end
|
||||||
|
-- Мишень исчезает
|
||||||
|
part:Destroy()
|
||||||
|
end)`;
|
||||||
|
for (const tid of TARGET_IDS) {
|
||||||
|
overrides['g15_target_' + tid] = targetScript;
|
||||||
|
}
|
||||||
|
return overrides;
|
||||||
|
})(),
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════
|
||||||
// ИГРА 16 — «Лавовый пол»
|
// ИГРА 16 — «Лавовый пол»
|
||||||
|
|||||||
@ -436,6 +436,11 @@ function newInstance(className, name) {
|
|||||||
value.Children.push(proxyRef);
|
value.Children.push(proxyRef);
|
||||||
try { value.ChildAdded && value.ChildAdded.Fire(proxyRef); } catch (_) {}
|
try { value.ChildAdded && value.ChildAdded.Fire(proxyRef); } catch (_) {}
|
||||||
}
|
}
|
||||||
|
// Спец-регистрация для ClickDetector — чтобы клик по Part
|
||||||
|
// мог сфейерить MouseClick через fireTargetEvent.
|
||||||
|
if (t.ClassName === 'ClickDetector' && value) {
|
||||||
|
try { value._clickDetector = proxyRef; } catch (_) {}
|
||||||
|
}
|
||||||
try { t.AncestryChanged && t.AncestryChanged.Fire(proxyRef, value); } catch (_) {}
|
try { t.AncestryChanged && t.AncestryChanged.Fire(proxyRef, value); } catch (_) {}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1387,6 +1392,15 @@ export function registerRobloxShim(lua, opts) {
|
|||||||
inst.Scale = new RbxVector3(1, 1, 1);
|
inst.Scale = new RbxVector3(1, 1, 1);
|
||||||
inst.Offset = new RbxVector3(0, 0, 0);
|
inst.Offset = new RbxVector3(0, 0, 0);
|
||||||
inst.VertexColor = new RbxVector3(1, 1, 1);
|
inst.VertexColor = new RbxVector3(1, 1, 1);
|
||||||
|
} else if (className === 'ClickDetector') {
|
||||||
|
// ClickDetector — клик по 3D-объекту (нужен Тиру и т.п.).
|
||||||
|
// Регистрация в part._clickDetector происходит автоматически
|
||||||
|
// через Proxy.set когда юзер делает clickDet.Parent = part.
|
||||||
|
inst = newInstance('ClickDetector', 'ClickDetector');
|
||||||
|
inst.MouseClick = makeSignal();
|
||||||
|
inst.MouseHoverEnter = makeSignal();
|
||||||
|
inst.MouseHoverLeave = makeSignal();
|
||||||
|
inst.MaxActivationDistance = 32;
|
||||||
} else if (className === 'BindableEvent') {
|
} else if (className === 'BindableEvent') {
|
||||||
inst = newInstance('BindableEvent', 'BindableEvent');
|
inst = newInstance('BindableEvent', 'BindableEvent');
|
||||||
inst.Event = makeSignal();
|
inst.Event = makeSignal();
|
||||||
@ -2164,6 +2178,18 @@ export function registerRobloxShim(lua, opts) {
|
|||||||
part.Touched.Fire(hrp);
|
part.Touched.Fire(hrp);
|
||||||
} else if (p.kind === 'untouch' || p.kind === 'untouched') {
|
} else if (p.kind === 'untouch' || p.kind === 'untouched') {
|
||||||
part.TouchEnded.Fire(hrp);
|
part.TouchEnded.Fire(hrp);
|
||||||
|
} else if (p.kind === 'click') {
|
||||||
|
// ClickDetector создаётся лениво — стрельба по 3D-объектам.
|
||||||
|
// Юзер делает: part.ClickDetector = Instance.new('ClickDetector', part)
|
||||||
|
// + clickDet.MouseClick:Connect(fn). Здесь фейерим сигнал.
|
||||||
|
try {
|
||||||
|
const cd = part._clickDetector;
|
||||||
|
if (cd && cd.MouseClick) cd.MouseClick.Fire(localPlayer);
|
||||||
|
} catch (_) {}
|
||||||
|
// Также фейерим Part.Clicked если есть (наш расширенный API).
|
||||||
|
try {
|
||||||
|
if (part.Clicked) part.Clicked.Fire();
|
||||||
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fireGlobalEvent(p) {
|
fireGlobalEvent(p) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user