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)