Using a Boolean in Constructor Class in p5.js

Good evening all;

I am still new to p5.js so appreciate your patience if I missed a simple thing! As a simple function in p5.js, I’m trying to make it so that when I click in a rectangle that it changes colour as well as that that change in colour also acknowledges a change in state (from false to true). I have successfully done this in Processing easy enough (in multiple sketches) but am having an unexpectedly hard time converting it into p5.js. I find that I can’t declare an array in the constructor within the Class. Any support is appreciated!

TL;DR – I tried to make it so that when I clicked a square in the array that it would change colour while also changing its state (from false to true), but cannot get it to work. I can change the colour without changing the state but not sure how to do it so that the colour changes and the state changes.

I have commented out some things that are not relevant right now. Here is the code in OpenProcessing: Speed Trainer - OpenProcessing

let sample = [];
let bassDrum = [];
let snareDrum = [];
let hiHat = [];

var bassRow = [16];
var snareRow = [16];
var hiHatRow = [16];

let col = 0;
let rectSize = 16;

// function preload() {
// 	sample[0] = loadSound('./BD.wav');
// 	sample[1] = loadSound('./SD.wav');
// 	sample[2] = loadSound('./CHH.wav');
// 	sample[3] = loadSound('./SS.wav');
// 	sample[4] = loadSound('./CC.wav');
// 	}

	function setup() {
		createCanvas(windowWidth, windowHeight);
		background(0);
		fill(255);
		for (let i = 0; i < 16; i++){
			bassDrum[i] = new drumButton(75 + i * 24, 50, bassRow, i);
			snareDrum[i] = new drumButton(75 + i * 24, 75, snareRow, i);
			hiHat[i] = new drumButton(75 + i * 24, 100, hiHatRow, i);
		}	
	}

	function draw() {
		for (let i = 0; i < 16; i++){
			bassDrum[i].pressEvent();
			bassDrum[i].display();
		}
		for (let i = 0; i < 16; i++){
			snareDrum[i].pressEvent();
			snareDrum[i].display();
		}
		for (let i = 0; i < 16; i++){
			hiHat[i].pressEvent();
			hiHat[i].display();
		}
	}

function mouseClicked() {
  if (col === 255) {
    col = 0;
  } else {
    col = 255;
  }
}

class drumButton {
	
	constructor(x, y, steps, stepId) {
		this.x  = x;
		this.y = y;
		this.steps = steps;
		this.stepId = stepId;
	}
	
	display(){
		if (this.steps[this.stepId] == true){
			fill(255,col,col,100);
		} else {
			fill(255,255,255,100);
		}
		rect(this.x, this.y, rectSize, rectSize);
	}
	
	pressEvent(){
		if (this.steps[this.stepId] == false && mouseIsPressed && mouseX >= this.x && mouseX <= (this.x + this.w) && mouseY >= (this.y) && mouseY <= (this.y + this.h)){
			this.steps[this.stepId] = true;
		} else {
			this.steps[this.stepId] = false;
		}
	}
}

// function keyTyped(){
// 	if (key == 'b') {
// 		sample[0].play();
// 	}
// 		if (key == 'h') {
// 		sample[2].play();
// 	}
// 	if (key == 's') {
// 		sample[1].play();
// 	}
// }

Hi @alenmartel

Your code checks for whether the mouse is hovering over a button using this.w and this.h. Does your drumButton class have a this.w and this.h attributes?

What are you trying to do with bassRow, snareRow, and hiHatRow arrays? Does each button need to have 16 steps? Why does it become a boolean in pressEvent?

What is the best way to track the active state of a button?

I can see that you tried different things to fix your issue but now they will fight against each other, especially toggling the col variable in the mouseClicked function.

There are a few other things that you could tweak to make your code more optimized:

  • There is no need for three separate for loops in the draw if all rows have the same number of buttons. (You may also want to look into the forEach loop. Its syntax is a little more advanced but it could make your code more succinct).
  • Your buttons check for click events on each frame even when the mouse is not pressed. What if they only checked when the mouse is clicked?
1 Like

Apologies for the delayed reply! I changed how the active states were checked as you suggested and made it work, thank you. The code in OpenProcessing was updated to show how it ended up working!