How to use particle 2D nodes to simulate the trail of rigidbody 2D?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By linwz

I am going to make a basketball shooting game. I made my basketball using rigidbody2D node, and i want to simulate the trail of basketball. Is there anyway to simulate the trail using patricle2d node?

:bust_in_silhouette: Reply From: timothybrentwood

Here is some code doing what you’re trying to do using a Line2D node:

extends KinematicBody2D

var line = Line2D.new()
var velocity = Vector2.ZERO
var speed = 50
var timer : Timer

func _ready() -> void:
	timer = Timer.new()
	timer.wait_time = 0.5
	timer.connect("timeout", self, "check_clear_points")
	self.add_child(timer)
	get_parent().call_deferred("add_child",line)
	
func _physics_process(delta: float) -> void:
	var direction = Vector2.ZERO

	if Input.is_key_pressed(KEY_D):
		direction += Vector2.RIGHT
	elif Input.is_key_pressed(KEY_A):
		direction += Vector2.LEFT
	elif Input.is_key_pressed(KEY_W):
		direction += Vector2.UP
	elif Input.is_key_pressed(KEY_S):
		direction += Vector2.DOWN
	else:
		velocity = velocity * 0.8
		if abs(velocity.distance_to(Vector2.ZERO)) < 0.5:
			velocity = Vector2.ZERO
	
	velocity = move_and_slide(velocity + (direction * speed * delta))
	
	if velocity == Vector2.ZERO:
        if timer.is_stopped():
    		timer.start()
	else:
		line.add_point(self.position)
		
func check_clear_points():
	if velocity == Vector2.ZERO:
		line.clear_points()

Where it says line.add_point(self.position) you could (assuming your particle faces right by default):

var new_particle = my_particle_2d_scene.instance()
new_particle.position = self.position
new_particle.rotation = velocity.angle()
get_parent().call_deferred("add_child", new_particle)
new_particle.add_to_group("particles")

Then where it says line.clear_points() you could:

call_group("particles", "queue_free")

Ideally, you would be checking a state of your basketball object rather than velocity == Vector2.ZERO

It’s very kind of you.

But I’m sorry that my expression of the question is wrong, because of my poor English.
The situation I am considering is when the ball hasn’t applied an impulse, I want to make a sighting line to aim ( not the trail, sorry).

And I found that in Particles2D node, when setting a ParticlesMaterial to node’s process material, there is an “Initial Velocity” property, it’s behavior is similar to RigidBody2D after applied an impulse.

like this:

extends Node2D

var direction = Vector2.RIGHT
var speed = 200

func _input(event):
	if event.is_action_pressed("ui_accept"):

		# hit ball
		$RigidBody2D.apply_central_impulse(direction * speed)

		# use particles to simulate the sighting line of ball
		var material = $Particles2D.get_process_material()
		material.direction = Vector3(direction.x, direction.y, 0)
		material.initial_velocity = speed
		$Particles2D.emitting = true

Anyway, thanks very much :slight_smile:

linwz | 2021-04-30 02:07