# [SOLVED] How to manage a 3 objects collision?

Attention Topic was automatically imported from the old Question2Answer platform.

Hello there,
For the story, I am making a puzzle game where you shoot pieces together for making point.

So, there is a possibility that I need collision on more than 2 objects. In that figure, I just pushed 1 through 2 and 3.

|2|
| | | |
|1|
| | |3|
| |

Is there any ways to do this (it seems that move and collide only return 1 collision)?

Because, as my code is wrote, for example, if 1 and 2 are the same piece, sometime, 1 and 2 collide (and it’s good), but, sometimes, it’s 1 and 3 which collide. So I must try again until the game decide to make 1 and 2 collide.

And, in the case that 1,2 and 3 are the same piece, it depends on how the game feel (Sometime, it collide 1 and 2, and sometime, it collide 1 and 3).

While sharing my code, I thank you in advance!

(Square.gd)

extends "res://Classes/actors.gd"

func _physics_process(delta):
if !Global.isPaused:
if getCollider():
if getCollider().getType() == getType():
getCollider().queue_free()
queue_free()
#[...]
elif getCollider().getType() != CONST.TYPE_BALL && getCollider().getType() != CONST.TYPE_WALL && getInputVector() != Vector2.ZERO :
velocity = velocityBounce
move(delta, CONST.SPEED_SQUARE, true)
setInputVector(Vector2.ZERO)
collide = null
velocity = Vector2.ZERO
velocityBounce = null
elif getCollider().getType() != CONST.TYPE_WALL :
setCanMove(false)
else :
move(delta, CONST.SPEED_SQUARE, true)

(Classes/actors.gd)

extends KinematicBody2D

var type = 0

var inputVector = Vector2.ZERO
var velocity = Vector2.ZERO
var collide = null
var velocityBounce = null
var canMove = true

func move(delta, speed, canCollide = false) :
if canMove :
if canCollide :
if inputVector != Vector2.ZERO :
velocity = velocity.move_toward(inputVector * speed , 500 * delta)
collide = move_and_collide(velocity)
else :
if inputVector != Vector2.ZERO :
velocity = velocity.move_toward(inputVector * speed, 500 * delta)
else :
velocity = velocity.move_toward(Vector2.ZERO, 1000 * delta)
velocity = move_and_slide(velocity)

#[Setting the velocity bounce]
#[...]

func setCanMove(newCanMove):
canMove = newCanMove

func getType():
return type

func setType(newType):
type = newType

func getCollider():
if collide :
return collide.collider
else:
return null

func setInputVector(newInputVector):
inputVector = newInputVector
inputVector.normalized()

func getInputVector():
return inputVector

I don’t imagine how stiff this movement should be in your game, but are You sure move_and_collide is good sollution ? It makes body stop after first collision, so it is unlikely, that You will ever collide with 2 objects at the same time. Perhaps You could use move and slide, it is basically a move_and_collide with multiple collision detection. Or You could use areas instead of bodies and get colliders within get_overlapping_areas ?

Inces | 2022-07-22 12:52

I added an Area2D on my Square.tcsn. I manage the others collision with move_and collide, but I used get_overlapping_areas for checking for pieces similarity.

This may be not the most optimal way, but it work! Thanks you, mate!

(Square.gd)

extends "res://Classes/actors.gd"

func _physics_process(delta):
if !Global.isPaused:
var areaCollide = \$Area2D.get_overlapping_areas()
if getCollider() :
if areaCollide.size() > 0:
for item in areaCollide :
if item.get_owner().getType() == getType():
item.get_owner().queue_free()
queue_free()
if  getCollider().getType() != CONST.TYPE_BALL && getCollider().getType() != CONST.TYPE_WALL && getInputVector() != Vector2.ZERO :
velocity = velocityBounce
move(delta, CONST.SPEED_SQUARE, true)
setInputVector(Vector2.ZERO)
collide = null
velocity = Vector2.ZERO
velocityBounce = null
elif getCollider().getType() != CONST.TYPE_WALL :
setCanMove(false)
else :
move(delta, CONST.SPEED_SQUARE, true)

L_BlueYoshiFan97 | 2022-07-24 00:01

You are welcome. I would appreciate vote up or choose as best answer

Inces | 2022-07-24 06:37