"Framing Frame" Coding Challenge

Hi! I’m a bit new to programming (and game design as a whole) and I have something for a game I’m working on that I have no idea how to approach. What I’m trying to achieve is a program that, when given several frames of random size and position, can create a parent frame that encapsulates all of them.

I’m not completely sure the best way to describe this problem so I’ll give a picture here.

As you can see by this terribly scuffed beautiful diagram I have a series of random frames, and I’m trying to create a parent frame that has a 10 pixel padding around them all. Ideally, this system could also update itself when a new frame is added or removed, or an existing frame moves or changes its’ dimensions.

Honestly, I really have no idea how to approach this problem. My first intuition is to get the size and position of a random frame, create the parent frame, and then compare the dimensions and the positions of all the other frames and do some equations to find the proper size of the parent frame. But even laying it out like that, I still am clueless where to start. Does anyone have any ideas? Thank you!

Loop through all frames you wish to encompass with a larger frame and:

  1. Use GuiBase2d.AbsolutePosition to get the centerpoint of each frame and find where they begin and end by adding/subtracting the X and Y size divided by 2 to the centerpoint.

  2. Store and replace the maximum and minimum values for X and Y locations.

Finally, Create your new frame at the position in the middle of these values, with the size of the distance between these values, plus whatever padding you want.

I figured it out, here’s the code

you MUST set the anchor point of Encompass frame to 0.5,0.5 otherwise it will not work

local Container = script.Parent.Container
local Encompass = script.Parent.Encompass

local padding = 0.025

local function positionTo()

	local topLeftX = 1
	local topLeftY = 1

	local topRightX = 0
	local topRightY = 1 

	local bottomLeftX = 1
	local bottomLeftY = 0

	local bottomRightX = 0
	local bottomRightY = 0

	for i, Frame : Frame in pairs(Container:GetChildren()) do
		local position = Frame.AbsolutePosition
		local size = Frame.AbsoluteSize 

		---------------------------------------------------------------
		local currentTopLeftX = position.x / Container.AbsoluteSize.X
		local currentTopLeftY = position.y / Container.AbsoluteSize.Y

		if currentTopLeftX < topLeftX then
			topLeftX = currentTopLeftX
		end

		if currentTopLeftY < topLeftY then
			topLeftY = currentTopLeftY
		end
		----------------------------------------------------------------
		local currentTopRightX = (position.X + size.X) / Container.AbsoluteSize.X
		local currentTopRightY = position.y / Container.AbsoluteSize.Y


		if currentTopRightX > topRightX then
			topRightX = currentTopRightX
		end

		if currentTopRightY < topRightY then
			topRightY = currentTopRightY
		end
		----------------------------------------------------------------
		local currentBottomLeftX = position.x / Container.AbsoluteSize.X
		local currentBottomLeftY = (position.Y + size.Y) / Container.AbsoluteSize.Y

		if currentBottomLeftX < bottomLeftX then
			bottomLeftX = currentBottomLeftX
		end

		if currentBottomLeftY > bottomLeftY then
			bottomLeftY = currentBottomLeftY
		end
		-----------------------------------------------------------------
		local currentBottomRightX = (position.X + size.X) / Container.AbsoluteSize.X
		local currentBottomRightY = (position.Y + size.Y) / Container.AbsoluteSize.Y

		if currentBottomRightX > bottomRightX then
			bottomRightX = currentBottomRightX
		end

		if currentBottomRightY > bottomRightY then
			bottomRightY = currentBottomRightY
		end
	end

	--[[local clonedEncompassTopLeft = Encompass:Clone()
	clonedEncompassTopLeft.Parent = Container 
	clonedEncompassTopLeft.Position = UDim2.new(topLeftX - padding , 0, topLeftY - padding, 0)

	local clonedEncompassTopRight = Encompass:Clone()
	clonedEncompassTopRight.Parent = Container 
	clonedEncompassTopRight.Position = UDim2.new(topRightX + padding, 0, topRightY - padding, 0)

	local clonedEncompassBottomLeft = Encompass:Clone()
	clonedEncompassBottomLeft.Parent = Container 
	clonedEncompassBottomLeft.Position = UDim2.new(bottomLeftX - padding, 0, bottomLeftY + padding, 0)

	local clonedEncompassBottomRight = Encompass:Clone()
	clonedEncompassBottomRight.Parent = Container 
	clonedEncompassBottomRight.Position = UDim2.new(bottomRightX + padding, 0, bottomRightY + padding, 0)
	--]]
	local centerX = (topLeftX + topRightX + bottomLeftX + bottomRightX) / 4
	local centerY = (topLeftY + topRightY + bottomLeftY + bottomRightY) / 4

	local centrePart = Encompass:Clone()
	centrePart.Parent = Container
	centrePart.Position = UDim2.new(centerX, 0, centerY, 0)
	
	local width = bottomRightX - bottomLeftX
	local height = topLeftY- bottomLeftY

	centrePart.Size = UDim2.new(width + padding , 0, height - padding, 0)
	
	print(centrePart.Size)
end

task.wait(1)

local corners = positionTo(Container.Test)

Here is the UI layout:

image

and heres a few examples:


also they can overlap it wont break anything

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.