move an object / sprite forever at its current angle / rotation ?

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

so i have 2 objects… the first object has basic movement code… and the second object has “look_at()” code… so everytime i move the first object the second object will always facing the first one… BUT… i want the second object to move forward forever … like…its move forward forever to its current angle/ rotation

:bust_in_silhouette: Reply From: Zylann

You can do it this way:

func _fixed_process(delta):

	# ...
	# look at
	# ...

	# You need an angle rotated 90 degrees,
	# because look_at considers that an angle of 0 is pointing up, not right.
	# (Adjust it if it's wrong in your case, depends on how your sprite looks)
	var angle = get_rot() - PI/2.0

	# Define some speed
	var speed = 10.0

	# Calculate direction:
	# the Y coordinate must be inverted,
	# because in 2D the Y axis is pointing down
	var dir = Vector2(cos(angle), -sin(angle))

	# Move
	set_pos(get_pos() + dir * (speed * delta))

no shorter code than that ?

AnotherUserz 1 | 2017-02-19 12:53

The code look long because I heavily commented it.
You can use move too, but I don’t know if it can make the code shorter.
It would be like this:

move(dir * (speed * delta))

In order for your node to move in a given direction (dir), you need that direction. All you have is an angle (one number), so you must convert that angle into a vector (x and y) using simple trigonometry.

You also need to define at which speed you want your object to move. In my code I just defined it on the fly as 10 pixels per second, but you can put it as a member variable of your script, or as a constant if you want.

In Godot, delta is the parameter received by _fixed_process and _process. It contains the amount of time elapsed between two frames.
It needs to be a multiplier of speed because in this way, your game won’t slow down if the game lags, and won’t be faster if FPS increases, it will stay at the speed you want.

Writing move(vector2(the x and y pos) is possible indeed, that’s what I do, because when you multiply dir by a number (speed * delta) you still obtain a vector, representing the “amount of distance in X and Y to move for this frame”. That’s basic vector math :wink:

However, I agree the extra rotations I added are a bit cumbersome, but they are needed due to 2D conventions in Godot, and also because it depends how you drew your sprite. My code assumes the sprite looks at the right in its image file, but if you made it look up, you don’t need it. And if it was looking left, you would need the opposite etc.

Zylann | 2017-02-19 17:39

If you want to get a directional vector and not worry too much about the math, you can use get_transform() (or get_global_transform if that’s what you need). This gives you three elements to work with; origin (basically what you’d get with get_pos()), and local vectors for x (facing right) and y (facing down).
If you’re using look_at(), it’s going to be pointing that y vector in the direction you want it to look, so if you want it to move in that direction:

var dir = get_transform().y
move(dir*speed*delta)

YeOldeDM | 2017-02-19 18:04

Ah yeah, almost forgot this. It looks cleaner indeed, but you might prefer getting the x vector in case the sprite is right-oriented.

Zylann | 2017-02-19 18:07

understand all already… thx… but what about the “angle” variable code ? why do i need to substract it with PI ? and divide it by 2 ???

AnotherUserz 1 | 2017-02-20 13:55