Like what’s the math behind it. Player clicks it move the bar and it constantly moving the bar from boss side. So how exactly is calculated how much to move the bar from player and from the boss side?
There is health value let’s say, and constant loop that changes bar’s size with math, there is green bar (you resize it) and red bar (static one), you make that every click this health value grows, and you update the bar’s size, if health is bigger than 1, then you win
EDIT: use this to calculate size:
local percent = health/maxHealth
bar.Size = UDim2.new(percent,0,1,0)
It goes down too where do you calculate it? On the server right?
So like when player clicks fight, it fires a event telling the server that this player is fighting with that Boss and then server updates the player score on each click but what about the Boss where does it get calculated?
Inside a loop i can think, like you have a table and you put each boss there and updates their’s score in like every .1 or .2 seconds then resize the bar accordingly on the client side.
Idk this what i thinks can be done. I can make it but is it really the way it done?
Ok so each bar would prob have a set amount of power needed e.g. 400 power. So the click power of the player would increase according to their level. I’ll put it in your perspective here
In the picture, you have 602 strength while the ‘boss’ has 100 strength, so the amount the bar moves with each click will vary according to your strength
local mainbar = script.Parent.BossBar
local clickbar = mainbar.PlayerClickBar
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local TS = game:GetService('TweenService')
local maxpower = mainbar:GetAttribute('Power')
local TI = TweenInfo.new(.1,Enum.EasingStyle.Linear,Enum.EasingStyle.Out)
local recordedpower = 0
function FightBack()
local rann = math.random(0,100)
if rann < 50 then -- 50% chance, change this to what you want
recordedpower -= workspace.MiniBoss:GetAttribute('Power')
TS:Create(clickbar,TI,{Size = UDim2.fromScale(math.clamp(recordedpower/maxpower,0,1),1}):Play()
end
end
game.ReplicatedStorage.StartMiniBoss.OnClientEvent:Connect(function()
local t = task.spawn(FightBack)
mainbar.Visible = true
mouse.Button1Down:Connect(function()
if clickbar.Size < mainbar.Size then
recordedpower += player:GetAttribute('ClickPower') -- This could be the strength, idk
TS:Create(clickbar,TI,{Size = UDim2.fromScale(math.clamp(recordedpower/maxpower,0,1),1}):Play()
if clickbar.Size >= mainbar.Size then
mainbar.Visible = false
task.cancel(t)
recordedpower = 0
print('Boss defeated!')
return
end
end
end)
end)
On client, health is shared value that server changes, clicks are sent via remote and checked if there is cooldown or smth, then when let’s say number value changes you update your bar’s size
It’s overcomplication, why would you use tween service? there is better option
Client:
--[[Player]]
local player = game:GetService("Players").LocalPlayer
local mouse = player:GetMouse()
--[[Important objects]]
local remote = game:GetService("ReplicatedStorage").ClickRemote
local HealthValueObject = player.BossFight.Health -- example folder
--[[Gui]]
local Gui = player.PlayerGui.BossFightGui
local Indicator = Gui.Frame.Indicator -- red bar
local Bar = Indicator.Bar -- green bar
--[[Update bar's size]]
local function OnUpdate()
local percent = HealthValueObject.Value
Bar.Size = UDim2.new(percent,0,1,0) -- Bar is parented to indicator, soo we can use percents
end
--[[Send info about clicking to server]]
mouse.Button1Down:Connect(function()
remote:FireServer()
end)
HealthValueObject:GetPropertyChangedSignal:Connect(OnUpdate)
Server:
local remote = game:GetService("ReplicatedStorage").ClickRemote
local debounce = {}
local clickCooldown = 0.05 -- cooldown
local clickStrenght = 0.1 -- how many percent one click adds
local function OnServerEvent(player: Player)
if not debounce[player] then debounce[player] = 0 end
if tick() - debounce[player] >= clickCooldown then
debounce[player] = tick()
player.BossFight.Health.Value += clickStrenght
end
end
remote.OnServerEvent:Connect(OnServerEvent)
NOTE: This script will update bar when player clicks it, you have to add loop that decrease the same value by some percent every second or soo, i wanted to show that @MysteryX2076’s script could be done better
Client Handling is easy. He clicks, the server changes his progress. I was thinking about boss as the game will have multiple players so is multiple bosses.
So do i need to handle them all in some separate loop for each or Can i do this?
function Main.Fight(player,Enemy) -- add a fight in the active table whenever a player starts a fight
table.insert(ActiveFights,{player,Enemy,true}) ---{player,enemy,isFighting}
end
while task.wait(.1) do
for i, fight in ipairs(ActiveFights) do
task.spawn(function()
local player = fight[1] --get the player from the active fights
local enemy = fight[2]--get the Boss from the active fights
wait(EnemiesInfo[enemy.Name].Cooldown) --- a cooldown for the boss, different boss have different fightback speed
fight[3]-=EnemiesInfo[enemy.Name].Strenght -- boss fight backs and reduces player progress
if fight[3] == 100 or fight[3] == -100 then -- if player had to reach the goal first or boss have reach it first fight ends
FightEnds(fight)
end
end)
end
end
the Fight[3] is the progress of the fight.
Which changes when player clicks and also when boss fight backs.
The goal for the player is to make the progress reach to 100, so like he add some value in the progress according to his strenght.
And the goal for the boss to make the progress reach to -100, so he subs some value in the progress according to his strenght.
After reaching, the goals fight ends and according to the progress it decides the winner.
Handling client is easy, I’m just thinking about a best way to handle all the bosses.
idk why there is -100, if you can use one of our methoods that are far better than this, also don’t use wait(), use task.wait() instead as it’s faster and better
local rate = 1/10
local BossDamage = 0.08
local victory = false
local function BossFight(player: Player)
repeat
player.BossFight.Health.Value -= BossDamage
if player.BossFight.Health.Value >= 1 then victory = true end
task.wait(rate)
until victory
end
-- some event such as button click or smth to connect this event to boss fight
Im sort of doing what you are doing now, subtracting the boss power from progress of the player with a 50% chance. While what you are doing works now, it takes a toll on your performance so I recommend running the fight on the client. You can take a part from @0786ideal’s code, sending a remote function to the server every click to modify the master player progress and have the boss fight back, and if the boss dies there give the rewards and stuff to the fighters
Yea. this is my concern. Also there’s some cooldown like .1 and not the true. I’ll change it in the code.
Isn’t handling it on client side make it easy to exploite?
I thought about this but what if player isn’t clicking that mean the boss is not fighting back either. But if you play these games, the boss is constantly fighting back even if player is not.
I was also thinking about this a bit. What about bindable events? Every time a player clicks you can fire it and other players fighting the boss will receive the change. Smth like this
local bossfightevent = game.ReplicatedStorage.MiniBossBindable
game.Players.LocalPlayer:GetMouse().Button1Down:Connect(function()
bossfightevent:Fire()
end)
bossfightevent.Event:Connect(function()
-- damage the boss
end)
You could activate this once the boss fight remote event is fired then you could spawn the function for the boss to fight back
TBH, this could be a good way. If no one is fighting then there will be no useless processing goin on but also if there’s only one player fighting the boss then again it goin to depend on him if the boss goin to fight back or not.