feat: 50 игр на Lua + импорт Roblox для всех + поддержка Lua в плеере #39
@ -510,22 +510,24 @@ coinSound.SoundId = "coin"; coinSound.Volume = 1
|
|||||||
local winSound = Instance.new("Sound", workspace)
|
local winSound = Instance.new("Sound", workspace)
|
||||||
winSound.SoundId = "win"; winSound.Volume = 1
|
winSound.SoundId = "win"; winSound.Volume = 1
|
||||||
|
|
||||||
-- Каждые 1.5 сек роняем куб
|
-- Каждые 1.5 сек роняем куб (через Heartbeat — task.spawn не умеет yield)
|
||||||
task.spawn(function()
|
local RunService = game:GetService("RunService")
|
||||||
while not won do
|
local _spawnTimer = 0
|
||||||
task.wait(1.5)
|
|
||||||
if won then break end
|
|
||||||
local cube = Instance.new("Part", workspace)
|
|
||||||
cube.Size = Vector3.new(0.8, 0.8, 0.8)
|
|
||||||
cube.Position = Vector3.new(math.random(-6, 6), 14, math.random(-6, 6))
|
|
||||||
cube.Color = Color3.fromRGB(255, 204, 51)
|
|
||||||
cube.Material = Enum.Material.Neon
|
|
||||||
cube.Anchored = false -- падает под действием гравитации
|
|
||||||
|
|
||||||
-- Куб исчезает через 6с если не поймали
|
local function spawnCube()
|
||||||
|
-- Используем хелпер __rbxl_spawn_part — он сразу создаёт примитив
|
||||||
|
-- с правильными свойствами (включая anchored=false → реальная гравитация).
|
||||||
|
local cube = __rbxl_spawn_part({
|
||||||
|
type = "cube",
|
||||||
|
x = math.random(-6, 6), y = 14, z = math.random(-6, 6),
|
||||||
|
sx = 0.8, sy = 0.8, sz = 0.8,
|
||||||
|
color = "#ffcc33",
|
||||||
|
anchored = false, -- падает
|
||||||
|
canCollide = true,
|
||||||
|
})
|
||||||
|
if not cube then return end
|
||||||
Debris:AddItem(cube, 6)
|
Debris:AddItem(cube, 6)
|
||||||
|
|
||||||
-- Ловля: при касании игроком +1 очко
|
|
||||||
local caught = false
|
local caught = false
|
||||||
cube.Touched:Connect(function(hit)
|
cube.Touched:Connect(function(hit)
|
||||||
if caught or won then return end
|
if caught or won then return end
|
||||||
@ -547,6 +549,14 @@ task.spawn(function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RunService.Heartbeat:Connect(function(dt)
|
||||||
|
if won then return end
|
||||||
|
_spawnTimer = _spawnTimer + (dt or 0.016)
|
||||||
|
if _spawnTimer >= 1.5 then
|
||||||
|
_spawnTimer = 0
|
||||||
|
spawnCube()
|
||||||
|
end
|
||||||
end)`,
|
end)`,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -1826,6 +1826,41 @@ export function registerRobloxShim(lua, opts) {
|
|||||||
count: Number(count) || 1,
|
count: Number(count) || 1,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// Спавн примитива (паритет с JS game.scene.spawn) — кладёт в сцену
|
||||||
|
// примитив с указанным состоянием (включая anchored/canCollide). Возвращает
|
||||||
|
// id примитива (число) для дальнейших операций.
|
||||||
|
let _nextSpawnedId = 800000 + Math.floor(Math.random() * 10000);
|
||||||
|
global.set('__rbxl_spawn_part', (opts) => {
|
||||||
|
try {
|
||||||
|
const id = _nextSpawnedId++;
|
||||||
|
const o = opts || {};
|
||||||
|
send('sceneCreate', {
|
||||||
|
primId: id,
|
||||||
|
type: String(o.type || 'cube'),
|
||||||
|
x: +o.x || 0, y: +o.y || 0, z: +o.z || 0,
|
||||||
|
sx: +o.sx || 1, sy: +o.sy || 1, sz: +o.sz || 1,
|
||||||
|
color: o.color || '#A0A0A0',
|
||||||
|
anchored: o.anchored !== false,
|
||||||
|
canCollide: o.canCollide !== false,
|
||||||
|
});
|
||||||
|
// Создаём Lua-side представление для скриптов
|
||||||
|
const fakePrim = {
|
||||||
|
id, name: o.name || `Spawned_${id}`,
|
||||||
|
x: +o.x || 0, y: +o.y || 0, z: +o.z || 0,
|
||||||
|
sx: +o.sx || 1, sy: +o.sy || 1, sz: +o.sz || 1,
|
||||||
|
color: o.color || '#A0A0A0',
|
||||||
|
anchored: o.anchored !== false,
|
||||||
|
canCollide: o.canCollide !== false,
|
||||||
|
};
|
||||||
|
const part = newPart(fakePrim, send);
|
||||||
|
partById.set(id, part);
|
||||||
|
return part;
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn('[__rbxl_spawn_part]', e?.message || e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
// Позиция игрока для удобства — отдельные функции для x/y/z, чтобы
|
// Позиция игрока для удобства — отдельные функции для x/y/z, чтобы
|
||||||
// wasmoon не оборачивал результат в userdata-proxy.
|
// wasmoon не оборачивал результат в userdata-proxy.
|
||||||
global.set('__rbxl_player_x', () => {
|
global.set('__rbxl_player_x', () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user