# How to use constant_torque with move_and_collide on a RigidBody2D?

4.2.1

### Question

I’m trying to learn game development moving from web development and I’m starting experimenting with a simple 2d physics based game. It is a spaceship navigating an asteroid field. This is my code for the ship rigid body:

``````const TORQUE = 4e6
const MAIN_DRIVE_FORCE = 1e6
const RCS_FORCE = 1e5

mass = 10e3
can_sleep = false
gravity_scale = 0.0
linear_damp = 0
contact_monitor = true
max_contacts_reported = 10

func _process(_delta):
constant_torque = 0
constant_force = Vector2.ZERO

if Input.is_physical_key_pressed(KEY_Q):
constant_torque = -TORQUE
if Input.is_physical_key_pressed(KEY_E):
constant_torque = TORQUE

if Input.is_physical_key_pressed(KEY_W):
add_constant_central_force(Vector2(RCS_FORCE * cos(rotation), RCS_FORCE * sin(rotation)))

if Input.is_physical_key_pressed(KEY_S):
add_constant_central_force(Vector2(RCS_FORCE * cos(rotation + PI), RCS_FORCE * sin(rotation + PI)))

if Input.is_physical_key_pressed(KEY_D):
add_constant_central_force(Vector2(RCS_FORCE * cos(rotation + PI / 2), RCS_FORCE * sin(rotation + PI / 2)))

if Input.is_physical_key_pressed(KEY_A):
add_constant_central_force(Vector2(RCS_FORCE * cos(rotation - PI / 2), RCS_FORCE * sin(rotation - PI / 2)))

if Input.is_physical_key_pressed(KEY_SHIFT):
add_constant_central_force(Vector2(MAIN_DRIVE_FORCE * cos(rotation), MAIN_DRIVE_FORCE * sin(rotation)))

var acc := constant_force / mass
var v := linear_velocity
# var collision = move_and_collide(v + acc * _delta)

# if collision:
#     var collider := collision.get_collider()
#     var col_position := collision.get_position()

#     print("collided with ", collider, " at ", col_position)

print("torque: ", constant_torque, "  ang_v: ", angular_velocity, "  force: ", constant_force, "  acc: ", acc, "  v: ", v)

``````

If I keep it like that, it works perfectly.

The problem happens when I uncomment the last lines to detect collisions with the asteroids. If I do that, the ship rotation breaks completely. It doesn’t rotate for a while, then it jumps to a higher angle on one frame, then it does nothing for a few seconds more, then it jumps to an even higher angle, etc…

What is going wrong here? Is there a better way to get the `KinematicCollision2D` without using `move_and_collide`?

I think the problem is because you’re mixing the `add_constant_central_force` with the `move_and_collide`, the add/apply methods is to let the physics engine handle all the physics while the move_and_collide is for you handle the physics manually

Also there’s a better way for you get the collisions with your rigidbody, use the
`body_entered` signal

RigidBody2D — Godot Engine (stable) documentation in English

2 Likes

I kinda tried that.

``````func test(collider):
print("Collided!",collider)

....
connect("body_entered", test)
....
``````

The problem is I’m only getting the collider node there, I also want to get the collision position, because in some cases, it will collide with a tilemap, and I need to know exactly on which tile is it colliding to remove it.

That why I think I need the `KinematicCollision2D` and not only the node

In this case use body_shape_entered signal and Tilemap.get_coords_for_body_rid(), that will return the tilemap coordinate of the collision:

``````func _on_body_shape_entered(body_rid, body, body_shape_index, local_shape_index):
if body is TileMap:
var collision_tile_coord = body.get_coords_for_body_rid(body_rid)
``````
1 Like

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