How do you use deltaTime for 2D Physics?

I’ve written some physics code for a 2d minigame where the character can move left-to-right, jump, and fall. It works like a charm, however, it doesn’t account for FPS as it speeds up when you go past 60 FPS. I’ve tried to apply deltaTime to the code – but I can’t seem to figure it out…

I’ve removed the stuff that you won’t need for this problem, so hopefully it would be easier to look at. This is the logic for the physics itself:

local velocity = Vector2.new(0, 0)
local acceleration = Vector2.new(0, spoinkHitbox.Size.Y.Scale)

RNS.RenderStepped:Connect(function(deltaTime)
	-- LEFT-TO-RIGHT
	if holdingRight then
		if velocity.X < 0 then
			velocity *= Vector2.new(.8, 1) -- friction
		end
		acceleration = Vector2.new(spoinkHitbox.Size.X.Scale * 1.5, acceleration.Y)
	elseif holdingLeft then
		if velocity.X > 0 then
			velocity *= Vector2.new(.8, 1) -- friction
		end
		acceleration = Vector2.new(-spoinkHitbox.Size.X.Scale * 1.5, acceleration.Y)
	else -- friction for x-axis movement
		acceleration = Vector2.new(acceleration.X * .15, acceleration.Y) 
		velocity *= Vector2.new(.9, 1)
	end

	-- the ifstatement is lowkey pseudocode, the important stuff is the velocity line 
	if shouldJump then
		task.spawn(function()
			jumpDebounce = true

			velocity = Vector2.new(velocity.X, -spoinkHitbox.Size.Y.Scale * 25) -- jump power!!!
			-- insert cooldown

			jumpDebounce = false
		end)
	end

	-- limiting our velocities
	velocity = Vector2.new(
		math.clamp(velocity.X, -7, 7),
		math.clamp(velocity.Y, -math.huge, 25)
	)

	-- magic	
	spoink.Position += UDim2.fromOffset( -- position += velocity
		velocity.X, 
		velocity.Y
	)
	velocity += acceleration
end)

As for my attempt, I made this function:

function perFrameFromDeltaTime(value, deltaTime) -- we need this to combat different fps rates (60 fps, 120 fps, etc)
	return value * (deltaTime / (1/60))
end

and I tried multiplying it to acceleration (gravity) and left-to-right movement… but it doesn’t really give me the results I want. It just jumps way higher than normal when I raise the cap to 120 FPS…

I feel like I’m just doing the function wrong, but whatever the case – how should I go about this?

1 Like

You just need to multiply the distance you’re moving by delta time.

Let’s suppose our moveSpeed is 10, and it takes 1s per frame.
In that case, I should move 10 every frame.
If it takes 0.5s per frame, your game runs 2x as fast, and so you should move 0.5x as far.

3 Likes

After looking through different resources, I (believe to have) figured out how to implement deltaTime in my physics code.

How I handle physics is called Euler’s Method, which is basically:

position += velocity
velocity += acceleration

And if we can say that the expected deltaTime is somewhere around 1/60 (60 frames in 1 second, which is approximately 0.0166…), we can use that to create a ratio that is equal to (60 * deltaTime)

image

Which leads to the final code of:

position += velocity * (60 * deltaTime)
velocity += acceleration * (60 * deltaTime)

After some testing, I believe it works well enough to cover FPS past 60 frames.


Final side note: I believe this method isn’t accurate enough when it comes to huge deltaTimes (i.e. whenever FPS goes lower than 60) – if anybody wants to look into this, try reading this post which was very useful to me.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.