Collision problem I really need your help ... begging

hey i am really struggeling with this collision issue
I want to make the white cell eat the bloodcell when they collide can u please help me

let MAX_NUM = 50;
let circles = [];


class Circle {
    constructor(x, y, ) {
        this.x = x;
        this.y = y;
        this.speedX = random(-15, 15);
        this.speedY = random(-14, 14);
        this.width = random(25, 50);
        this.height = random(25, 50);
        this.color = color(random(255), random(20), random(20), 100);
    }
    checkBoundary() {
        if (this.x < 0) {
            this.x = 0;
            this.speedX *= -1;
        }
        if (this.x > width) {
            this.x = width;
            this.speedX *= -1;
        }
        if (this.y < 0) {
            this.y = 0;
            this.speedY *= -1;
        }
        if (this.y > height) {
            this.y = height;
            this.speedY *= -1;
        }
    }
    update() {



        this.x += this.speedX;
        this.y += this.speedY;

    }


overlapping(circles) {
    for (let i = 0; i < circles.length; i++) {
        if (dist(this.location.x, this.location.y, objects[i].location.x, objects[i].location.y) < objects[i].size / 2) {
            this.health -= 255;
            creatures.pop()
        }
    }
}
    



    display() {
        push();
        fill(this.color);
        ellipse(this.x, this.y, this.width, this.height);
        pop();
    }

    boem() {

        if (this.x > width / 2) {
            this.speedX = (this.x - width / 2) / (height / 2 - this.y);
        } else {
            this.speedX = -(this.x - width / 2) / (height / 2 - this.y);
        }


        if (this.y > width / 2) {
            this.speedY = -(height / 2 - this.y) / (height / 2 - this.y);
        } else {
            this.speedY = (height / 2 - this.y) / (height / 2 - this.y);
        }




    }




}

class WhiteCell {
    constructor(x, y) {
        this.x = x;
        this.y = y;
        this.h = 50;
        this.w = 50;
    }
    verschijn() {
        fill('white')
        ellipse(this.x, this.y, this.w, this.h);
    }
    moveLinks() {
        this.x -= 5;
    }
    moveRechts() {
        this.x += 5;
    }
    moveUp() {
        this.y -= 5;
    }
    moveDown() {
        this.y += 5;
    }




}




let teller = 0;
let links = false;
let rechts = false;
let down = false;
let up = false;

function setup() {
    createCanvas(800, 800);
    background(0);
    noStroke();
    witte = new WhiteCell(400, 600);
}

function draw() {
    background(0, 50);  


    for (let i = 0; i < circles.length; i++) {
        circles[i].checkBoundary();
        circles[i].update();
        circles[i].display();

        if (teller === 20) {
            circles.splice(1)
            background('darkred')
            teller = 0;
        }


    }



    fill('gray')
    rect(10, 10, 780, 20)
    fill('red');
    rect(10, 10, 39 * teller, 20);
    fill('white')
    textSize(10)
    text("POWERBAR", 15, 25)
    fill('white')
    textSize(20);
    text('PRESS R TO USE POWER', 10, 60)
    text('FILL THE BAR BY CLICKING ON THE SCREEN TO CENTER THE CELLS AND LET THEM IMPLODE', 10, 100, 780);
    text('USE ARROWS TO MOVE THE BLOODCELL', 10, 200)



    witte.verschijn();
    if (keyIsDown(RIGHT_ARROW)) {
        witte.moveRechts();
    }
    if (keyIsDown(DOWN_ARROW)) {
        witte.moveDown();
    }
    if (keyIsDown(UP_ARROW)) {
        witte.moveUp()
    }
    if (keyIsDown(LEFT_ARROW)) {
        witte.moveLinks();
    }




}

function mousePressed() {
    if (circles.length < MAX_NUM) {
        for (let i = 0; i < 5; i++) {
            circles.push(new Circle(mouseX, mouseY));

        }
    } else {
        circles.forEach(item => item.boem());
        teller += 1;




    }
}

function keyPressed() {
    if (key == "r") {
        for (let i = 0; i < circles.length; i++) {

            circles[i].speedX = random(-2, 2) * teller;
            circles[i].speedY = random(-2, 2) * teller;

        }
        teller = 0;

    }
}

