What is the best way to implement collisions

Let’s say I have 5 different objects: Player- Player Bullet - Enemy1 - Enemy2 - Enemy Bullet

They all hit each other and I want to register that when it happens, I can use multiple if-else statements but that would get tedious especially with more objects being added:

if ((event.object1.id == "enemyBullet" and event.object2.id == "enemy1") or (event.object1.id == "enemy1" and event.object2.id == "playerBullet"))

So, my question is, is there a more efficient way to test which object hit what. Also I would like to know the difference between : “event.object1, object2” and “event.target, event.other”

Thank you. 

If you want to listen for a collision between any two objects in the system, I would actually reduce that consideration down to which objects are really necessary to listen to. For example, do you actually need to know both when a bullet hits a player and when a player is hit by a bullet? I suspect you really only need to know when the player has been hit by a bullet, which means only the player object needs a collision listener and that means you only need to check for there ‘other’ object being one of the other object types.

If you really do need to listen for when a bullet hits something and when something is hit by a bullet, I would create a collision listener for each object and attach it uniquely. So, bullets would have a collision listener function which can check the type of the other object and behave appropriately. Players would have their own function doing a similar thing - but not checking for other player objects (I assume) and so on.

You would probably create a collision mask so that bullets can’t collide with other bullets and never need to have a condition where they are checked for those collisions.

TL;DR: Create a unique collision listener function for each object type and only check the event.other.name property for valid collisions. Perhaps use a collision filter to avoid receiving collision events which shouldn’t happen.

To add on, object1 and object2 are used in global collision listeners, while target and other are used in local listeners.

 

 

So, in short, you recommend using an event listener attached to each object and use event.other to test rather that using a global collision function, right?

Let’s say I have 5 different objects: Player- Player Bullet - Enemy1 - Enemy2 - Enemy Bullet

They all hit each other and I want to register that when it happens, I can use multiple if-else statements but that would get tedious especially with more objects being added:

if ((event.object1.id == “enemyBullet” and event.object2.id == “enemy1”) or (event.object1.id == “enemy1” and event.object2.id == “playerBullet”))

So, my question is, is there a more efficient way to test which object hit what. Also I would like to know the difference between : “event.object1, object2” and “event.target, event.other”

Thank you. 

<<They all hit each other 

Are you sure?  Player’s own bullet hits player??  Enemy’s own bullet hits enemy???  If not, then as per other replies, step one is to implement filters to eliminate combinations you’ll NEVER care about.

>>is there a more efficient way to test which object hit what. 

Assuming you still end up with a global collision listener, the “more efficient” way to implement these two-way if statements is to pre-sort your objects, quick pseudocode:

local obj1 = event.object1 -- aliases local oid1 = obj1.id local obj2 = event.object2 local oid2 = obj2.id if (oid1 \> oid2) then obj1,oid1,obj2,oid2 = obj2,oid2,obj1,oid1 -- swap-sort by id end

Having done that, you only now need to have “one-way” if statements, because obj1 is always the “lower” id, fe

if (oid1 == "enemy" and oid2 == "player") then -- (oid1=="player" and oid2=="enemy") need not be tested end

Having done that, restructure your if statements into “groups” by oid1

if (oid1 == PLAYER\_ID) then -- test here for all the oid2's than a player can collide with if (oid2 == ENEMY\_BULLET\_ID) then elseif (oid2 == POWERUP\_ID) then elseif (oid2 == MONEY\_ID) then end elseif (oid1 == ENEMY\_ID) then -- test here for all the oid2's than an enemy can collide with end

HTH

If you want to listen for a collision between any two objects in the system, I would actually reduce that consideration down to which objects are really necessary to listen to. For example, do you actually need to know both when a bullet hits a player and when a player is hit by a bullet? I suspect you really only need to know when the player has been hit by a bullet, which means only the player object needs a collision listener and that means you only need to check for there ‘other’ object being one of the other object types.

If you really do need to listen for when a bullet hits something and when something is hit by a bullet, I would create a collision listener for each object and attach it uniquely. So, bullets would have a collision listener function which can check the type of the other object and behave appropriately. Players would have their own function doing a similar thing - but not checking for other player objects (I assume) and so on.

You would probably create a collision mask so that bullets can’t collide with other bullets and never need to have a condition where they are checked for those collisions.

TL;DR: Create a unique collision listener function for each object type and only check the event.other.name property for valid collisions. Perhaps use a collision filter to avoid receiving collision events which shouldn’t happen.

To add on, object1 and object2 are used in global collision listeners, while target and other are used in local listeners.

 

 

So, in short, you recommend using an event listener attached to each object and use event.other to test rather that using a global collision function, right?

Let’s say I have 5 different objects: Player- Player Bullet - Enemy1 - Enemy2 - Enemy Bullet

They all hit each other and I want to register that when it happens, I can use multiple if-else statements but that would get tedious especially with more objects being added:

if ((event.object1.id == “enemyBullet” and event.object2.id == “enemy1”) or (event.object1.id == “enemy1” and event.object2.id == “playerBullet”))

So, my question is, is there a more efficient way to test which object hit what. Also I would like to know the difference between : “event.object1, object2” and “event.target, event.other”

Thank you. 

<<They all hit each other 

Are you sure?  Player’s own bullet hits player??  Enemy’s own bullet hits enemy???  If not, then as per other replies, step one is to implement filters to eliminate combinations you’ll NEVER care about.

>>is there a more efficient way to test which object hit what. 

Assuming you still end up with a global collision listener, the “more efficient” way to implement these two-way if statements is to pre-sort your objects, quick pseudocode:

local obj1 = event.object1 -- aliases local oid1 = obj1.id local obj2 = event.object2 local oid2 = obj2.id if (oid1 \> oid2) then obj1,oid1,obj2,oid2 = obj2,oid2,obj1,oid1 -- swap-sort by id end

Having done that, you only now need to have “one-way” if statements, because obj1 is always the “lower” id, fe

if (oid1 == "enemy" and oid2 == "player") then -- (oid1=="player" and oid2=="enemy") need not be tested end

Having done that, restructure your if statements into “groups” by oid1

if (oid1 == PLAYER\_ID) then -- test here for all the oid2's than a player can collide with if (oid2 == ENEMY\_BULLET\_ID) then elseif (oid2 == POWERUP\_ID) then elseif (oid2 == MONEY\_ID) then end elseif (oid1 == ENEMY\_ID) then -- test here for all the oid2's than an enemy can collide with end

HTH