2D Battle System?

I’m currently creating a 2D Battle system for a single-player game.

I am not sure what the most effective way of doing this type of system would be since this is my first time creating something like this. By “2D Battle System” I mean a GUI object which can move in four directions and that can detect if other GUI objects hit it. (I do this atm but I am using actual objects and rendering them on the client as images).

I use the player object for now as the heart and the bones are parts. I’m not sure if it is a good way of doing this like that? If it is an alright way of doing it then how could I improve the code below?

(The code below is only the client since the server creates attack objects, moves them and handles damage and some normal security.)

Code:

local Battle = {}

-- VARIABLES
local RunService = game:GetService("RunService")
local Player = game.Players.LocalPlayer
local Client = Player.PlayerGui.Client
local Root = Player.Character:WaitForChild("HumanoidRootPart")
local Humanoid = Player.Character:WaitForChild("Humanoid")
local RenderPlayer
local RenderAttack
local RenderCamera

-- OBJECT VARIABLES
local AttackStorage = game.Workspace.Battle.Attack
local Spawn = game.Workspace.Battle.Spawn

-- FUNCTIONS
function Battle:CalculatePos(obj) -- calculates objects for the area inside the GUI.
	local x,z = obj.Position.X, obj.Position.Z
	local xz = UDim2.fromScale(x/100+0.5, z/50+0.5)
	return xz
end

function Battle:CreateAttack(physicalObj) -- creates attack obj in GUI.
	if AttackStorage[physicalObj.Name] then
		local guiObject = script[physicalObj.Name]:Clone()
		guiObject.Parent = Client.BattleFrame.Area
		guiObject.Name = physicalObj:WaitForChild("GUID").Value
		guiObject.Position = self:CalculatePos(physicalObj)
		Battle:VisualAttack(guiObject.Name)
	end
end

function Battle:VisualAttack(GUID) -- unique object identification and movement for object.
	for _,v in pairs(Client.BattleFrame.Area:GetChildren()) do
		if v.Name == GUID then
			RenderAttack = RunService.RenderStepped:Connect(function()
				for _,b in pairs(AttackStorage:GetChildren()) do
					for _,d in pairs(b:GetChildren()) do
						if d:IsA("StringValue") and d.Value == GUID then
							Client.BattleFrame.Area[GUID].Position = self:CalculatePos(b)
						end
					end
				end
			end)
		end
	end
end

local RemoveBattleAttack = function(GUID) -- removes gui object.
	for _,b in pairs(AttackStorage:GetChildren()) do
		for _,d in pairs(b:GetChildren()) do
			if d:IsA("StringValue") and d.Value == GUID then
				Client.BattleFrame.Area[d.Value]:Destroy()
			end
		end
	end
end

local BattleCamera = function(state) -- forces player's camera to have matching orientation with the gui (-90, 0, 0)
	if state then
		RenderCamera = RunService.RenderStepped:Connect(function()
			game.Workspace.CurrentCamera.CFrame = game.Workspace.Battle.Camera.CFrame
		end)
	else
		if RenderCamera then
			RenderCamera:Disconnect()
			game.Workspace.CurrentCamera.CFrame = game.Workspace
		else
			return print("[CLIENT] - Camera has not been rendered!")
		end
	end
end

function Battle:Render() -- renders the player in gui (heart)
	RenderPlayer = RunService.RenderStepped:Connect(function()
		Client.BattleFrame.Area.Player.Position = Battle:CalculatePos(player)
	end)
end

function Battle:TeleportPlayer() -- teleports player to area for now.
	Root.CFrame = CFrame.new(Spawn.Position)
end

AttackStorage.ChildAdded:Connect(function(typ) -- creates attack when server creates attack.
	Battle:CreateAttack(typ)
end)

-- CONNECTIONS
Battle:TeleportPlayer()
Battle:Render()

local CameraEvent = game.ReplicatedStorage.Assets.Events:WaitForChild("Camera")
local CleanBattleEvent = game.ReplicatedStorage.Assets.Events:WaitForChild("Clean")
CleanBattleEvent.OnClientEvent:Connect(RemoveBattleAttack)
CameraEvent.OnClientEvent:Connect(BattleCamera)

return Battle

GUI:

Physical Room:

8 Likes

I like how there’s 6 likes but nobody actually tries to help you…

I don’t know how to answer this but I’ll try to help. There are a few GUI collision scripts out there that you can learn off since its just basic math.

1 Like

I actually already use that for the collision (but I didn’t show it in the post), but thanks anyways! This post and my questions do not make too much sense tbh, and I was basically asking if I should do this using actual objects then to replicate it on the client or to do the system purely on the client.

I already figured out what I would do and I’ll see how it performs when the game comes further in development.