Godot Version
4.4.1.stable
Question
I’m working on a Duck Hunt clone where everything is delayed, so you have to time your shots well to shoot the fish (the duck replacements). The current state of my project is this: you generate a torpedo at the location of the mouse once you click, which starts an animation that shows a clock counting down, and, upon the end of the animation, (As of now it takes one second, but I’ll probably make it take longer later.) if the detonation signal is connected, (whether it is or not is dictated by an _on_body_entered signal and an _on_body_exited signal, essentially meaning that the signal is only connected when the fish and the pending torpedo are overlapping.) the fish starts its death animation. The problem is that, if I try to shoot two fish at once by clicking at a fish and then, before the clock animation is finished, I click at another fish, the first torpedo starts the first fish’s death animation, but the second torpedo doesn’t. I’m not getting any error message, so I have no clue what I’m doing wrong. I’m pretty new to programming, (I just finished the 2D game tutorial.) so even though I’ve been checking the documentation religiously, I don’t understand a lot of things in it. Anyway, here’s the scripts from the Torpedo scene, the Fish scene, and the Main scene, as well as a screenshot of the scene tree. I tried to follow the style guide, but once again, I’m really new to this so please forgive me for any mistakes.
Torpedo script:
extends CharacterBody2D
## Not much here, mainly just stuff that deals with signals. I probably could
## have gone without making a custom signal, but I don't really know what else
## to use.
signal detonated
func _ready() -> void:
$AnimatedSprite2D.play()
func _on_animated_sprite_2d_animation_finished() -> void:
detonated.emit()
queue_free()
Fish script:
extends Area2D
## The duck replacements. I'm planning on giving them different behavior based
## on what color they are, with each color being a different animation.
@onready var color = ["yellow", "blue", "pink", "green", "red"]
func _ready() -> void:
$AnimatedSprite2D.animation = color.pick_random()
$AnimatedSprite2D.play()
func _on_body_entered(body: Node2D) -> void:
if body.name == "Torpedo":
body.detonated.connect(_on_Torpedo_detonated)
# The below code block is, as of yet, unused, as I haven't yet coded in the
# fish's movement yet, because that sounds really hard.
func _on_body_exited(body: Node2D) -> void:
if body.name == "Torpedo":
body.detonated.disconnect(_on_Torpedo_detonated)
# The animations with Fillet in the names are the death animations.
func _on_Torpedo_detonated():
$CollisionShape2D.set_deferred("disabled", true)
rotate(3 * PI / 2)
if $AnimatedSprite2D.animation == "yellow":
$AnimatedSprite2D.animation = "yellowFillet"
if $AnimatedSprite2D.animation == "red":
$AnimatedSprite2D.animation = "redFillet"
if $AnimatedSprite2D.animation == "blue":
$AnimatedSprite2D.animation = "blueFillet"
if $AnimatedSprite2D.animation == "green":
$AnimatedSprite2D.animation = "greenFillet"
if $AnimatedSprite2D.animation == "pink":
$AnimatedSprite2D.animation = "pinkFillet"
Main:
extends Node
## This is where the bulk of the Torpedo's instructions are.
##
## The SchoolGap Timer is going to be used for spawning in schools of fish that
## are evenly spaced, and the Pointer sprite only exists because I'm too lazy to
## resize a 9x9 png.
const TORPEDO_LIMIT = 3
var torpedo_count = 0
func _ready() -> void:
$Torpedo.queue_free()
$Fish.queue_free()
func _input(event: InputEvent) -> void:
if Input.is_action_just_pressed("LMB") and torpedo_count < 3:
var Torpedo = preload("res://torpedo.tscn")
var Torpedo_instance = Torpedo.instantiate()
Torpedo_instance.position = get_viewport().get_mouse_position()
add_child(Torpedo_instance)
# The block below is just a placeholder so I can freely test the fish.
if Input.is_action_just_pressed("RMB"):
var Fish = preload("res://fish.tscn")
var Fish_instance = Fish.instantiate()
Fish_instance.position = get_viewport().get_mouse_position()
add_child(Fish_instance)
func _on_torpedo_ready() -> void:
torpedo_count += 1
func _on_torpedo_detonated() -> void:
torpedo_count -= 1
Thank you!