How can I change this code with for loop, so that I can create more bigger rectangles with same functions? When I use for loop, when I point to the smaller rectangle, the bigger rectangle will also change color. I can't make it exclusive to the rectangle I am pointing at. Thankss.
let rectX = 200;
let rectY = 200;
let rect1Width = 80;
let rect1Height = 80;
let rect2Width = 40;
let rect2Height = 40;
let isMouseOverRect1 = false;
let isMouseOverRect2 = false;
let rect1 = false;
let rect2 = false;
function setup() {
createCanvas(400, 400);
rectMode(CENTER);
}
function draw() {
background(200);
if (
mouseX > rectX - rect1Width / 2 &&
mouseX < rectX + rect1Width / 2 &&
mouseY > rectY - rect1Height / 2 &&
mouseY < rectY + rect1Height / 2
) {
isMouseOverRect1 = true;
rect1 = true;
} else {
isMouseOverRect1 = false;
rect1 = false;
}
if (
mouseX > rectX - rect2Width / 2 &&
mouseX < rectX + rect2Width / 2 &&
mouseY > rectY - rect2Height / 2 &&
mouseY < rectY + rect2Height / 2
) {
isMouseOverRect2 = true;
rect2 = true;
} else {
isMouseOverRect2 = false;
rect2 = false;
}
if (isMouseOverRect1 && !rect2) {
fill(0);
} else {
fill(255);
}
rect(rectX, rectY, rect1Width, rect1Height);
if (isMouseOverRect2 && rect1) {
fill(0);
} else {
fill(255);
}
rect(rectX, rectY, rect2Width, rect2Height);
}
Drawing with for loop with same function.
You can encapsulate reusable functionalities, for example:
There are multiple ways to implement this depending on your level of comfort. For example you could do something this:
[x,y,w,h]
) (or Object({x:200, y: 200, w:80, y:80}
)let rect1 = {x:160, y:160, w:80, h:80}
let rect2 = {x:180, y:180, w:40, h:40};
function setup() {
createCanvas(400, 400);
}
function draw() {
background(200);
let isOver1 = isOverRectangle(mouseX, mouseY, rect1);
let isOver2 = isOverRectangle(mouseX, mouseY, rect2);
fill(isOver1 && !isOver2 ? 0 : 255);
drawRectangle(rect1);
fill(isOver2 ? 0 : 255);
drawRectangle(rect2);
}
function isOverRectangle(mx, my, rectangle){
return (mx >= rectangle.x && mx <= (rectangle.x + rectangle.w)) &&
(my >= rectangle.y && my <= (rectangle.y + rectangle.h));
}
function drawRectangle(r){
rect(r.x, r.y, r.w, r.h);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
Alternatively you could define a class:
class Rect{
constructor(x, y, w, h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
draw(){
rect(this.x, this.y, this.w, this.h);
}
isOver(mx, my){
return (mx >= this.x && mx <= (this.x + this.w)) &&
(my >= this.y && my <= (this.y + this.h));
}
}
let rect1 = new Rect(160, 160, 80, 80);
let rect2 = new Rect(180, 180, 40, 40);
function setup() {
createCanvas(400, 400);
}
function draw() {
background(200);
let isOver1 = rect1.isOver(mouseX, mouseY);
let isOver2 = rect2.isOver(mouseX, mouseY);
fill(isOver1 && !isOver2 ? 0 : 255);
rect1.draw();
fill(isOver2 ? 0 : 255);
rect2.draw();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
For two rectangles you might not need a for loop, however if you do choose to encapsulation will make this a bit easier now. It will be a fun challenge for yourself, especially working out the logic to check which boxes to ignore and take into account to change the fill color. Have fun!