function keyIsDown() {
    if (keyCode === LEFT_ARROW) {

        witte.moveLinks();
    }
    if (keyCode === UP_ARROW) {
        witte.moveUp();
    }
    if (keyCode === DOWN_ARROW) {
        witte.moveDown();
    }
    if (keyCode === RIGHT_ARROW) {
        witte.moveRechts();
    }
}

Seems like those blood cells are represented by the class Circle, right?

Both classes WhiteCell & Circle are drawn to the canvas using ellipse().

Therefore you have a case of circle/circle collision:
CrHallberg.com/CollisionDetection/Website/circle-circle.html

1 Like

hey tnx for the quick reply i should have mentioned that I am obligated to use OOP in the assignment any ideas on how to implement it in that way kind regards

i tried fixing it using your method without oop and it didn’t work could you maybe try it and see if it works ?

  • You could write a parent class which would serve as a base for both child classes WhiteCell & Circle.
  • Let’s call that base class Cell.
  • Also rename class Circle to BloodCell so it’s more coherent.
  • That parent base class would include properties which both classes WhiteCell & now BloodCell have in common.
  • Like their positions, dimensions, speeds and colors.
  • Besides regular properties we can also add to the base class sharable methods like display(), update(), isColliding(), etc.
  • And of course a sharable base constructor() which the child classes would invoke via keyword super:
class Cell {
  constructor(pos, dim, vel, col) {
    this.pos = createVector().set(pos);
    this.dim = createVector().set(dim);
    this.vel = createVector().set(vel);
    this.col = color(col);
  }

  display() {
    const { pos: { x, y }, dim: { x: w, y: h }, col } = this;
    fill(col).ellipse(x, y, w, h);
    return this;
  }

  update() {
    this.pos.add(this.vel);
    return this;
  }

  isColliding(cell) {
    const
      { pos: { x, y }, dim: { x: w, y: h } } = this,
      { pos: { x: cx, y: cy }, dim: { x: cw, y: ch } } = cell,

      rw = w >> 1, rh = h >> 1,
      crw = cw >> 1, crh = ch >> 1,
      radiiW = rw + crw, radiiH = rh + crh,

      dx = cx - x, dy = cy - y,
      distance = sq(dx) / sq(radiiW) + sq(dy) / sq(radiiH);

    return distance < 1;
  }
}

P.S.: I dunno whether method Cell::isColliding() is even close to be of any use b/c I’m not good at trigonometry and the collision link states:

… the math for ellipse collision is actually quite complicated.

If those BloodCell objects had a circle() shape instead of ellipse() the collision math would be much easier.

Anyways, after you have a parent base class you need to use keyword extends when defining your child classes:

For example your class WhiteCell would be like this now:

class WhiteCell extends Cell {
  constructor(x, y) {
    const
      pos = createVector(x, y),
      dim = createVector(50, 50),
      vel = createVector(5, 5),
      col = 'white';

    super(pos, dim, vel, col);
  }
}

And following the same model, class BloodCell should start like this:

class BloodCell extends Cell {
  constructor(x, y) {
    const
      pos = createVector(x, y),
      dim = createVector(random(25, 50), random(25, 50)),
      vel = createVector(random(-15, 15), random(-14, 14)),
      col = color(random(255), random(20), random(20), 100);

    super(pos, dim, vel, col);
  }
}

Hope those examples should kick-start you in the right OOP direction.

1 Like

hey man while you i asked for the oop solution i tried the method without oop but it isn’t working for me do u know why

the help is much appreciated


class Circle {
    constructor(x, y, ) {
        this.x = x;
        this.y = y;
        this.speedX = random(-15, 15);
        this.speedY = random(-14, 14);
        this.width = 20;
        this.color = color(random(255), random(20), random(20), 100);
    }
    checkBoundary() {
        if (this.x < 0) {
            this.x = 0;
            this.speedX *= -1;
        }
        if (this.x > width) {
            this.x = width;
            this.speedX *= -1;
        }
        if (this.y < 0) {
            this.y = 0;
            this.speedY *= -1;
        }
        if (this.y > height) {
            this.y = height;
            this.speedY *= -1;
        }
    }
    update() {
        this.x += this.speedX;
        this.y += this.speedY;
    }

    display() {
        push();
        fill(this.color);
        ellipse(this.x, this.y, this.width, this.width);
        pop();
    }

