Having problems to rotate an object

Godot Version

4.2

Question

I’m having problems to position the object’s center to the mouse cursor. It’s like the paper game “Battlefields”: you have a grid and place ships on the grid. They need to be horizontal or vertical, diagonals are not allowed. The ship class is a Node2D because I draw a rectangle on it. On that rectangle is the Sprite2D with the actual ship and an Area2D with Collider to get the mouse events. When I click one ship, it gets selected and follows the mouse (this works so far).
But now, when I hit the space bar I rotate the ship:

func rotate_ship(angle: int):
	print("Rotation: ", a)
	print("Global Position: ", global_position)
	print("Position: ", position)
	rotation = deg_to_rad(a)
	global_position.x = get_global_mouse_position().x #- (x * PX / 2)
	global_position.y = get_global_mouse_position().y #- (y * PX / 2)
	print("Mouse position: ", get_global_mouse_position())

“angle” starts with 0 and is incremented with each space bar hit by 90, so “Rotation” prints 90, 180, 270, 0. This works as well, but the ship is no longer centered to the mouse cursor. As per the debug messages the global_position (I tried “position” also) is not changed, I even tried “+400” and it didn’t change.
Debug messages (e.g.):
Rotation: 180
Global Position: (242, 265)
Position: (242, 265)
Mouse position: (258, 377)
Rotation: 270
Global Position: (242, 265.0002)
Position: (242, 265.0002)
Mouse position: (258, 377)
Rotation: 0
Global Position: (242, 265)
Position: (242, 265)
Mouse position: (258, 377)

Any ideas how I can make the ship to always be centered to the current position of the mouse cursor? Only Rotation = 0 is ok, in all other rotations the Area2D doesn’t get the mouse clicked event. And just for my understanding: why can’t I just write:

position = get_global_mouse_position() + Vector2(x/2, y/2) #Offset

Make sure your Sprite2D and CollisionShape2D are at (0,0). That is, they have no offset from the parent Ship / Node2D. Your rotation of the Ship will not work as expected otherwise.

Your debug print is before you change the position, so you’re always seeing the previous position.

Lastly, I don’t think you need to update position during rotation at all.

This sample works as expected for picking up a sprite that follows the mouse and can be rotated while held:

extends Node2D

var selected = false;

func _input(event):
	if(selected and event.is_action_pressed("rotate_left")):
		rotate_ship(-90)
		
	if(selected and event.is_action_pressed("rotate_right")):
		rotate_ship(90)
		
func _process(delta):
	if(selected):
		global_position = get_global_mouse_position()

func rotate_ship(angle: int):
	rotation += deg_to_rad(angle)

func _on_area_2d_input_event(viewport, event, shape_idx):
	if(event is InputEventMouseButton and event.is_action_released("select")):
		selected = !selected

Thanks, that was the solution. The ships were not centered, so their upper left corner was 0,0. Now I moved their center to 0,0 and it works as expected, even without re-positioning. Sometimes the solution is very easy, but if you sit there and stare at the code and try things out, it’s easy to overlook something.
So thanks again and happy new year!

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