While loop speeding up

made a 2d game animation using images but the loop for each frame speeds up

script
local image = script.Parent.Head

local hum = script.Parent.Humanoid

task.wait()

local function idle()
	image.idle.Enabled = true
	image.run.Enabled = false
	image.jump.Enabled = false
	while true do
		image.idle.A.Visible = true
		image.idle.B.Visible = false
		wait(0.3)
		image.idle.A.Visible = false
		image.idle.B.Visible = true
		wait(0.3)
	end
end

local function jump()
	image.idle.Enabled = false
	image.run.Enabled = false
	image.jump.Enabled = true
end

local function run()
	image.idle.Enabled = false
	image.run.Enabled = true
	image.jump.Enabled = false
	while true do
		image.run.A.Visible = true
		image.run.B.Visible = false
		wait(0.3)
		image.run.A.Visible = false
		image.run.B.Visible = true
		wait(0.3)
	end
end

hum.Running:Connect(function(speed)
	if speed > 0 then
		run()
	else
		idle()
	end
end)

hum.Jumping:Connect(function()
	jump()
end)

hum.StateChanged:Connect(function(_, new)
	if new == Enum.HumanoidStateType.Landed then
		idle()
	end
end)

the while loop speeds up when user spam the movement button and thats bad since this game is being a fighting game so users will be needed to spam the buttons to dodge the attacks

vid:

2 Likes

Lets say you have function A

You call function A when:
Player jumps

Function fires during jump

Inside the function you have a loop BUT the loop has nothing to stop it.

Function fires again, another loop is added
Function keeps firing for every jump, another loop is added for every jump
The loops add up together at once
crazy things happen at that point.

TL:DR
If you jumped 50 times, this would fire 50 times OVER and OVER without stopping every single moment:

while true do
	image.idle.A.Visible = true
	image.idle.B.Visible = false
	wait(0.3)
	image.idle.A.Visible = false
	image.idle.B.Visible = true
	wait(0.3)
end
3 Likes

how do I stop a loop inside a function using a different function tho? or I have to use repeat until?

you may use an if true then break end or disconnect a runservice event. Your choice.

1 Like

you may use a value to indicate running or walking:

local image = script.Parent.Head
local runValue = false
local hum = script.Parent.Humanoid

task.wait()

local function idle()
	image.idle.Enabled = true
	image.run.Enabled = false
	image.jump.Enabled = false
	repeat
		image.idle.A.Visible = true
		image.idle.B.Visible = false
		task.wait(0.3)
		image.idle.A.Visible = false
		image.idle.B.Visible = true
		task.wait(0.3)
	until not runValue
end

local function jump()
	image.idle.Enabled = false
	image.run.Enabled = false
	image.jump.Enabled = true
hum.StateChanged:Wait()
image.jump = false
if runValue then
image.run.Enabled = true
else
image.idle.Enabled = true
end
end

local function run()
	image.idle.Enabled = false
	image.run.Enabled = true
	image.jump.Enabled = false
	repeat
		image.run.A.Visible = true
		image.run.B.Visible = false
		task.wait(0.3)
		image.run.A.Visible = false
		image.run.B.Visible = true
		task.wait(0.3)
    until runValue
end

hum.Jumping:Connect(function()
	jump()
end)


repeat
	if speed > 0 then
        runValue = true
		task.spawn(run())
	else
        runValue = false
		task.spawn(idle())
	end
until false
-- dont put anything below here
2 Likes

it kind works, the run thing doesn’t loop back to the first image and the idle does too

It maybe inefficient but i think it would work

while image.idle.Enabled do
while image.run.Enabled do

Modify your while true do loops such that they have breaking conditions.

2 Likes

perhaps this should work better
it disconnects the function with return and it does that after its no longer doing its exact thing

local image = script.Parent.Head

local hum = script.Parent.Humanoid

task.wait()

local function idle()
	image.idle.Enabled = true
	image.run.Enabled = false
	image.jump.Enabled = false
	repeat
		image.idle.A.Visible = true
		image.idle.B.Visible = false
		wait(0.3)
		image.idle.A.Visible = false
		image.idle.B.Visible = true
		wait(0.3)
	until image.idle.Enabled == false
    return
end

local function jump()
	image.idle.Enabled = false
	image.run.Enabled = false
	image.jump.Enabled = true
end

local function run()
	image.idle.Enabled = false
	image.run.Enabled = true
	image.jump.Enabled = false
	repeat
		image.run.A.Visible = true
		image.run.B.Visible = false
		wait(0.3)
		image.run.A.Visible = false
		image.run.B.Visible = true
		wait(0.3)
	until image.run.Enabled == true
    return
end

hum.Running:Connect(function(speed)
	if speed > 0 then
		run()
	else
		idle()
	end
end)

hum.Jumping:Connect(function()
	jump()
end)

hum.StateChanged:Connect(function(_, new)
	if new == Enum.HumanoidStateType.Landed then
		idle()
	end
end)
1 Like

update: I fixed the running but the idle is broken, I used scripts with loops inside them that changes the image and just used the disabled property to set what image, the run works fine but the idle however doesn’t change the image, it just stops at what run image is currently enabled after the player stops moving

heres the script that changes the disabled property:

local image = script.Parent.Head

local hum = script.Parent.Humanoid

task.wait()

hum.Running:Connect(function(speed)
	if speed > 0 then
		script.run.Disabled = false
		script.idle.Disabled = true
	else
		script.run.Disabled = true
		script.idle.Disabled = false
	end
end)

hum.Jumping:Connect(function()
	image.idle.Enabled = false
	image.run.Enabled = false
	image.jump.Enabled = true
end)

hum.StateChanged:Connect(function(_, new)
	if new == Enum.HumanoidStateType.Landed then
		script.idle.Disabled = false
		script.run.Disabled = true
	end
end)

(I didn’t make a new local script for the jump since it doesn’t need to be looped)

run script:

local hum = script.Parent.Parent.Humanoid

local image = script.Parent.Parent.Head

image.idle.Enabled = false

image.run.Enabled = true

image.jump.Enabled = false

while wait() do

image.run.A.Visible = true

image.run.B.Visible = false

wait(0.3)

image.run.A.Visible = false

image.run.B.Visible = true

wait(0.3)

end

idle script:

local hum = script.Parent.Parent.Humanoid

local image = script.Parent.Parent.Head

image.idle.Enabled = false

image.run.Enabled = true

image.jump.Enabled = false

while wait() do

image.idle.A.Visible = true

image.idle.B.Visible = false

wait(0.3)

image.idle.A.Visible = false

image.idle.B.Visible = true

wait(0.3)

end

a more clear presentation:

nvm I found the cause, I forgot to change the enabled