# Trouble using mouse events to control movement of an object

**URL:** <https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553>\
**Category:** Coding Questions\
**Created:** [March 10, 2020, 9:01am UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553 "2020-03-10T09:01:13Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Irhutchi](https://avatars.discourse-cdn.com/v4/letter/i/ed8c4c/32.png) [@Irhutchi](https://discourse.processing.org/u/Irhutchi)\
**Post date:** [March 10, 2020, 9:01am UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/1 "2020-03-10T09:01:13Z")

</div>

Hi, I am working on a project and am relatively new to programming. I am have setup a ball class outside of main tab and am having trouble with using mouse events inside the ball class which are then called in the draw() function.

I am hoping for some advice on how I can start the ball on the grey box and when the mousePressed a line is drawn to show trajectory. When mouseReleased I want the ball to launch in the opposite direction.

Currently The ball is following the mouse and I don’t know how to implement a mouseReleased into the ball class and call it without looping continuously in draw() function. Any help is much appreciated.

```auto
/* ------------------------ Main Tab ----------------------*/
void setup()
{
   size(450,650);
   background(0);
   stroke(0); 
   
   ball = new Ball(20.0);
   //slider = new TBar(200);
}

Ball ball;
//TBar slider;

void draw()
{
  background(0);
  playingArea();
  
  ball.display();
  ball.moveBall();
  ball.edgeDetection();
  ball.mouseReleased();
  
  //slider.display();
  //slider.update();
  
}

void playingArea() 
{ 
  //centre the all shapes so x and y coord can be easily configured.
  rectMode(CENTER); // Set rectMode to CENTER
  //green
  fill(0,193,66);
  rect(width/2,height*0.5, 400,600);
  fill(150);
  //teeBox
  rect(width/2,height*0.9, 125,40);
  // hole 
  fill(0);
  ellipse(width/2, height*0.1, 20,20);
}

/*----------------------- Ball Class --------------------------------*/
public class Ball 
{
  private float xPos;
  private float yPos;
  private float diameter;
  private float xSpeed = 0.0;
  private float ySpeed = 0.0;
  private float friction = 0.996;
  
  //Constructor method
  public Ball(float diameter)
   {
      setDiameter(diameter);
   }
  
  //Draw the ball on the display window
  public void display()
  {
   fill(255);
   strokeWeight(1);
   ellipse(xPos, yPos, diameter, diameter);
  } 
  
  public void moveBall()
  {
    xPos = xPos + xSpeed;
    yPos = yPos + ySpeed;
    
    //add friction to slow the ball down after shot is taken  
    xSpeed = xSpeed*friction;
    ySpeed = ySpeed*friction;
    
     
    if(mousePressed == true)
    {
      strokeWeight(2);
      line(xPos,yPos,mouseX,mouseY);
    }
      
 
  }
  public void mouseReleased()
  {
    xSpeed = (mouseX - xPos);
    ySpeed = (mouseY - yPos);
    //noLoop();
  }
  
  public void edgeDetection()
  {
    if (xPos > width-30-diameter/2 || xPos < 30+diameter/2) {
      xSpeed *= -1.0;
    }
    if (yPos > height-30-diameter/2 || yPos < 30+diameter/2) {
      ySpeed *= -1.0;
    }

  }
  
  //getter methods
  public float getXPos()
   {  
      return xPos;
   }  

   public float getYPos()
   {
      return yPos;
   }  

   public float getDiameter()
   {
      return diameter;
   }  
   
   //setter methods
   public void setDiameter(float diameter)
   {
     //The ball diameter must be between 20 and height/6 (inclusive)
     if ((diameter >= 20) && (diameter <= height/6)){
        this.diameter = diameter;
     }
     else {
        // If an invalid diameter is passed as a parameter, a default of 20 is imposed.
        // With this animation, if we do not supply a default value for the diameter, a ball may not be 
        // drawn on the display window. Important note: it is not always appropriate to provide a default 
        // value at mutator level; this will depend on your design.
        this.diameter = 20;
     }
   }
  
}

```

---

<div class="post-metadata">

**Author:** ![matheplica](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/matheplica/32/21035_2.png) [@matheplica](https://discourse.processing.org/u/matheplica)\
**Post date:** [March 10, 2020, 11:48am UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/2 "2020-03-10T11:48:52Z")

</div>

Please format yout text, press (Ctrl+shift+c) on a new line  
The setup function is missing, i don’t know where you create your ball

---

<div class="post-metadata">

**Author:** ![Irhutchi](https://avatars.discourse-cdn.com/v4/letter/i/ed8c4c/32.png) [@Irhutchi](https://discourse.processing.org/u/Irhutchi)\
**Post date:** [March 10, 2020, 12:08pm UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/3 "2020-03-10T12:08:14Z")

</div>

@matheplica, thank you for responding so soon.  
I have included the setup function in my post, so should open on Processing.  
How would I create and use a mouse event function in the ball class that will work in my draw() function?

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 11, 2020, 8:39pm UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/4 "2020-03-11T20:39:45Z")

</div>

> [@Irhutchi](#):
>
> if(mousePressed == true) {

This would work inside the class

> [@Irhutchi](#):
>
> void mouseReleased()  
> {

This won’t work inside the class. Solution: have void mouseReleased() also outside the class and call the class’ mouseReleased() from there

---

<div class="post-metadata">

**Author:** ![Irhutchi](https://avatars.discourse-cdn.com/v4/letter/i/ed8c4c/32.png) [@Irhutchi](https://discourse.processing.org/u/Irhutchi)\
**Post date:** [March 13, 2020, 8:31pm UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/5 "2020-03-13T20:31:09Z")

</div>

@Chrisir . I took your advice and moved the mousePressed() & mouseReleased() from the ball class into the main tab. I can now use the mouse to control the movement of the ball.

```auto
/*main tab */
Ball ball;

void setup()
{
   size(450,650);
   stroke(0); 
   
   ball = new Ball(20.0, width/2, height-40);
}
void draw()
{
  background(0,255,0);

  calculateSpeed();
  ball.display();
  ball.moveBall();
  ball.edgeDetection();
  fill(0);
  ellipse(width/2, 40, 30, 30);
  
 if(mousePressed == true)
 {
   strokeWeight(2);
   line(ball.getXPos(),ball.getYPos(),mouseX,mouseY);
 }
 println("speedX" +ball.getXSpeed()+ "speedY" +ball.getYSpeed());
}

void mouseReleased()
{  
  ball.setXSpeed(0);
  ball.setYSpeed(-3);
}

```

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [March 13, 2020, 8:54pm UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/7 "2020-03-13T20:54:47Z")

</div>

sorry last post was garbage, I shall recode the example before presenting.

---

<div class="post-metadata">

**Author:** ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)\
**Post date:** [March 13, 2020, 8:59pm UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/8 "2020-03-13T20:59:28Z")

</div>

Here is a link to my Button class, please note it is still a work in progress, but it all works fine,

[https://www.openprocessing.org/sketch/857717](https://www.openprocessing.org/sketch/857717)

Thats just the button class, if you want to see it in action

> **[paulgoux/project](https://github.com/paulgoux/project)**
>
> Contribute to paulgoux/project development by creating an account on GitHub.

take a look at the selfclick, toggle, latch, etc.

might need to copy it into your favourite editor, as the search isnt great on openprocessing.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 14, 2020, 8:45am UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/9 "2020-03-14T08:45:17Z")

</div>

Nice that you got it working

Remark

> [@Irhutchi](#):
>
> strokeWeight(2);  
> line(ball.getXPos(),ball.getYPos(),mouseX,mouseY);  
> }

You got a lot of usages of variables belonging to the class outside of it. For example in the line() command I quoted.

It would be better to have a function inside the class lineToMouse() and to make the line therein.

Then you just call the function don’t hassle with the variables of the class.

Same for mousePressed (where you didn’t follow my advice exactly)

---

<div class="post-metadata">

**Author:** ![Irhutchi](https://avatars.discourse-cdn.com/v4/letter/i/ed8c4c/32.png) [@Irhutchi](https://discourse.processing.org/u/Irhutchi)\
**Post date:** [March 17, 2020, 10:29am UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/10 "2020-03-17T10:29:52Z")

</div>

After your reply, I went back to review and worked to implement your advice. I found it difficult but I have the mouse events working now (90% at least). Now that I have done it, I realize I overthink these problems and make it harder on myself by using to many variables.  
Can I get your advice on collision detection in my program?

```auto
/*--------- main tab ----------*/
Ball ball;
Hole hole;

void setup()
{
   size(450,650);
   stroke(0); 
   
   ball = new Ball(20.0, width/2, height-40);
   hole = new Hole(30.0, width/2, 40);
}

void draw()
{
  background(0,255,0);

  ball.display();
  ball.moveBall();
  ball.stopBall();
  ball.edgeDetection();
  
  hole.display();
  
  if(mousePressed == true)
  {
    ball.lineToMouse();   
  }
  println("speedX" +ball.getXSpeed()+ "speedY" +ball.getYSpeed());
  
  boolean collision = hitHole(hole, ball);
  if(collision == true)
  {
   hit();
  }
}

void mouseReleased()
{ 
  ball.launchBall();
}

boolean hitHole(Hole hole, Ball ball)
  {
    //checking distance between ball and hole centres.
    float circleDistanceX = abs(ball.getXPos() - hole.getXPos());
    float circleDistanceY = abs(ball.getYPos() - hole.getXPos());
    float circleDistance = sqrt((circleDistanceX*circleDistanceX) + (circleDistanceY*circleDistanceY));
   
    //The distance between ball and hole radius is less tha ball diameter. Collision detected.
    if (circleDistance <= (ball.getDiameter()/2) + (hole.getDiameter()/2))
    {
      return true;
    }
   
    return false;
  }

 //will use laater for collision
  public void hit ()
  {
    //ball.setXSpeed(0);
    //ball.setYSpeed(0);
    //ball.setXPos(225);
    //ball.setYPos(50);
    hole.setXPos(random(50,400));
    hole.setYPos(random(50,400));
  }

/* --------- ball class --------*/
public class Ball 
{
  private float xPos;
  private float yPos;
  private float diameter;
  private float xSpeed;
  private float ySpeed;
  private float friction = 0.96;
  
  //Constructor method
  public Ball(float diameter, float xPos, float yPos)
   {  
     setDiameter(diameter);
     setXPos(xPos);
     setYPos(yPos);
   }
  
  //Draw the ball on the display window
  public void display()
  {
   fill(255);
   strokeWeight(1);
   ellipse(xPos, yPos, diameter, diameter);
  } 
  public void lineToMouse()
  {
    strokeWeight(2);
    line(xPos, yPos,mouseX,mouseY);
  }
  
   public void launchBall()
  {
    xSpeed = mouseX - xPos; //set the speed in the direction of the mouse
    ySpeed = mouseY - yPos; 
  }
  
  public void moveBall()
  {
    xPos = xPos + xSpeed;
    yPos = yPos + ySpeed;
    //add friction to slow the ball down after shot is taken  
    xSpeed = xSpeed*friction;
    ySpeed = ySpeed*friction;
    
  }
  
  public void stopBall()
  {
    if(abs(xSpeed)<0.15 && abs(ySpeed)<0.15)
    {
      xSpeed = 0;
      ySpeed = 0;
    }
  }
  
  public void edgeDetection()
  {
    if (xPos > width-diameter/2 || xPos < diameter/2) {
      xSpeed *= -1.0;
    }
    if (yPos > height-diameter/2 || yPos < diameter/2) {
      ySpeed *= -1.0;
    }

  }
  
  //getter methods
  public float getXPos()
   {  
      return xPos;
   }  

   public float getYPos()
   {
      return yPos;
   }  
    public float getXSpeed()
   {  
      return xSpeed;
   }  

   public float getYSpeed()
   {
      return ySpeed;
   }
   public float getDiameter()
   {
      return diameter;
   }  
   
   //setter methods
   public void setDiameter(float diameter)
   {
     if ((diameter >= 20) && (diameter <= height/6)){
        this.diameter = diameter;
     }
     else {
        this.diameter = 20;
     }
   }
   
   public void setXPos(float xPos)
   {
     if ((xPos >=(diameter/2) && (xPos <= width -(diameter/2)))){
        this.xPos = xPos;
     }
     else {
        this.xPos = width/2;
     }
   }
  public void setYPos(float yPos)
   {
     if ((yPos >(diameter/2) && (yPos <= height -(diameter/2)))){
        this.yPos = yPos;
     }
     else {
        this.yPos = height/2;
     }
   }
   public void setXSpeed(float xSpeed)
   {
     if ((xSpeed >=0 && (xSpeed <= 10))){
        this.xSpeed = xSpeed;
     }
     else {
        this.xSpeed = 5;
     }
   }
  public void setYSpeed(float ySpeed)
   {
     if ((ySpeed >(0) && (ySpeed <= 10))){
        this.ySpeed = ySpeed;
     }
     else {
        this.ySpeed = 5;
     }
   }
}

/*---------- hole class --------*/
public class Hole 
{
  private float xPos;
  private float yPos;
  private float diameter;

  //Constructor method
  public Hole(float diameter, float xPos, float yPos)
   {  
     setDiameter(diameter);
     setXPos(xPos);
     setYPos(yPos);
   }
  
  public void display()
  {
  fill(0);
  ellipse(width/2, 40, 30, 30);
  } 
  
  
  
  //getter methods
  public float getXPos()
  {  
    return xPos;
  }  

  public float getYPos()
  {
    return yPos;
  }  

  public float getDiameter()
  {
    return diameter;
  }  
  
   public void setDiameter(float diameter)
  {
    //The ball diameter must be between 20 and height/6 (inclusive)
    if ((diameter >= 22) && (diameter <= height/6)) {
      this.diameter = diameter;
    } else {
      // value at mutator level; this will depend on your design.
      this.diameter = 22;
    }
  }
  
   public void setXPos(float xPos)
   {
     if ((xPos >=(diameter/2) && (xPos <= width -(diameter/2)))){
        this.xPos = xPos;
     }
     else {
        this.xPos = width/2;
     }
   }
  public void setYPos(float yPos)
   {
     if ((yPos >(diameter/2) && (yPos <= height -(diameter/2)))){
        this.yPos = yPos;
     }
     else {
        this.yPos = height/4;
     }
   }
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 17, 2020, 1:35pm UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/11 "2020-03-17T13:35:47Z")

</div>

for sphere-sphere-reflection:  
see [https://www.processing.org/examples/bouncybubbles.html](https://www.processing.org/examples/bouncybubbles.html)

but remove gravity

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [March 17, 2020, 3:33pm UTC](https://discourse.processing.org/t/trouble-using-mouse-events-to-control-movement-of-an-object/18553/12 "2020-03-17T15:33:30Z")

</div>

I had time to look into this.

I implemented a **new screen** where it is shown (red text) when you had a hit before the game goes on.

- I changed: draw() (now based on boolean `hit`!), hitHole(), hit(), mouseReleased() (now based on boolean `hit`!),

- class Ball: edgeDetection()

- class Hole : display()

**Suggestions**

I would suggest that a hit is only allowed when the ball speed is below a certain speed. When it’s too fast he would skip over it.

At the moment, it is enough to click in the center of the hole. Which is a bit lame though. 😉

Also the ball could get a new position after a hit.

Chrisir

**Entire Code**

```auto
//--------- main tab ----------/
Ball ball;
Hole hole;

boolean hit=false; 

void setup() {
  size(450, 650);
  stroke(0);

  ball = new Ball(20.0, width/2, height-40);
  hole = new Hole(30.0, width/2, 40);
}

void draw() {
  background(0, 255, 0);

  if (hit) {

    hole.display();
    ball.display();

    fill(255, 2, 2); 
    textSize(38);
    text("H I T", width/2-textWidth("H I T")/2, height/2);
    textSize(19);
    text("Click mouse", width/2-textWidth("Click mouse")/2, height/2+33);
  } else {

    ball.display();
    ball.moveBall();
    ball.stopBall();
    ball.edgeDetection();

    hole.display();

    if (mousePressed) {
      ball.lineToMouse();
    }
    // println("speedX" +ball.getXSpeed()+ "; speedY" +ball.getYSpeed());

    boolean collision = hitHole(hole, ball);
    if (collision) {
      hit();
    }
  }
}

void mouseReleased() {

  if (hit) {

    // reset 

    hit=false;

    hole.setXPos(random(50, 400));
    hole.setYPos(random(50, 400));
  } else {
    ball.launchBall();
  }
}

boolean hitHole(Hole hole, Ball ball) {
  //checking distance between ball and hole centres.

  if (dist(ball.getXPos(), ball.getYPos(), hole.getXPos(), hole.getYPos() ) <= hole.getDiameter()/3) {
    println("hit"); 
    ball.fullStop(); 
    return true;
  }

  /*
  float circleDistanceX = abs(ball.getXPos() - hole.getXPos());
   float circleDistanceY = abs(ball.getYPos() - hole.getXPos());
   float circleDistance = sqrt((circleDistanceX*circleDistanceX) + (circleDistanceY*circleDistanceY));
   
   //The distance between ball and hole radius is less tha ball diameter. Collision detected.
   if (circleDistance <= (ball.getDiameter()/2) + (hole.getDiameter()/2)) {
   return true;
   }
   */
  return false;
}

//will use later for collision
public void hit ()
{
  //ball.setXSpeed(0);
  //ball.setYSpeed(0);
  //ball.setXPos(225);
  //ball.setYPos(50);

  hit=true; 
  //hole.setXPos(random(50, 400));
  //hole.setYPos(random(50, 400));
}

/* --------- ball class --------*/
public class Ball
{
  private float xPos;
  private float yPos;
  private float diameter;
  private float xSpeed;
  private float ySpeed;
  private float friction = 0.96;

  //Constructor method
  public Ball(float diameter, float xPos, float yPos)
  {
    setDiameter(diameter);
    setXPos(xPos);
    setYPos(yPos);
  }

  //Draw the ball on the display window
  public void display()
  {
    fill(255);
    strokeWeight(1);
    ellipse(xPos, yPos, diameter, diameter);
  }
  public void lineToMouse()
  {
    strokeWeight(2);
    line(xPos, yPos, mouseX, mouseY);
  }

  public void launchBall()
  {
    xSpeed = mouseX - xPos; //set the speed in the direction of the mouse
    ySpeed = mouseY - yPos;
  }

  public void moveBall()
  {
    xPos = xPos + xSpeed;
    yPos = yPos + ySpeed;
    //add friction to slow the ball down after shot is taken
    xSpeed = xSpeed*friction;
    ySpeed = ySpeed*friction;
  }

  public void stopBall()
  {
    if (abs(xSpeed)<0.15 && abs(ySpeed)<0.15)
    {
      xSpeed = 0;
      ySpeed = 0;
    }
  }

  void fullStop() {
    xSpeed = 0;
    ySpeed = 0;
  }

  public void edgeDetection()
  {
    if (xPos > width-diameter/2 ) {
      xSpeed = - abs(xSpeed);
    }

    if ( xPos < diameter/2) {
      xSpeed = abs(xSpeed);
    }

    // -------------
    if (yPos > height-diameter/2 ) {
      ySpeed = - abs(ySpeed);
    }

    if ( yPos < diameter/2) {
      ySpeed = abs(ySpeed);
    }
  }//func 

  //getter methods
  public float getXPos()
  {
    return xPos;
  }

  public float getYPos()
  {
    return yPos;
  }
  public float getXSpeed()
  {
    return xSpeed;
  }

  public float getYSpeed()
  {
    return ySpeed;
  }
  public float getDiameter()
  {
    return diameter;
  }

  //setter methods
  public void setDiameter(float diameter)
  {
    if ((diameter >= 20) && (diameter <= height/6)) {
      this.diameter = diameter;
    } else {
      this.diameter = 20;
    }
  }

  public void setXPos(float xPos)
  {
    if ((xPos >=(diameter/2) && (xPos <= width -(diameter/2)))) {
      this.xPos = xPos;
    } else {
      this.xPos = width/2;
    }
  }
  public void setYPos(float yPos)
  {
    if ((yPos >(diameter/2) && (yPos <= height -(diameter/2)))) {
      this.yPos = yPos;
    } else {
      this.yPos = height/2;
    }
  }
  public void setXSpeed(float xSpeed)
  {
    if ((xSpeed >=0 && (xSpeed <= 10))) {
      this.xSpeed = xSpeed;
    } else {
      this.xSpeed = 5;
    }
  }
  public void setYSpeed(float ySpeed)
  {
    if ((ySpeed >(0) && (ySpeed <= 10))) {
      this.ySpeed = ySpeed;
    } else {
      this.ySpeed = 5;
    }
  }
}

//---------- hole class --------/
public class Hole
{
  private float xPos;
  private float yPos;

  private float diameter;

  //Constructor method
  public Hole(float diameter, float xPos, float yPos)
  {
    setDiameter(diameter);
    setXPos(xPos);
    setYPos(yPos);
  }

  public void display()
  {
    fill(0);
    ellipse(xPos, yPos, 30, 30);
  }

  //getter methods
  public float getXPos()
  {
    return xPos;
  }

  public float getYPos()
  {
    return yPos;
  }

  public float getDiameter()
  {
    return diameter;
  }

  public void setDiameter(float diameter)
  {
    //The ball diameter must be between 20 and height/6 (inclusive)
    if ((diameter >= 22) && (diameter <= height/6)) {
      this.diameter = diameter;
    } else {
      // value at mutator level; this will depend on your design.
      this.diameter = 22;
    }
  }

  public void setXPos(float xPos)
  {
    if ((xPos >=(diameter/2) && (xPos <= width - (diameter/2)))) {
      this.xPos = xPos;
    } else {
      this.xPos = width/2;
    }
  }
  public void setYPos(float yPos)
  {
    if ((yPos >(diameter/2) && (yPos <= height -(diameter/2)))) {
      this.yPos = yPos;
    } else {
      this.yPos = height/4;
    }
  }
}
//

```
