Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questions about your speed physic #1

Open
navalex opened this issue Dec 5, 2024 · 3 comments
Open

Questions about your speed physic #1

navalex opened this issue Dec 5, 2024 · 3 comments

Comments

@navalex
Copy link

navalex commented Dec 5, 2024

Hi there !

Sorry to bother you, but I found your project while trying to make a zuma like game in Godot, and appreciated the smooth of your game physics. My tries where more about processing each ball individually with an area2d to check if progress need to move or not, but it was clunky and glitchy.

After some times to check your code, I tried to reimplement the basic and it works pretty fine for the moment. However I'm not understanding everything on how you manage the speed of a FollowGroup. More precisely i'm confused with the spring function.
Wanted to ask if you can explain me a bit how it works ? Never heard about Hooke Law before

Thanks!

@damnjan
Copy link
Owner

damnjan commented Dec 5, 2024

Hello! So cool you are also making this game, I had a lot of fun while learning Godot with it :)

It's been a while since I last worked on it, but for the spring physics I asked ChatGPT and did lots of trial and error until it looked good. But basically, the spring function is modifying speed on every tick. Here's line-by-line explanation:

var displacement = target_speed - current_speed  

Displacement here represents the difference between the speed that we want to achieve and the current speed.

var acceleration = Globals.SPRING_CONSTANT * displacement

The spring constant is just a constant that defines the stiffness of the spring, and with this formula we get how much we need to accelerate. So if the speed difference (displacement) is big, the acceleration needed will be big as well. As we are approaching the desired speed, the displacement gets smaller and we are slowing down - thus we get the spring effect.

current_speed = clampf(current_speed + acceleration * delta, -Globals.MAX_BACKWARDS_SPEED, target_speed)

Here we're modifying speed (accelerating) but we want to make sure that the speed doesn't go below -Globals.MAX_BACKWARDS_SPEED and above target_speed.

global_progress += current_speed * delta

This is finally moving the group based on current_speed

I'm a bit rusty because I haven't worked with this for a long time, but I hope I helped you a bit

@navalex
Copy link
Author

navalex commented Dec 6, 2024

Thanks for your reactivity !
Okay it helps a bit. But i'm still not sure about why using a spring function. Is it just for backward movement ?

For the moment I just made a basic group logic, going only forward and without collision / merge, and making a basic linear function speed * width made no difference with the spring I think, not checked values yet.

@damnjan
Copy link
Owner

damnjan commented Dec 7, 2024

A group can have 3 states: FORWARDS, RUSHING_BACKWARDS and WAITING. If we have 2 groups and one of them is rushing backwards, as soon as it hits the group behind it, they merge into one group that is in FORWARDS state. But because of physics, the group is still moving backwards for a while until it stops and starts going forwards again. From the technical point, the group gets instant negative speed but it is actively accelerating and trying to move forwards.

This function is used for moving when the group is in its FORWARDS state. It is trying to make the group achieve a certain speed by modifying its acceleration. If acceleration is 0, then the group is moving at a constant speed. When another group hits it while rushing backwards, we sum their speeds and gets a negative speed so the merged group is now moving backwards. Now the group needs to accelerate in order to get back to its desired (positive) speed. This function calculates how much acceleration is needed to do that smoothly on every tick. Basically if the group starts suddenly moving backwards, it needs a high positive acceleration in order to counter that, and as it approaches the desired speed, acceleration needs to decrease and become 0 when the speed is reached.

I named the function like that because I tried to mimic a spring/elastic effect. Maybe it is better to think of it as an easing function.

Alternatively, if you don't care about this effect, you can simplify the following two functions like this:

func _spring(target_speed, delta):
	global_progress += current_speed * delta
func _on_next_group_collision():
	var item_to_check_from = last_item()
	manager.merge_groups(self, next_group)
	check_for_matches_from_item(item_to_check_from, true)

But then when a group hits another, they'll just continue moving forward immediately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants