Shoot one bullet at a time

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

I want to only shoot another “bullet” when there’s no other bullet on the screen (basically only shoot one at a time). What’s the easiest way of doing that? Thank you for reading.

:bust_in_silhouette: Reply From: Gokudomatic2

Use groups. If there’s at least one entity in the “bullet” group, your player won’t be allowed to shoot.

:bust_in_silhouette: Reply From: Zylann

You don’t necessarily need a group for this (unless you want more than one bullet on screen). Indeed, why would you need a group if it’s to put only one node in it?

What I would do is to keep a reference on the bullet node, and disable it when appropriate instead of destroying it. Then you know if you can shoot and enable it again by checking if the bullet is active or not.

How would you do this using code? Can you give me an example? Sorry I’m a total newbie

Zero | 2016-07-14 19:33

With bullet reference:

var _bullet = null

func can_shoot():
	return _bullet == null or not _bullet.is_visible()


func _process(delta):
	if Input.is_action_pressed("shoot") and can_shoot():
		
		[...] Get the position and direction where you want

		# If the bullet doesn't exists yet, create it
		if _bullet == null:
			_bullet = preload("bullet.tscn").instance()
			get_tree().get_root().add_child(_bullet)

		# Fire bullet
		_bullet.spawn(new_position, new_direction)

Then you can disable your projectile when it hits something or goes too far away.

Actually, with groups the code is simpler, but you have to put the bullet scene into a group,
and you also have to destroy it with queue_free() when it hits something, and recreate it each time you need to shoot.

func can_shoot():
	return get_tree().get_nodes_in_group("bullets").size() == 0

func _process(delta):
	if Input.is_action_pressed("shoot") and can_shoot():
		var bullet = preload("bullet.tscn").instance()
		get_tree().get_root().add_child(bullet)
		
		[...]

		bullet.spawn(new_position, new_direction)

Actually with only one bullet, any of the options do the job quite well.

In both examples I assume there is a spawn function in the bullet, it should set the position and direction of it (but I assume you have this already).

Zylann | 2016-07-14 20:36

The group one helped me out a lot! Thank you very much!

Zero | 2016-07-14 20:58