function DPad.Enable(A)DPadFrame.Visible=true end function DPad.Disable(A)DPadFrame.Visible=false OnInputEnded()end function DPad.Create(r,A)if DPadFrame then DPadFrame:Destroy()DPadFrame=nil end local t=UDim2.new(0,10,1,-230)DPadFrame=Instance.new("\070\114\097\109\101")DPadFrame.Name="\068\080\097\100\070\114\097\109\101"DPadFrame.Active=true DPadFrame.Visible=false DPadFrame.Size=UDim2.new(0,192,0,192)DPadFrame.Position=t DPadFrame.BackgroundTransparency=1 local B=UDim2.new(0,23,0,23)local h=UDim2.new(0,64,0,64)local I=Vector2.new(46,46)local G=Vector2.new(128,128)local R=createArrowLabel("\066\097\099\107\066\117\116\116\111\110",UDim2.new(.5,-32,1,-64),h,Vector2.new(0,0),G)local v=createArrowLabel("\070\111\114\119\097\114\100\066\117\116\116\111\110",UDim2.new(.5,-32,0,0),h,Vector2.new(0,258),G)local a=createArrowLabel("\076\101\102\116\066\117\116\116\111\110",UDim2.new(0,0,.5,-32),h,Vector2.new(129,129),G)local H=createArrowLabel("\082\105\103\104\116\066\117\116\116\111\110",UDim2.new(1,-64,.5,-32),h,Vector2.new(0,129),G)local V=createArrowLabel("\074\117\109\112\066\117\116\116\111\110",UDim2.new(.5,-32,.5,-32),h,Vector2.new(129,0),G)local g=createArrowLabel("\070\111\114\119\097\114\100\076\101\102\116\066\117\116\116\111\110",UDim2.new(0,35,0,35),B,Vector2.new(129,258),I)local L=createArrowLabel("\070\111\114\119\097\114\100\082\105\103\104\116\066\117\116\116\111\110",UDim2.new(1,-55,0,35),B,Vector2.new(176,258),I)g.Visible=false L.Visible=false V.InputBegan:connect(function(A)MasterControl:DoJump()end)local T=Vector3.new(0,0,0)local function l(A)local r=V.AbsoluteSize.x/2 local t=getCenterPosition()local B=Vector2.new(A.x-t.x,A.y-t.y)if B.magnitude>r then local A=ATAN2(B.y,B.x)local r=FLOOR((8*A)/(2*PI)+8.5)%8+1 T=COMPASS_DIR[r]end if not g.Visible and T==COMPASS_DIR[7]then g.Visible=true L.Visible=true end end DPadFrame.InputBegan:connect(function(A)if TouchObject or A.UserInputType~=Enum.UserInputType.Touch then return end MasterControl:AddToPlayerMovement(-T)TouchObject=A l(TouchObject.Position)MasterControl:AddToPlayerMovement(T)end)DPadFrame.InputChanged:connect(function(A)if A==TouchObject then MasterControl:AddToPlayerMovement(-T)l(TouchObject.Position)MasterControl:AddToPlayerMovement(T)end end)OnInputEnded=function()TouchObject=nil g.Visible=false L.Visible=false MasterControl:AddToPlayerMovement(-T)T=Vector3.new(0,0,0)end DPadFrame.InputEnded:connect(function(A)if A==TouchObject then OnInputEnded()end end)DPadFrame.Parent=A end return DPad
--[[ Public API ]]
--
function DPad:Enable()
	DPadFrame.Visible = true
end

function DPad:Disable()
	DPadFrame.Visible = false
	OnInputEnded()
end

function DPad:Create(parentFrame)
	if DPadFrame then
		DPadFrame:Destroy()
		DPadFrame = nil
	end

	local position = UDim2.new(0, 10, 1, -230)
	DPadFrame = Instance.new("Frame")
	DPadFrame.Name = "DPadFrame"
	DPadFrame.Active = true
	DPadFrame.Visible = false
	DPadFrame.Size = UDim2.new(0, 192, 0, 192)
	DPadFrame.Position = position
	DPadFrame.BackgroundTransparency = 1

	local smArrowSize = UDim2.new(0, 23, 0, 23)
	local lgArrowSize = UDim2.new(0, 64, 0, 64)
	local smImgOffset = Vector2.new(46, 46)
	local lgImgOffset = Vector2.new(128, 128)

	local bBtn =
		createArrowLabel("BackButton", UDim2.new(0.5, -32, 1, -64), lgArrowSize, Vector2.new(0, 0), lgImgOffset)
	local fBtn =
		createArrowLabel("ForwardButton", UDim2.new(0.5, -32, 0, 0), lgArrowSize, Vector2.new(0, 258), lgImgOffset)
	local lBtn =
		createArrowLabel("LeftButton", UDim2.new(0, 0, 0.5, -32), lgArrowSize, Vector2.new(129, 129), lgImgOffset)
	local rBtn =
		createArrowLabel("RightButton", UDim2.new(1, -64, 0.5, -32), lgArrowSize, Vector2.new(0, 129), lgImgOffset)
	local jumpBtn =
		createArrowLabel("JumpButton", UDim2.new(0.5, -32, 0.5, -32), lgArrowSize, Vector2.new(129, 0), lgImgOffset)
	local flBtn =
		createArrowLabel("ForwardLeftButton", UDim2.new(0, 35, 0, 35), smArrowSize, Vector2.new(129, 258), smImgOffset)
	local frBtn = createArrowLabel(
		"ForwardRightButton",
		UDim2.new(1, -55, 0, 35),
		smArrowSize,
		Vector2.new(176, 258),
		smImgOffset
	)
	flBtn.Visible = false
	frBtn.Visible = false

	-- input connections
	jumpBtn.InputBegan:connect(function(inputObject)
		MasterControl:DoJump()
	end)

	local movementVector = Vector3.new(0, 0, 0)
	local function normalizeDirection(inputPosition)
		local jumpRadius = jumpBtn.AbsoluteSize.x / 2
		local centerPosition = getCenterPosition()
		local direction = Vector2.new(inputPosition.x - centerPosition.x, inputPosition.y - centerPosition.y)

		if direction.magnitude > jumpRadius then
			local angle = ATAN2(direction.y, direction.x)
			local octant = (FLOOR(8 * angle / (2 * PI) + 8.5) % 8) + 1
			movementVector = COMPASS_DIR[octant]
		end

		if not flBtn.Visible and movementVector == COMPASS_DIR[7] then
			flBtn.Visible = true
			frBtn.Visible = true
		end
	end

	DPadFrame.InputBegan:connect(function(inputObject)
		if TouchObject or inputObject.UserInputType ~= Enum.UserInputType.Touch then
			return
		end

		MasterControl:AddToPlayerMovement(-movementVector)

		TouchObject = inputObject
		normalizeDirection(TouchObject.Position)

		MasterControl:AddToPlayerMovement(movementVector)
	end)

	DPadFrame.InputChanged:connect(function(inputObject)
		if inputObject == TouchObject then
			MasterControl:AddToPlayerMovement(-movementVector)
			normalizeDirection(TouchObject.Position)
			MasterControl:AddToPlayerMovement(movementVector)
		end
	end)

	OnInputEnded = function()
		TouchObject = nil
		flBtn.Visible = false
		frBtn.Visible = false

		MasterControl:AddToPlayerMovement(-movementVector)
		movementVector = Vector3.new(0, 0, 0)
	end

	DPadFrame.InputEnded:connect(function(inputObject)
		if inputObject == TouchObject then
			OnInputEnded()
		end
	end)

	DPadFrame.Parent = parentFrame
end

return DPad
