Cannon.js is there a way to check if an object is colliding with 2 other objects at the same time?

1.8k views Asked by At

I'm using Cannon.js to make a game where a ball bounces of of your head and the sides of the screen have boxes as boundaries. when the ball collides with the head it adds one more to the score. I want to check if the the ball is colliding with the one of the walls and the head at the same time, because when this happens I don't want it to add one to the score. does someone know how to create a check for this?

My code:

const UIManager = require("./UIManager.js");

var playing = false;

// Create cannon world and setting gravity
const world = new CANNON.World();
world.gravity.set(0, -0.52, 0);

// Create sphere body and setting its shape and properties
var mat1 = new CANNON.Material();

// Radius for the ball object
const Radius = 0.05;

// Radius for the head hitbox
const Radius2 = 0.08;

const BallProp = {
    mass: 2,
    position: new CANNON.Vec3(0, 1.1, 0),
    radius: Radius,
    material: mat1,
    shape: new CANNON.Sphere(Radius),
}

// Add the ball to the physics world
const BallBody = new CANNON.Body(BallProp);
world.addBody(BallBody);

// Create a material for the head hitbox
var HeadMaterial = new CANNON.Material();

// Create ground body and settings its shape and properties
const HeadProp = {
    mass: 0,
    position: new CANNON.Vec3(0, 0, 0),
    radius: Radius2,
    material: HeadMaterial,
    shape: new CANNON.Sphere(Radius2),
}
const HeadBody = new CANNON.Body(HeadProp);

// Rotate the ground so it is flat (facing upwards)
const angle = -Math.PI / 2;
const xAxis = new CANNON.Vec3(1, 0, 0);
HeadBody.quaternion.setFromAxisAngle(xAxis, angle);

// Add the hitbox to the physics world
world.addBody(HeadBody);

// Create a new material for the walls
var WallMaterial = new CANNON.Material();

// Create walls and settings its shape and properties
const WallProp1 = {
    mass: 0,
    position: new CANNON.Vec3(-1.19, 0.6, 0),
    material: WallMaterial,
    shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1)),
}

const WallProp2 = {
    mass: 0,
    position: new CANNON.Vec3(1.19, 0.6, 0),
    material: WallMaterial,
    shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1)),
}

const Wall1Body = new CANNON.Body(WallProp1);
const Wall2Body = new CANNON.Body(WallProp2);

// Add the walls to the physics world
world.addBody(Wall1Body);
world.addBody(Wall2Body);

// Create a death plane and settings its shape and properties
const deathProps = {
    mass: 0,
    position: new CANNON.Vec3(0, -0.35, 0),
    shape: new CANNON.Plane(),
}
const DeathBody = new CANNON.Body(deathProps);

// Set the rotation correctly
DeathBody.quaternion.setFromAxisAngle(xAxis, angle);

// Add the deathplane to the physics world
world.addBody(DeathBody);

// Add new settings to the materials
var mat1_ground = new CANNON.ContactMaterial(HeadMaterial, mat1, { friction: 0.0, restitution: 1});
var mat1_wall = new CANNON.ContactMaterial(WallMaterial, mat1, { friction: 0.0, restitution: 0.65});
world.addContactMaterial(mat1_ground);
world.addContactMaterial(mat1_wall);

// Configure time step for Cannon
const fixedTimeStep = 1.0 / 60.0;
const maxSubSteps = 3;
const timeInterval = 30;
let lastTime;

var score = 0;

//checks for collision with the head hitbox
HeadBody.addEventListener("collide",function(e){
    if(playing)
    {
        score++;
        Diagnostics.log("Bounced amount / Score = " + score);
    }
    else
    {
        BallBody.velocity.set(0,0,0);
        BallBody.position.set(0,1,0);
    }
});

//checks for collision with the death plane
DeathBody.addEventListener("collide",function(e){
    if(playing)
    {
        EndGame(score);
    }
    else
    {
        BallBody.velocity.set(0,0,0);
        BallBody.position.set(0,1,0);
    }
});
1

There are 1 answers

0
Samuel On

this might work:
step 1 : create a variable colliding and set it to false
step 2 : set colliding to false every frame
step 3 : in headBody event listener, if it collides with the ball, set colliding to true
step 4 : in deathPlane, check if it collides with the ball and if colliding is true, it means the ball touches both
(you might have to switch, i.e. setting colliding in deathPlane and checking it in headBody)

That's how i used to check if 2 specific items collide, and that check involved checking 2 collisions at same frame + some other verifications.

If you don't know how to check if a body collides with the ball, the condition is event.body.id == ballBody.id with ballBody being the body of the ball use for physical calculations.