# Help needed, bounce, clickable area

**URL:** <https://discourse.processing.org/t/help-needed-bounce-clickable-area/4011>\
**Category:** Coding Questions\
**Created:** [October 1, 2018, 10:38am UTC](https://discourse.processing.org/t/help-needed-bounce-clickable-area/4011 "2018-10-01T10:38:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![SolDrakibane](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/soldrakibane/32/1810_2.png) [@SolDrakibane](https://discourse.processing.org/u/SolDrakibane)\
**Post date:** [October 1, 2018, 10:38am UTC](https://discourse.processing.org/t/help-needed-bounce-clickable-area/4011/1 "2018-10-01T10:38:41Z")

</div>

Alright i have two issues at hand with the code below.

1. Bounces  
Bouncing the bullseye works with the code below in the horizontal X. When i change that to Y it also works.  
How can i make X and Y work by making it bounce to the edges of the window? Cause when i do certain maths on them it sometimes works but always ends up flying out of the screen.

2. Clickable area  
The bullseye requires the circles within to give different scores. For the center being the highest score and the score decreasing the further you miss the center. I can’t figure this out, i’ve tried to give the X,Y, Width and Height dimensions of those circles different scores. Which kind of works but it overrides the others or counts them up (so if i click the middle i get +10 instead of +4 cuz the others give +1, +2 + 3.

```auto
int 
  circleSize, 
  rectX, rectY, rectSize, 
  scoreX, scoreY, score, mis, bonus, 
  red, white, green;

int[] bonusArray = new int[4];

float circleX, circleY, snelheid;

boolean 
  start;

void setup() {
  size(500, 500); 
  smooth(8);
  background(5);
  circleX = width/2;
  circleY = height/2;
  circleSize = 40;
  rectX = width/2;
  rectY = height;
  rectSize = 80;
  red = color(255, 0, 0);
  white = color(255);
  green = color(0, 255, 0);
  start = false;
  scoreX = width/50;
  scoreY = height/20;
  score = 0;
  mis = 0;
  bonus = 0;
  snelheid = random(5, 8);
  bonusArray[0] = 0;
  bonusArray[1] = 1;
  bonusArray[2] = 2;
  bonusArray[3] = 3;
}

void draw() {
  clear();
  noStroke();
  scoreText();
  buttonText();
  bullseye();
  println(snelheid);
}

void scoreText() {
  textSize(18);
  text("Score: " + score, scoreX, scoreY);
  text("Aantal mis: " + mis, scoreX*11, scoreY);
  text("Bonus: " + bonusArray[bonus], scoreX*26, scoreY);
}

void bullseye() {
  for (int circles = circleSize; circles > 0; circles -= 20) {
    fill(red);
    ellipse(circleX, circleY, circles, circles);
    fill(white);
    ellipse(circleX, circleY, circles-10, circles-10);
  }
  if (start) {
    circleX = circleX + snelheid;
  } else if (!start) {
    circleX = width/2;
  }
  if (circleX > width || circleX < 0) {
    snelheid = snelheid * -1.010;
  }
}

void buttonText() {
  noStroke();
  fill(green);
  rect(rectX-rectSize/2, rectY-rectSize/2, rectSize, rectSize/2);
  fill(red);
  textSize(24);
  if (!start) {    
    text("Start", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  } else if (start) {
    text("Stop", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  } else if (!start) {
    text("Start", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  }
}

void mousePressed() {
  if (mouseX > rectX-rectSize/2 && mouseX < rectX-rectSize/2 + rectSize &&
    mouseY > rectY-rectSize/2 && mouseY < rectY-rectSize/2 + rectSize/2) {
    start = ! start;
  } 
  if (mouseX > circleX-circleSize/2 && mouseX < circleX + circleSize/2 &&
    mouseY > circleY-circleSize/2 && mouseY < circleY + circleSize/2) {
    score += 1;
    bonus += 1;
    if (bonus > 3) {
      bonus = 3;
    }
    if (bonus == 1) score = score+=0;
    if (bonus == 2) score = score+=1;
    if (bonus >= 3) score = score+=2;
  } else if (mouseX > rectX-rectSize/2 && mouseX < rectX-rectSize/2 + rectSize &&
    mouseY > rectY-rectSize/2 && mouseY < rectY-rectSize/2 + rectSize/2) {
    score = 0;
    bonus = 0;
    mis = 0;
  } else {
    mis += 1;
    bonus = 0;
  }
}

```

**The code below is where i tried step 1 and 2 and failed.**

```auto
int 
  circleSize, 
  rectX, rectY, rectSize, 
  scoreX, scoreY, score, mis, bonus, 
  red, white, green;

int[] bonusArray = new int[4];

float circleX, circleY, snelheid;

boolean 
  start;

void setup() {
  size(500, 500); 
  smooth(8);
  background(5);
  circleX = width/2;
  circleY = height/2;
  circleSize = 40;
  rectX = width/2;
  rectY = height;
  rectSize = 80;
  red = color(255, 0, 0);
  white = color(255);
  green = color(0, 255, 0);
  start = false;
  scoreX = width/50;
  scoreY = height/20;
  score = 0;
  mis = 0;
  bonus = 0;
  snelheid = random(5, 10);
  bonusArray[0] = 0;
  bonusArray[1] = 1;
  bonusArray[2] = 2;
  bonusArray[3] = 3;
}

void draw() {
  clear();
  noStroke();
  scoreText();
  buttonText();
  bullseye();
  //println(snelheid);
}

void scoreText() {
  textSize(18);
  text("Score: " + score, scoreX, scoreY);
  text("Aantal mis: " + mis, scoreX*11, scoreY);
  text("Bonus: " + bonusArray[bonus], scoreX*26, scoreY);
}

void bullseye() {
  for (int circles = circleSize; circles > 0; circles -= 20) {
    fill(red);
    ellipse(circleX, circleY, circles, circles);
    fill(white);
    ellipse(circleX, circleY, circles-10, circles-10);
  }
  if (start) {
    circleX = circleX + snelheid;
    circleY = circleY + snelheid;
  } else if (!start) {
    circleX = width/2;
  }
  if (circleX > width || circleX < 0 ) {
    snelheid = snelheid * -1.010;
  }
  if (circleY > height || circleY < 0 ) {
    snelheid = snelheid * -1.010;
  }
}

void buttonText() {
  noStroke();
  fill(green);
  rect(rectX-rectSize/2, rectY-rectSize/2, rectSize, rectSize/2);
  fill(red);
  textSize(24);
  if (!start) {    
    text("Start", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  } else if (start) {
    text("Stop", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  } else if (!start) {
    text("Start", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  }
}

void mousePressed() {
  if (mouseX > rectX-rectSize/2 && mouseX < rectX-rectSize/2 + rectSize &&
    mouseY > rectY-rectSize/2 && mouseY < rectY-rectSize/2 + rectSize/2) {
    start = ! start;
  } 
  if (mouseX > circleX-circleSize/2 && mouseX < circleX + circleSize/2 &&
    mouseY > circleY-circleSize/2 && mouseY < circleY + circleSize/2 ) {
    score += 1;
    bonus += 1;
    println(score, bonus);
  } 
  if (mouseX > circleX-circleSize/2 && mouseX < circleX + circleSize/3 &&
    mouseY > circleY-circleSize/2 && mouseY < circleY + circleSize/3 ) {
    score += 2;
    bonus += 1;
  } 
  if (mouseX > circleX-circleSize/2 && mouseX < circleX + circleSize/4 &&
    mouseY > circleY-circleSize/2 && mouseY < circleY + circleSize/4 ) {
    score += 3;
    bonus += 1;
  } 
  if (mouseX > circleX-circleSize/2 && mouseX < circleX + circleSize/6 &&
    mouseY > circleY-circleSize/2 && mouseY < circleY + circleSize/6 ) {
    score += 4;
    bonus += 1;
  } 
  if (mouseX > rectX-rectSize/2 && mouseX < rectX-rectSize/2 + rectSize &&
    mouseY > rectY-rectSize/2 && mouseY < rectY-rectSize/2 + rectSize/2) {
    score = 0;
    bonus = 0;
    mis = 0;
  } else {
    mis += 1;
    bonus = 0;
  }
  if (bonus > 3) {
    bonus = 3;
  }
  if (bonus == 1) score = score+=0;
  if (bonus == 2) score = score+=1;
  if (bonus >= 3) score = score+=2;
}

```

---

<div class="post-metadata">

**Author:** ![Ov3rM1nD](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ov3rm1nd/32/1756_2.png) [@Ov3rM1nD](https://discourse.processing.org/u/Ov3rM1nD)\
**Post date:** [October 1, 2018, 3:26pm UTC](https://discourse.processing.org/t/help-needed-bounce-clickable-area/4011/2 "2018-10-01T15:26:15Z")

</div>

All right, let’s start with your **first question** :  
You should assign a speed variable for each axis, in order to control the horizontal and vertical movements independently:  
`float speedX, speedY;`  
and assign them random values as well… (inside setup):

```auto
  speedX = random(5, 10);
  speedY = random(5, 10);

```

Then, in order to force the target to always remain within the boundaries of the canvas, you have to update the position of the circle, in the exact frame in which it touches the side of the canvas, before reversing the direction of its movement. So you prevent your program from incurring into some glitch.

```auto
  if (start) {
    circleX = circleX + speedX;
    circleY = circleY + speedY;
  } else {
    circleX = width/2;
    circleY = height/2;
  }
  if (circleX - circleSize/2 <= 0) {
    circleX = circleSize/2;
    speedX = speedX * -1.010;
  }
  if (circleX + circleSize/2 >= width) {
    circleX = width - circleSize/2;
    speedX = speedX * -1.010;
  }
  if (circleY - circleSize/2 <= 0) {
    circleY = circleSize/2;
    speedY = speedY * -1.010;
  }
  if (circleY + circleSize/2 >= height) {
    circleY = height - circleSize/2;
    speedY = speedY * -1.010;
  }

```

There’s an outstanding explanation written by @quark that you can find [here](http://lagers.org.uk/blog/?p=122).

Now, for your **second question** , we have to make some major changes.  
You should always store the distance between the mouse and the center of the circle in a variable. For this you can use the `dist()` method. See [dist()](https://processing.org/reference/dist_.html).

```auto
float d = dist(mouseX, mouseY, circleX, circleY);

```

Then, in order to assign a score to each ring of the target, you can make use of the `map()` function, and thus avoid annoying calculations. With this method you can re-map any number from one range to another. See [map()](https://processing.org/reference/map_.html).  
You want to do this only if the mouse is inside the target:

```auto
  if (d <= circleSize/2) score += (int)map(d, circleSize/2, 0, minScore, maxScore+1);

```

Put everything together, your code would look like this: (with some minor corrections here and there)

```auto
int 
  circleSize, 
  rectX, rectY, rectSize, 
  scoreX, scoreY, score, mis, bonus, 
  red, white, green;

int[] bonusArray = new int[4];

float circleX, circleY;
float speedX, speedY;

boolean start;

void setup() {
  size(500, 500); 
  smooth(8);
  background(5);
  circleX = width/2;
  circleY = height/2;
  circleSize = 40;
  rectX = width/2;
  rectY = height;
  rectSize = 80;
  red = color(255, 0, 0);
  white = color(255);
  green = color(0, 255, 0);
  start = false;
  scoreX = width/50;
  scoreY = height/20;
  score = 0;
  mis = 0;
  bonus = 0;

  speedX = random(5, 10);
  speedY = random(5, 10);
  
  bonusArray[0] = 0;
  bonusArray[1] = 1;
  bonusArray[2] = 2;
  bonusArray[3] = 3;
}

void draw() {
  clear();
  noStroke();
  scoreText();
  buttonText();
  bullseye();
}

void scoreText() {
  textSize(18);
  text("Score: " + score, scoreX, scoreY);
  text("Aantal mis: " + mis, scoreX*11, scoreY);
  text("Bonus: " + bonusArray[bonus], scoreX*26, scoreY);
}

void bullseye() {
  for (int circles = circleSize; circles > 0; circles -= 20) {
    fill(red);
    ellipse(circleX, circleY, circles, circles);
    fill(white);
    ellipse(circleX, circleY, circles-10, circles-10);
  }
  if (start) {
    circleX = circleX + speedX;
    circleY = circleY + speedY;
  } else {
    circleX = width/2;
    circleY = height/2;
  }
  if (circleX - circleSize/2 <= 0) {
    circleX = circleSize/2;
    speedX = speedX * -1.010;
  }
  if (circleX + circleSize/2 >= width) {
    circleX = width - circleSize/2;
    speedX = speedX * -1.010;
  }
  if (circleY - circleSize/2 <= 0) {
    circleY = circleSize/2;
    speedY = speedY * -1.010;
  }
  if (circleY + circleSize/2 >= height) {
    circleY = height - circleSize/2;
    speedY = speedY * -1.010;
  }
}

void buttonText() {
  noStroke();
  fill(green);
  rect(rectX-rectSize/2, rectY-rectSize/2, rectSize, rectSize/2);
  fill(red);
  textSize(24);

  if (start) {
    text("Stop", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  } else {
    text("Start", rectX-rectSize/3, rectY-rectSize+rectSize/6*5);
  }
}

void mousePressed() {
  int minScore = 1;
  int maxScore = 4;
  float d = dist(mouseX, mouseY, circleX, circleY);

  if (d <= circleSize/2) { 
    score += (int)map(d, circleSize/2, 0, minScore, maxScore+1);
    bonus++;
  } else {
    mis += 1;
    bonus = 0;
  }
  if (bonus > 3) bonus = 3;
  //score = score + bonusArray[bonus];

  if (mouseX > rectX-rectSize/2 && mouseX < rectX-rectSize/2 + rectSize &&
    mouseY > rectY-rectSize/2 && mouseY < rectY-rectSize/2 + rectSize/2) {
    score = 0;
    bonus = 0;
    mis = 0;
    start = !start;
  }
}

```

I commented the line `//score = score + bonusArray[bonus];` because I do not know if this is what you intend to do with the bonusArray.

---

<div class="post-metadata">

**Author:** ![SolDrakibane](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/soldrakibane/32/1810_2.png) [@SolDrakibane](https://discourse.processing.org/u/SolDrakibane)\
**Post date:** [October 2, 2018, 10:10pm UTC](https://discourse.processing.org/t/help-needed-bounce-clickable-area/4011/3 "2018-10-02T22:10:09Z")

</div>

Oh my god this is amazing! The way you explained it is great. I’m having trouble understanding map() at the moment but i’m probably going to get how it works eventually when i experiment with it. The best part is that i compared your code with the one i had and saw what you corrected. This allowed me to understand the if statement better. Great learning material! Thanks again for your time and effort @Ov3rM1nD .

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [October 3, 2018, 7:19pm UTC](https://discourse.processing.org/t/help-needed-bounce-clickable-area/4011/4 "2018-10-03T19:19:20Z")

</div>

> [@SolDrakibane](#):
>
> I’m having trouble understanding map() at the moment

In addition to the reference, check out the examples to better understand `map()`:

- [Map / Examples / Processing.org](https://processing.org/examples/map.html)
- [map() / Reference / Processing.org](https://processing.org/reference/map_.html)

---

<div class="post-metadata">

**Author:** ![Ov3rM1nD](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/ov3rm1nd/32/1756_2.png) [@Ov3rM1nD](https://discourse.processing.org/u/Ov3rM1nD)\
**Post date:** [October 3, 2018, 11:36pm UTC](https://discourse.processing.org/t/help-needed-bounce-clickable-area/4011/5 "2018-10-03T23:36:17Z")

</div>

You’re welcome buddy. I love to help. As @jeremydouglass said, check out some examples and do some trials with the map() function. This function is one of the best features in Processing.
