[SOLVED] How to manage a 3 objects collision?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By L_BlueYoshiFan97

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

onready var CONST = load("res://const.gd")

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 :wink:

Inces | 2022-07-24 06:37

:bust_in_silhouette: Reply From: Inces

(Transferred to answer)

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 ?