    boem() {
        if (this.x > width / 2) {
            this.speedX = (this.x - width / 2) / (height / 2 - this.y);
        } else {
            this.speedX = -(this.x - width / 2) / (height / 2 - this.y);
        }

        if (this.y > width / 2) {
            this.speedY = -(height / 2 - this.y) / (height / 2 - this.y);
        } else {
            this.speedY = (height / 2 - this.y) / (height / 2 - this.y);
        }
    }
}
class WhiteCell {
    constructor(x, y) {
        this.x = x;
        this.y = y;
        this.size = 50;
    }

    verschijn() {
        fill('white')
        circle(this.x, this.y, this.size);
    }
    moveLinks() {
        this.x -= 5;
    }
    moveRechts() {
        this.x += 5;
    }
    moveUp() {
        this.y -= 5;
    }
    moveDown() {
        this.y += 5;
    }
}

let teller = 0;
let witte;
let MAX_NUM = 50;
let circles = [];

function setup() {
    createCanvas(800, 800);
    background(0);
    noStroke();
    witte = new WhiteCell(400, 600);
}

function draw() {
    background(0, 50);
    for (let i = 0; i < circles.length; i++) {
        circles[i].checkBoundary();
        circles[i].update();
        circles[i].display();

        if (teller === 20) {
            circles.splice(1)
            background('darkred')
            teller = 0;
        }
    }

    fill('gray')
    rect(10, 10, 780, 20)
    fill('red');
    rect(10, 10, 39 * teller, 20);
    fill('white')
    textSize(10)
    text("POWERBAR", 15, 25)
    fill('white')
    textSize(20);
    text('PRESS R TO USE POWER', 10, 60)
    text('FILL THE BAR BY CLICKING ON THE SCREEN TO CENTER THE CELLS AND LET THEM IMPLODE', 10, 100, 780);
    text('USE ARROWS TO MOVE THE BLOODCELL', 10, 200)



    witte.verschijn();
    if (keyIsDown(RIGHT_ARROW)) {
        witte.moveRechts();
    }
    if (keyIsDown(DOWN_ARROW)) {
        witte.moveDown();
    }
    if (keyIsDown(UP_ARROW)) {
        witte.moveUp()
    }
    if (keyIsDown(LEFT_ARROW)) {
        witte.moveLinks();
    }
    let hit = circleCircle(witte.x,witte.y, witte.size / 2, circles.forEach(element => element.x), circles.forEach(element => element.y), circles.forEach(element => element.width) /2);
   
    if (hit) {
        console.log("bump")
    }
    else {
        console.log("nobump")
    }
}

function mousePressed() {
    if (circles.length < MAX_NUM) {
        for (let i = 0; i < 5; i++) {
            circles.push(new Circle(mouseX, mouseY));

        }
    } else {
        circles.forEach(item => item.boem());
        teller += 1;
    }
}

function keyPressed() {
    if (key === "r") {
        for (let i = 0; i < circles.length; i++) {

            circles[i].speedX = random(-2, 2) * teller;
            circles[i].speedY = random(-2, 2) * teller;

        }
        teller = 0;
    }
}

function keyIsDown() {
    if (keyCode === LEFT_ARROW) {
        witte.moveLinks();
    }
    if (keyCode === UP_ARROW) {
        witte.moveUp();
    }
    if (keyCode === DOWN_ARROW) {
        witte.moveDown();
    }
    if (keyCode === RIGHT_ARROW) {
        witte.moveRechts();
    }
}
function circleCircle(x1, y1, s1, x2, y2, s2){
    let distX = x1 - x2;
    let distY = y1 - y2;
    let distance = sqrt((distX*distX) + (distY*distY));

    if (distance <= s1+s2) {
        return true;
    }
    return false;
}

The statement above doesn’t make any sense b/c the method Array::forEach() returns undefined:

So the 3 latest arguments you pass to function circleCircle() are actually just undefined.

Instead you need to define a for () loop to iterate over the array circles[].

I’ve created this function which does just that:

function gotHit() {
  for (const { x, y, width } of circles)
    if (circleCircle(witte.x, witte.y, witte.size >> 1, x, y, width >> 1))
      return true;
}

hey tnx a lot for al the help could you help me with implementing this in the code so it works when I tried it it didn’t work but it is probs me who is doing it wrong