Lua Script Vault

Store. Inspect. Ship.

A cleaner interface for managing personal Lua scripts, editing code from mobile, and downloading ready-to-run files.

Puck controller

Позволяет управлять шайбой

Author: darknifus339
local menuGroup = display.newGroup()
menuGroup.isVisible = false
local active = {pc = false}
local puck = nil
local joystick = nil
local pSpeed = 500 

local function findPuck(obj)
    if not obj then return nil end
    if obj.x and (string.find(tostring(obj.name or ""), "puck") or (obj.fill and string.find(tostring(obj.fill), "puck"))) then
        return obj
    end
    if obj.numChildren then
        for i = 1, obj.numChildren do
            local f = findPuck(obj[i])
            if f then return f end
        end
    end
    return nil
end

local function applyControl(dx, dy)
    if puck and not puck.x then puck = nil end
    local p = puck or findPuck(display.currentStage)
    if p and p.x then
        puck = p
        if p.setLinearVelocity then
            p:setLinearVelocity(dx * pSpeed, dy * pSpeed)
        else
            p.x, p.y = p.x + dx * (pSpeed/20), p.y + dy * (pSpeed/20)
        end
    end
end

local function createJoystick()
    if joystick then joystick:removeSelf(); joystick = nil end
    joystick = display.newGroup()
    local ring = display.newCircle(joystick, 100, display.contentHeight - 100, 60)
    ring:setFillColor(0,0,0,0.2); ring.strokeWidth = 3; ring:setStrokeColor(1,1,1,0.5)
    local dot = display.newCircle(joystick, ring.x, ring.y, 25)
    dot:setFillColor(0, 0.6, 1, 0.8)
    dot:addEventListener("touch", function(e)
        if e.phase == "began" then display.currentStage:setFocus(e.target)
        elseif e.phase == "moved" then
            local dx, dy = e.x - ring.x, e.y - ring.y
            local dist = math.sqrt(dx*dx + dy*dy)
            local limit = 50
            if dist > limit then dx, dy = dx * limit / dist, dy * limit / dist end
            dot.x, dot.y = ring.x + dx, ring.y + dy
            applyControl(dx/limit, dy/limit)
        elseif e.phase == "ended" or e.phase == "cancelled" then
            display.currentStage:setFocus(nil)
            transition.to(dot, {x = ring.x, y = ring.y, time = 100})
        end
        return true
    end)
    joystick.isVisible = active.pc
end

-- Параметры меню
local mWidth = 350
local mHeight = 250
local padding = 20

local bg = display.newRoundedRect(menuGroup, display.contentCenterX, display.contentCenterY, mWidth, mHeight, 20)
bg:setFillColor(0,0,0,0.95); bg.strokeWidth = 2; bg:setStrokeColor(0,0.5,1)

-- Функция для создания строк меню
local function createRow(label, y)
    local row = display.newGroup(); menuGroup:insert(row)
    
    -- Текст СЛЕВА
    local txt = display.newText(row, label, bg.x - mWidth/2 + padding, y, native.systemFont, 18)
    txt.anchorX = 0
    
    -- Переключатель СПРАВА
    local track = display.newRoundedRect(row, bg.x + mWidth/2 - padding - 25, y, 50, 24, 12)
    track:setFillColor(0.2)
    local thumb = display.newCircle(row, track.x - 15, y, 9); thumb:setFillColor(0.8)
    
    row:addEventListener("tap", function()
        active.pc = not active.pc
        transition.to(thumb, {x = active.pc and (track.x + 15) or (track.x - 15), time=150})
        transition.to(track, {fillColor = active.pc and {0,0.5,1} or {0.2,0.2,0.2}, time=150})
        if joystick then joystick.isVisible = active.pc else createJoystick() end
        return true
    end)
end

-- Блок регулировки скорости
local function createSpeedControl(y)
    local g = display.newGroup(); menuGroup:insert(g)
    
    local txt = display.newText(g, "STICK SPEED", bg.x - mWidth/2 + padding, y, native.systemFont, 18)
    txt.anchorX = 0
    
    local valTxt = display.newText(g, pSpeed, bg.x + mWidth/2 - padding - 65, y, native.systemFontBold, 18)
    valTxt.anchorX = 0.5
    
    local function sBtn(t, x, d)
        local b = display.newRoundedRect(g, x, y, 35, 30, 8); b:setFillColor(0.2, 0.2, 0.3)
        display.newText(g, t, b.x, b.y, native.systemFontBold, 20)
        b:addEventListener("tap", function()
            pSpeed = math.max(100, pSpeed + d)
            valTxt.text = pSpeed
            return true
        end)
    end
    
    sBtn("-", bg.x + mWidth/2 - padding - 110, -50)
    sBtn("+", bg.x + mWidth/2 - padding - 20, 50)
end

-- Наполнение
createRow("PUCK STICK CONTROL", bg.y - 40)
createSpeedControl(bg.y + 20)

-- Перетаскивание всего меню за фон
bg:addEventListener("touch", function(e)
    if e.phase == "began" then 
        display.currentStage:setFocus(e.target)
        e.target.ox = e.x - menuGroup.x
        e.target.oy = e.y - menuGroup.y
    elseif e.phase == "moved" then 
        menuGroup.x = e.x - e.target.ox
        menuGroup.y = e.y - e.target.oy
    elseif e.phase == "ended" then 
        display.currentStage:setFocus(nil)
    end
    return true
end)

-- Маленькая кнопка MOD
local mBtn = display.newGroup()
local mI = display.newCircle(mBtn, 60, 60, 30); mI:setFillColor(0,0,0,0.8); mI.strokeWidth=2; mI:setStrokeColor(0,0.6,1)
display.newText(mBtn, "M", 60, 60, native.systemFontBold, 24)

mBtn:addEventListener("touch", function(e)
    if e.phase == "began" then display.currentStage:setFocus(e.target); e.target.ox=e.x-e.target.x; e.target.oy=e.y-e.target.y
    elseif e.phase == "moved" then e.target.x=e.x-e.target.ox; e.target.y=e.y-e.target.oy
    elseif e.phase == "ended" then display.currentStage:setFocus(nil) end
    return true
end)
mI:addEventListener("tap", function() menuGroup.isVisible = not menuGroup.isVisible end)

Info

ID: 8
Created: 2026-04-04 21:31:06
Updated: 2026-04-04 21:31:06