Finding a position in any given enclosed area

Hello. Currently I am working on a Paper.io game, and the problem I have currently is this:

How would I find a position in these areas? I need a formula that works for all areas, which unfortunately I currently have no idea how to do.

For further clarification, I need to get a position in these areas to put a part into.


(Red dots are positions I need to find because I will put a part in that position. but it has to be enclosed in the area)

Thanks for all help!

1 Like

I am not really experienced with a game like this, but I thought of a simple algorithm that could help you achieve your goal. I am not sure that it’s the best way though.

Alright, so imagine you have this and you want to get the “insides”
image

What I thought of is that you are going to go through each row and check the farthest left and farthest right positions (marked red below). I assigned a number to each row.
image

So now we are simply going through each row and see if there are any empty parts between them.

So let’s go through the first row.

We can see there are 2 parts between the red parts, these are part of the border. Whether you want to include this in your “empty parts” collection, it’s up to you, but I am going to assume you do want this. We will be coloring every “empty part” green.

Now we have this. We can repeat this for the next row and we will get all our empty spaces.
image
image

Problem with this is that it will not work with shapes like this, because it would also get the spaces outside of the shape (marked dark green)
image
image

So perhaps you want to go for a different approach that will get the red parts like so
image

But I wouldn’t be sure how to do that.

I am just giving you ideas cause I am not certain on how to achieve this in the best way possible.

1 Like

Wow, this looks very promising! And I do believe it might work, as I only need 1 position in the area.

do you just need a random position in that area?

1 Like

yeah thats what I need. charsssss

Here’s an idea. Run a “tracker” through across each layer. I’m using a sort of grid system here with tiles of 4 and I hope you are using the same or I don’t think this works. I keep track whether I’m in an empty zone or not.
To calculate a random position from these parts you’d do something alone the lines of:

  • Pick random tile in possible tiles
  • Pick random position from within the tile
External Media
local currentTile
local parts = workspace.Parts
local touchTable = {false,false} -- {previousPart, currentPart}
local emptyLines = 1
local possibleTiles = 0
local top = -1000

for i,v in parts:GetChildren() do
	if v.Position.X > top then
		top = v.Position.X
	end
end

local bottom = 1000
for i,v in parts:GetChildren() do
	if v.Position.X < bottom then
		bottom = v.Position.X
	end
end

local left = 1000

for i,v in parts:GetChildren() do
	if v.Position.Z < left then
		left = v.Position.Z
	end
end

local right = -1000

for i,v in parts:GetChildren() do
	if v.Position.Z > right then
		right = v.Position.Z
	end
end

local function newPart(pos)
	local newPart = Instance.new("Part")
	newPart.Anchored = true
	newPart.Size = Vector3.new(4,0.25,4)
	newPart.Position = pos
	newPart.Parent = workspace
	if newPart:GetTouchingParts()[1] ~= nil then 
		touchTable[2] = true
	else
		touchTable[2] = false
	end
	currentTile = newPart
end

for i = top-4,bottom+4,-4 do
	emptyLines = 1
	for i2 = left-8,right+8,4 do
		touchTable[1] = touchTable[2]
		newPart(Vector3.new(i,0.25,i2))
		if not touchTable[2] and touchTable[1] then
			emptyLines += 1
		end
		if not touchTable[2] and emptyLines % 2 == 0 then
			possibleTiles += 1
			print(possibleTiles)
			currentTile.Color = Color3.fromRGB(28, 12, 255)
		end
		wait()
	end
end

print(possibleTiles)
1 Like

I think Azartics idea is easiest and most simple. I think making a pre-made grid of parts in your areas and doing his code is best.

heres a code sample I made from his code which can get a random position inside one of the areas in your pic

local tilesfolder = workspace.TilesSection1

local tiles = tilesfolder:GetChildren()

function getrandompos()
	local randomtile = tiles[math.random(1, #tiles)]

	local newsize = randomtile.Size/2
	local randomX = math.random(-newsize.X, newsize.X)
	local randomZ = math.random(-newsize.Z,newsize.Z)

	local randomPos = Vector3.new(randomX, 0, randomZ)

	local finalrandomposition = randomtile.Position+randomPos
	
	return finalrandomposition
end
1 Like

Wow! This looks like it could work, but I’m unsure what you mean by grid system?

Well it looks like the parts in the pictures you sent at 2x2x2 cubes. In the actual game, do the players take over (invisible) tiles, (“grid system”), or do the players have complete free realm of which areas they can occupy. ie. how does your game work for taking over areas?

My game is basically Paperio, so players have complete free realm of areas they occupy.

Ouch, this just made everything really complicated. Here’s an idea
First consider the point the player leaves to the points the player arrives
You’d then need to calculate whether the player has travelled in a clockwise, or
anti-clockwise direction
From here can pick any random point on the line the user has generated, and pick a
random point along this line. (I don’t know how your system works, so I’m not sure how hard
all of this is to implement)
With your random point chosen, you can then fire a raycast to the normal of the direction of the line
If the player travelled clockwise you can fire the raycast to the right of the normal, and for anti-clockwise fire the raycast to the left on the normal.
Here’s an example with clockwise rotatation by the player, with some possible raycasts shown
In reality the raycast could be created anywhere along the line
With the raycast fired, it would stop when it meets the point on the same line generated by the user.

To pick a random point on the raycast, and thus the whole playing area, you can do some vector math

This might look something like this on the example from earlier

Will this work? No clue lol, it’s pretty complicated
There are a lot of random shapes the player can create, so it’s hard to visualize
I guess if the raycast returns nil on the touch you could generate a new random raycast until you get a hit