I am currently working on a 2D Game and the basics of it: Physics is what I am concentrated on.
I have done quite well but I’m stuck on a Hitboxing method to detect collisions. This is my work so far:
local Servces =
{
RunService = game:GetService('RunService'),
Plrs = game:GetService('Players')
}
type PhysicInfo =
{
Size: Vector2,
Pos: Vector2,
Tag: string,
Name: string,
Anchored: boolean,
Vel: Vector2
}
local ProcessedPhysics:{[string]:PhysicInfo} = {}
ProcessedPhysics['Ground'] =
{
Size = Vector2.new(99999,.2),
Pos= Vector2.new(-9999,.8),
Tag = 'SolidPart',
Name = 'Ground',
Anchored = true,
Vel = Vector2.new(0,0)
}
local function PHB()
local HitBoxes = {}
for Name, Props in pairs(ProcessedPhysics) do
table.insert(HitBoxes,Props.Pos.X+(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2))
table.insert(HitBoxes,Props.Pos.X+(Props.Size.X/2)-Props.Pos.Y+(Props.Size.Y/2))
table.insert(HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2))
table.insert(HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y-(Props.Size.Y/2))
end
return HitBoxes
end
function RunSim()
end
It seems like you’re currently only supporting axis-aligned boxes (sometimes referred to as AABB) as you do not have a rotation variable in your type (nice using luau!)
AABB rectangular collision is easy to check for and in a physics engine context a little more to check for intersection and/or a resulting “push back”. You’ll find plenty more helpful articles on “AABB 2d collision” through google but the basic idea is
type Rectangle = {
x: number,
y: number,
width: number,
height: number,
}
local function collides(rect1: Rectangle, rect2: Rectangle): boolean
if rect1.x + rect1.width < rect2.x then
return false
elseif rect1.x > rect2.x + rect2.width then
return false
elseif rect1.y + rect1.height < rect2.y then
return false
elseif rect1.y > rect2.y + rect2.height then
return false
else
return true
end
end
Here’s a simple 2D collision detection though it doesn’t provide an intersection, which is useful for physics engines to resolve collisions usually by pushing objects away from another.
If you do add rotation then you’ll need to look into the Separating Axis Theorem which also works for any convex polygon! Either way you’re in for a fair amount of work and my recommendation is use as many circles as possible as circles are very easy to do collision detection or start programming outside of roblox for greater control and better performance.
Thanks! And yeah I will add a rotation value as a number value, but I will keep the positions and sizes as Vector2s as they should be more space effiecent as I don’t need the offset value anyways.
local function PHB()
local HitBoxes = {}
for Name, Props in pairs(ProcessedPhysics) do
for i, v in pairs(HitBoxes) do
local cHB =
{
HitBoxes,Props.Pos.X+(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2), -- top right
HitBoxes,Props.Pos.X+(Props.Size.X/2)-Props.Pos.Y+(Props.Size.Y/2), -- bottom right
HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2), -- bottom left
HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y-(Props.Size.Y/2) -- bottom right
}
if cHB[1] > v[1] and cHB[2] > v[2] and cHB[3] > v[3] and cHB[4] > v[4] then
Props.Vel = Vector2.new(0,0)
end
end
table.insert(HitBoxes,
{
HitBoxes,Props.Pos.X+(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2),
HitBoxes,Props.Pos.X+(Props.Size.X/2)-Props.Pos.Y+(Props.Size.Y/2),
HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2),
HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y-(Props.Size.Y/2)
})
end
Here is an update! Haven’t tested it yet but the math should be correct.
local cHB = {
HitBoxes,Props.Pos.X+(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2), -- top right
HitBoxes,Props.Pos.X+(Props.Size.X/2)+Props.Pos.Y-(Props.Size.Y/2), -- bottom right
HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y+(Props.Size.Y/2), -- top left
HitBoxes,Props.Pos.X-(Props.Size.X/2)+Props.Pos.Y-(Props.Size.Y/2) -- bottom left
}
I think this is more correct, including the comments. you don’t want to subtract by position -Props.Pos.Y shouldn’t come up when converting to rectangles. It also might help to add --!strict to the top of your scripts with large math and tables and look into the luau type checking system, this doesn’t affect your scripts just tries to make sure you’re using the right values and provides better auto-complete.