Hi everyone. I’m trying to create a game where an object spawns and you need to grab the correct object towards it to destroy it, and once it’s destroyed it will spawn again after a certain amount of time. While I’ve been able to accomplish spawning the object I want and destroying it, I haven’t been able to get it to spawn again. I’ve tried using if statements but that keeps it from spawning altogether.
This part gets it to spawn:
extends Area2D
var customer = preload("res://right_customer.tscn")
var spawned = false
var posit = self.global_position
func _ready() -> void:
spawn()
func spawn():
%SpawnTimer.start()
func _on_spawn_timer_timeout() -> void:
inst(posit)
spawned = true
global.customers += 1
%SpawnTimer.stop() # Keeps it from spawning over and over again.
func inst(pos):
var instance = customer.instantiate()
instance.position = pos
add_child(instance)
And this part is to destroy the object that has been spawned.
extends Node2D
var draggable = false
var is_inside_dropable = false
var body_ref
var offset: Vector2
var initialPos: Vector2
func _ready():
initialPos = global_position
$Label.text = self.name
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta):
if draggable:
if Input.is_action_just_pressed("click"):
offset = get_global_mouse_position() - global_position
global.is_dragging = true
if Input.is_action_pressed('click'):
global_position = get_global_mouse_position() - offset
elif Input. is_action_just_released("click"):
global.is_dragging = false
if is_inside_dropable:
var test = body_ref.desired_food[0]
if self.name == test:
body_ref.queue_free()
global.score += 1
else:
body_ref.patience -= 20
var tween = get_tree().create_tween()
tween.tween_property(self,"global_position",initialPos,0)
func _on_area_2d_mouse_entered():
if not global.is_dragging:
draggable = true
scale = Vector2(1.2, 1.2)
func _on_area_2d_mouse_exited():
if not global.is_dragging:
draggable = false
scale = Vector2(1,1)
func _on_area_2d_body_entered(body):
if body.is_in_group("dropable"):
is_inside_dropable = true
body_ref = body
body.scale = Vector2(1.1,1.1)
func _on_area_2d_body_exited(body):
if body.is_in_group("dropable"):
is_inside_dropable = false
body.scale = Vector2(1,1)
It looks like you are stopping the timer in the spawner, but nothing starts it again. Something will have to call spawn() again. I’m not sure what “global” is but I assume it’s an autoload you have. Maybe have a function in global that tells the timer to start again, and call it from your _on_area_2d_body_entered? Would be a good idea to tell us what global is. It’s kind of important and I’m only able to assume it’s an autoload.
Cool. So you need something to call spawn again and probably doing it from global would work. You seem to be making a lot of unnecessary choices or maybe ones that are just confusing to me. var posit = self.global_position… it will never change, it simply captures where the global position is just before _ready fires. You have a lot of seemingly unnecessary logic jumps too and probably far more conditionals or nesting than necessary, but maybe I’m missing something? You may need to give more info.
Yeah, that’s to help put the instantiated object in the position where I drop it in the scene; last I checked, if I don’t do that, the object just appears in the top left of the screen.
Also, I am trying to call spawn from global, but it give me a “null_instance” error. I’m trying to call the node, but it doesn’t seem to work.
This is the function I used in the autoload to try to spawn again, and the SpawnPoint is it’s own scene that I’ve placed in the main scene.
func start_again():
var custom = get_node("/root/global/SpawnPoint")
custom.spawn()
I think all you have to do is call %SpawnTimer.start() after the doodad gets queue_freed. % should make the node accessible anywhere as long as it’s in the scene. Sorry if I’m butting in on your process, but just some tips, you can probably queue free in the area entered signal. I think _input is better for checking if the mouse is moving rather than do it constantly in process. You can probably move a lot of that in _process into signals. Calling all of these each process frame is pretty un-optimal though you aren’t doing enough per frame to notice it being slow. Just some thoughts.
Okay, that worked, thanks. But I had to create it as a child in the main scene rather than a child of the SpawnPoint Scene itself, if that makes any sense.
I suppose, although the idea is to have it happen when the player lets go of the mouse button, but maybe that does clutter things up, or at least it does the way I’m doing it.