Heart System Help

Hello Devs!
Im still quite bad at scripting, and I need some help with a heart system. I already have a draft, and it doesnt work too well. If the player loses hearts slowly, it does what its meant to do, but if the player loses hearts quickly, because of the 1 second cooldown, the script breaks. Ive tried lowering the cooldown but that breaks the animation.

! This script is really messy and is probably done in an inefficient way !

local TweenService = game:GetService("TweenService")
local Heart1 = script.Parent.Heart1
local Heart2 = script.Parent.Heart2
local Heart3 = script.Parent.Heart3

local BrokenID = "rbxassetid://15738277774"
local FixedID = "rbxassetid://15738280507"

local function createBrokenHeart(originalHeart)
	local newHeart = originalHeart:Clone()
	newHeart.Image = BrokenID
	newHeart.Parent = originalHeart.Parent
	newHeart.Position = originalHeart.Position
	return newHeart
end

local function animateHeartLoss(originalHeart)
	if originalHeart.Image == BrokenID then
		return
	end

	local brokenHeart = createBrokenHeart(originalHeart)

	local tweenInfo = TweenInfo.new(1, Enum.EasingStyle.Quart, Enum.EasingDirection.Out)
	local endPosition = originalHeart.Position + UDim2.new(0, 0, 0, 50)

	local tween = TweenService:Create(originalHeart, tweenInfo, {
		Position = endPosition,
		ImageTransparency = 1,
	})

	tween:Play()

	tween.Completed:Connect(function()
		originalHeart:Destroy()
		brokenHeart.Visible = true
	end)
end

local function resetHearts()
	script.Parent.Heart1.Image = FixedID
	script.Parent.Heart2.Image = FixedID
	script.Parent.Heart3.Image = FixedID
end

local player = game.Players.LocalPlayer
local Values = player:WaitForChild("Values")
local Hearts = Values:WaitForChild("Hearts")

-- I think the error starts from around here

while true do
	wait(1)
	local HeartsValue = Hearts.Value

	if HeartsValue == 3 then
		resetHearts()
	elseif HeartsValue == 2 then
		animateHeartLoss(script.Parent.Heart1)
		Heart2.Image = FixedID
		Heart3.Image = FixedID
	elseif HeartsValue == 1 then
		animateHeartLoss(script.Parent.Heart2)
		Heart3.Image = FixedID
	elseif HeartsValue == 0 then
		animateHeartLoss(script.Parent.Heart3)
	end
end

I thought the error was that I need to make it check if the hearts value is 2 or less, 1 or less etc using <=, but that introduces more problems.

Apologies for having such little knowledge about this topic

4 Likes

can you show a video? because i don’t understand the issue

and can you show where the script stops working?

1 Like

Sure,
robloxapp-20231230-1241481.wmv (458.5 KB)
Sorry for the rough UI, havent got to designing it yet
(if I do it faster the hearts dont go at all, or just one heart goes like the middle one)

1 Like

i found this, instead doing while true do change it in while wait(1) do
i think is the problem but i didn’t see the video yet

1 Like

The same issue persists, it does the same thing when changing it

1 Like

i have an idea, create a text gui for template and in the while wait() do change it to HeartsValue so you can see if the value goes below 0 or not

1 Like

and for not getting values get up or down to a limit you can use math.clamp(num, min, max)

1 Like

It goes below 0 for now, but i was planning on adding a limit later, like a game over screen

1 Like

you can do

	elseif HeartsValue < 1 then
		animateHeartLoss(script.Parent.Heart3)
	end
end

the HeartsValue < 1 checks if is going below 0
or if gets an error just use math.clamp for where you change the HeartsValue

1 Like

tried this, if I spam lose hearts, something like this happens
image

1 Like

an error, just use math.clamp for where you change the HeartsValue

1 Like

Sorry, how do I use that, not too good with that

1 Like

the first is the number, the second the mininum limit, and the third the max limit

here’s an example:

local HeartsValue = Hearts.Value

function SomeFunctionToChangeTheHealthForExample()
	HeartsValue = math.clamp(HeartsValue - 1, 0, 3)
end

Do I put this where im decreasing hearts?

1 Like

can you show me the script where you decrease the heartsValue?

1 Like

Heres the part of the script:

function CheckTopping(button, player)
	if not currentTopping then
		SetRandomTopping()
	end

	if button.Name == currentTopping then
		print("Correct!")
	else
		game.Players.LocalPlayer.Values.Hearts.Value = math.clamp(game.Players.LocalPlayer.Values.Hearts.Value - 1, 0, 3)
		print("Wrong!")
	end

	SetRandomTopping()
end
1 Like

but does it work the math.clamp?

1 Like

Yes, it doesnt go above or below now, but I still have the error.
If I Iose hearts very slowly, the script works, heres what it does:
robloxapp-20231230-1302544.wmv (146.0 KB)

But the problem is that the player will lose hearts very quickly, causing the heart system to break as shown in the other video

1 Like

i have an idea, but it will require some time, hide the buttons using

function hideAndShowButton(ButtonOfToppingIdkTheName)
	ButtonOfToppingIdkTheName.Visible = false
	wait(1)
	ButtonOfToppingIdkTheName.Visible = true
end

--in the wrong  topping for the if ... then
for i, button in pairs(buttons:GetChildren()) do
	coroutine.wrap(hideAndShowButton)(button) -- coroutine is going to countinue the for i loop without doing it one after the other
end

this is an example

1 Like

Can you explain what this does, im a bit confused. Also there is 3 buttons so what should I do?
Sorry for the dumb questions

1 Like