I'm spawning a number of identical objects in code (Area2d with sprite and collisionshape2d children). When two objects collide I'd like to be able to stop them and put them back in their pre-collision places. To do this, in each objects process function I'm storing the current position before moving to the new position. If the object collides I'm trying to restore the old position in the ...area_entered() function but it doesn't work. Collisions are being detected properly so what's going on?

func _process(delta): # get vector to mouse var mouse_vector = (get_viewport().get_mouse_position() - position) var mv_length = mouse_vector.length() old_position = position # if nearby if mv_length < 100: if monster_type == CHASER: # growl if not flagGrowled: $GrowlSound.play() flagGrowled = true # move towards mouse cursor mouse_vector = mouse_vector.normalized() position += mouse_vector * delta * SPEED else: flagGrowled = false

and in the collision handler:

func _on_Face_area_entered(area): print("Collided") position = old_position

Without testing (and just glancing through the code real fast), I think the problem is that you are updating old_position every _process call, which means it is not storing the original position, but rather the position a single _process call ago. Since _process is called every frame, that means you old_position is storing the position the node had last frame, not the position it had originally.

You should just need to add old_position = position in _ready, remove the the old_position = position line in _process, and then it should work.

@TwistedTwigleg said: ... I think the problem is that you are updating old_position every _process call, which means it is not storing the original position, but rather the position a single _process call ago. Since _process is called every frame, that means you old_position is storing the position the node had last frame, not the position it had originally.

Thanks for the reply. Yes that's what I want to achieve, ie if a collision has occurred , put the object back to it's pre-collision position. In another procedural language I'd calculate the new position and check if it would collide, if it would then I'd abandon the move. I can't think how to do this in Godot...

Sorry, forgot to say, I also tried using _physics_process() even if that's not relevant for an Area2d node, in case the position info was inaccurate but the result is the same.

Almost solved this with the use of a simple flag and moving the colliding sprite object back from where it came (sort of!). Code attached, just need to kill the sound when the objects collide. To use, move the mouse near to a sprite, most of which will follow the mouse cursor but some are passive.

Hey @picnic! Sorry about the late reply, was busy with other stuff :smile:

I looked at the project, and I think I see why the initial problem was not working. I changed the code and added a comments on things I changed, hopefully explaining how it works, and why I changed what I did. One thing I did not realize until looking at the code was you are calling add_child before setting the position, which made old_position always equal (0,0) (assuming it was not being set in _physics_process). I changed the code to store the starting position, and now when two faces collide, their positions are reset correctly.

As for stopping the sound, you can just need to use $GrowlSound.stop() (I think that is the name of the node) and that will stop the sound from playing.

I also changed the color of the sprites based on which type they are to make it easier to tell which move and which do not. This is just a personal preference, as I like to know which node does what at a glance. Feel free to remove the code if you want! I added a comment showing which part changes the color.

Feel free to remove/change anything I added to the project! Hopefully it will help!

Hey @TT

Thanks for looking into that, I'll take a look at your comments. I've now changed the code entirely to use RigidBody2D instead of Area2D and it's working nicely with some additional features :smiley: Incidentally, the plan is to make the final sprites look the same so you never know until you're up close whether they'll chase you or not ;)

Cheers!

@picnic said: Thanks for looking into that, I'll take a look at your comments. I've now changed the code entirely to use RigidBody2D instead of Area2D and it's working nicely with some additional features

Ah, cool! Glad you have got it working, with additional features to boot! :smile:

Incidentally, the plan is to make the final sprites look the same so you never know until you're up close whether they'll chase you or not

Ah, that makes sense! I At first I was really confused at why some were not following and it was kinda surprising when the first one did, as the first couple I checked were not the chasing ones. Now it totally makes sense!

4 years later