How to properly handle high speed collisions

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By PKNzeta
:warning: Old Version Published before Godot 3 was released.

Hello everybody,
I have a little issue trying to use the Physics2D and RigidBody2D collision system.
I made a 500x500 window with StaticBody2D and RectangleShapes as border. then I put a Rigidbody2D ball with a Sprite2D and CircleShape2D and removed gravity. now I made the ball constantly accelerate. here is the problem, the ball accelerate has it is intended to, but as it gains more and more speed it lasts by fleeing out of the screen.

So how can I prevent the ball of doing this. I’ve looked the internet to find the correct solution, but I cannot figure out what is the correct answer for godot.

here is the code for the ball:


extends RigidBody2D

var speed = 2000

func _ready():
	randomize()
	set_linear_velocity(Vector2(rand_range(-10,10),rand_range(-10,10)))

func get_speed():
	var vect = get_linear_velocity()
	return (abs(vect.x) + abs(vect.y))

func _integrate_forces(state):
	var vect = get_linear_velocity()
	var spd = get_speed()
	
	if spd < speed - 1:
		vect *= 1.025
	elif spd > speed + 1:
		vect *= 0.975

```
set_linear_velocity(vect)
```

and there is a screenshot of the project:
screenshot
Thank you for your time.

:bust_in_silhouette: Reply From: JoshGrams

You probably want to uncheck the “Custom Integrator” box. integrate_forces gets called even if it’s unchecked, it just turns off the internal force integration. Does your ball collide with the boundaries at all?

The ball collides with the boundaries, but when it become too fast it just pass trough. no matter if I checked the Custom integration button or not.

PKNzeta | 2016-03-12 12:18

Huh. And I see you have continuous collision turned on. Maybe it’s a physics bug then… :frowning:

JoshGrams | 2016-03-12 14:36

Oh, wait. Have you tried accelerating by applying a force or impulse instead? Maybe setting the velocity directly is somehow overriding the collision response when it gets too big? Dunno.

JoshGrams | 2016-03-12 14:40

No more luck with that :-/
I tried:

extends RigidBody2D

var speed = 4000

func _ready():
	randomize()
	apply_impulse(Vector2(rand_range(-30,30),rand_range(-30,30)),Vector2(rand_range(-30,30),rand_range(-30,30)))

func get_speed(vect):
	return (abs(vect.x) + abs(vect.y))

func _integrate_forces(state):
	var vect = get_linear_velocity()
	var spd = get_speed(vect)
	
	if spd < speed - 1:
		apply_impulse(Vector2(0,0),vect)
	elif spd > speed + 1:
		apply_impulse(Vector2(0,0),-vect)

```
#set_linear_velocity(vect)
```

PKNzeta | 2016-03-12 14:52

:bust_in_silhouette: Reply From: KRL

Make your collision boundaries thicker

Hello, it is nor a viable solution for my game (an arknaoid like game)

PKNzeta | 2016-03-12 16:55

Then increase physics fixed step

KRL | 2016-03-12 18:08

:bust_in_silhouette: Reply From: styf

Hi,

Maybe you need to tweak the physics settings. You can find them under Project Settings → Physics 2D . Try lowering cell_size (It has to a power of 2)

see http://docs.godotengine.org/en/latest/tutorials/2d/physics_introduction.html?highlight=cell_size

for more information.

I’ve already tried this. It does not seam to affect anything.

PKNzeta | 2016-03-12 16:58

:bust_in_silhouette: Reply From: DriNeo

I had this issue on a 3D prototype.
I solved it by increasing the fixed fps value in Project settings, Physics .
It worked but I don’t know if a better solution is avalaible.

that solved my issue, thank you.
It’s still doing strange bounce at very high speed but it is unlikely that this kind of thing happen in my game.

PKNzeta | 2016-03-12 18:52

If you want a ball who behaves like a classic breakout game you can try with a kinematic2D instead.
Just give it a direction vector and a speed in his move() function.
His bouncing code may look like this.

 if is_colliding():
   direction = get_collision_normal().reflect(direction)  #bouncing like a breakout ball.

DriNeo | 2016-03-12 19:09

:bust_in_silhouette: Reply From: puppetmaster-

This is my solution:

func limitVelocity(delta):
	var currentVel = get_linear_velocity()
	if (currentVel.length() > MAX_BALL_SPEED):
		currentVel = currentVel.normalized()*MAX_BALL_SPEED
	set_linear_velocity(currentVel)

Nice solution. Thanks for posting it.

Robster | 2017-04-21 12:22