Search code examples
javascriptclassprocessingp5.js

Referencing different objects in a class depending on user input


I'm trying to create a very basic physics simulation in p5.js and I am using a class to create multiple instances of the shapes (which are currently all circles), I have a function that checks if the user clicks inside the area of a circle and if so allows them to drag it around but I ran into a problem. I need to have the program work out which object it is hovering but I'm not sure how I would do so, below I have the function working for only the first object (obj1). can I do something like {classname}.posX instead?

function whilePressed()
    {
      if (Math.pow(mouseX-obj1.posX,2)+(Math.pow(mouseY-obj1.posY,2))<=(Math.pow(obj1.size/2,2)) | grabbed == true)
        {
          grabbed = true;
          if (firstGrab == true)
          {
            difX = (obj1.posX-mouseX);
            difY = (obj1.posY-mouseY);
            firstGrab = false;
          }
          obj1.posX = mouseX+difX;
          obj1.posY = mouseY+difY;
        }
    }

below is the class (the draw function has a switch statement in it because I used to have a square as well but decided to get a circle working before implementing a square)

class primitive
{
  constructor()
  {
    this.size = 50;
    this.posX = canvasSize/2;
    this.posY = canvasSize/2;
    this.velX = 0;
    this.velY = 0;
    this.terminalVel = 15;
  }
  
  pos(x,y)
  {
    this.posX = x;
    this.posY = y;
  }
  
  draw(shape = 'circle')
  {
    stroke(168,198,159);
    fill(204,226,163);
    switch (shape)
    {
      case 'circle':
        circle(this.posX,this.posY,this.size);
      break;
    }
  }
  
  gravity()
  {
    if (this.velY < this.terminalVel)
    {
      this.velY = (this.velY+1);  
    }
    else
    {
      this.velY = 20;
    }
    this.posY = this.posY+this.velY;
    
    if (this.posY > groundLevel-(this.size/2))
    {
      this.posY = groundLevel-(this.size/2);
      this.velY = 0;
    }
  }
}

Solution

  • You can create a static method on the primitive class like so: First, create an array which has all the instances of the class in it. This is the code:
    Remember: I added the parameter name to the constructor. That means when creating an instance do it like so:

    var foo = new primitive("foo");
    
    var PRIMITIVES = [];
    // ...
    constructor(name)
      {
        this.name = name;
        this.size = 50;
        this.posX = canvasSize/2;
        this.posY = canvasSize/2;
        this.velX = 0;
        this.velY = 0;
        this.terminalVel = 15;
        PRIMITIVES.push(name);
      }
    

    Now, using the same mouse find principle, you can create a static method that finds and return the right instance.

    static findInstance(mouseX, mouseY) {
      for (var i = 0; i < PRIMITIVES.length; i++) 
        {
          obj = window[PRIMITIVES[i]];
          if (Math.pow(mouseX-obj.posX,2)+(Math.pow(mouseY-obj.posY,2))<=(Math.pow(obj.size/2,2)))
            {
              return obj;
            }
        }
      
    }
    

    Then, you can call primitive.findInstance(mouseX, mouseY), and it will return the right instance. If this doesn't work, please comment. I hope this helped you.