Need help with physics engine using GUI

ive been trying to work on this for hours and i cant get it right, theres many issues with it.
Heres a video of its current state:

The current issues are:

No momentum, so nothing can be flung.
Collisions only seem to consistently work with squares.
I can only have 2 elements: 1 collider, one faller.

Current code:



function areFramesOverlapping(Frame1,Frame2)
	-- X axis overlap detection
	local F1posX,F2posX = Frame1.AbsolutePosition.X,Frame2.AbsolutePosition.X
	local F1sizeX,F2sizeX = Frame2.AbsoluteSize.X,Frame2.AbsoluteSize.X

	local Xdistance = math.abs(F1posX-F2posX) -- distance (in px) between frames
	local minXdistance = math.abs(F1sizeX+F2sizeX/100)-- min distance w/o overlap

	-- Y axis overlap detection
	local F1posY,F2posY = Frame1.AbsolutePosition.Y,Frame2.AbsolutePosition.Y
	local F1sizeY,F2sizeY = Frame2.AbsoluteSize.Y,Frame2.AbsoluteSize.Y

	local Ydistance = math.abs(F1posY-F2posY) -- distance (in px) between frames
	local minYdistance = math.abs(F1sizeY+F2sizeY/100)-- min distance w/o overlap
	
	local DataTable = {
		YDist = 0,
		YDistAbs = 0,
		XDist = 0,
		XDistAbs = 0,
		Closest = "",
		Inside = true
	}
	
	DataTable.YDistAbs = Ydistance
	DataTable.YDist = F1posY-F2posY
	
	DataTable.XDistAbs = Xdistance
	DataTable.XDist = F1posX-F2posX
	
	if Ydistance > Xdistance then
		DataTable.Closest = "Y"
		if Ydistance ~= DataTable.YDist then
			DataTable.Closest = DataTable.Closest.."-"
		end
	else
		DataTable.Closest = "X"
		if Xdistance ~= DataTable.XDist then
			DataTable.Closest = DataTable.Closest.."-"
		end
	end
	
	print(Xdistance, Ydistance)
	if Xdistance > 100 or Ydistance > 100 then
		DataTable.Inside = false
	end
	
	

	if Ydistance < minYdistance and Xdistance < minXdistance then return DataTable end -- OVERLAP!!
	
	return false -- no overlap detected
end

task.wait(2)

while true do
	local C1 = script.Parent.Frame1
	local C2 = script.Parent.Frame2
	
	local Run = areFramesOverlapping(C1, C2)
	
	if Run == false then
		if C1.Falling.Value == false then
			C1.Falling.Value = true
			task.spawn(function()
				local Mult = 0.001
				while C1.Falling.Value == true do
					script.Parent.Frame1.Position = UDim2.new(script.Parent.Frame1.Position.X.Scale, script.Parent.Frame1.Position.X.Offset, script.Parent.Frame1.Position.Y.Scale+Mult, script.Parent.Frame1.Position.Y.Offset)
					Mult += Mult/35
					task.wait()
				end
			end)
			C1.BottomHit.Visible = false
			C1.TopHit.Visible = false
			C1.LeftHit.Visible = false
			C1.RightHit.Visible = false
		end
	else
		print(Run["Closest"])
		print(Run["Inside"])
		
		if Run["Closest"] == "Y-" then
			C1.Falling.Value = false
			C1.BottomHit.Visible = true
			if Run["Inside"] == true then
				script.Parent.Frame1.Position = UDim2.new(script.Parent.Frame1.Position.X.Scale, script.Parent.Frame1.Position.X.Offset, script.Parent.Frame1.Position.Y.Scale-0.01, script.Parent.Frame1.Position.Y.Offset)
			end
		elseif Run["Closest"] == "Y" then
			C1.TopHit.Visible = true
			if Run["Inside"] == true then
				script.Parent.Frame1.Position = UDim2.new(script.Parent.Frame1.Position.X.Scale, script.Parent.Frame1.Position.X.Offset, script.Parent.Frame1.Position.Y.Scale+0.01, script.Parent.Frame1.Position.Y.Offset)
			end
		elseif Run["Closest"] == "X" then
			C1.LeftHit.Visible = true
			if Run["Inside"] == true then
				script.Parent.Frame1.Position = UDim2.new(script.Parent.Frame1.Position.X.Scale+0.01, script.Parent.Frame1.Position.X.Offset, script.Parent.Frame1.Position.Y.Scale, script.Parent.Frame1.Position.Y.Offset)
			end
		elseif Run["Closest"] == "X-" then
			C1.RightHit.Visible = true
			if Run["Inside"] == true then
				script.Parent.Frame1.Position = UDim2.new(script.Parent.Frame1.Position.X.Scale-0.01, script.Parent.Frame1.Position.X.Offset, script.Parent.Frame1.Position.Y.Scale, script.Parent.Frame1.Position.Y.Offset)
			end
		end
	end
	task.wait()
end

Sorry if it looks bad, ive never made a physics engine.