class Drawer { #canvasWidth #canvasHeight constructor(_padding) { this.padding = _padding; createCanvas(0, 0); } setTubesParams(_tubesNumbers, _tubeLevels, _tubeSize) { this.tubesNumbers = _tubesNumbers; this.tubeLevels = _tubeLevels; this.tubeSize = _tubeSize; this.#canvasWidth = this.tubesNumbers * (this.tubeSize + this.padding) + this.padding; this.#canvasHeight = 3 * this.padding + this.tubeLevels * this.tubeSize; resizeCanvas(this.#canvasWidth, this.#canvasHeight); } draw(game) { let tubes = game.tubes; let selectedTube = game.selectedTube; background('white'); this.drawTubes(this.padding, 2*this.padding, tubes, selectedTube); } drawTubes(x, y, tubes, selectedTube) { let tubeX = x; let tubeY = y; let selectionOffset = 0; tubes.forEach(tube => { selectionOffset = (tube == selectedTube ? this.padding : 0); this.drawTube(tubeX, tubeY - selectionOffset, tube); tubeX += this.padding + this.tubeSize; }); } drawTube(x, y, tube) { y += (this.tubeLevels-1) * this.tubeSize; for(let i = 0; i < this.tubeLevels; i++) { color = tube.getColorAtLevel(i); color == null ? noFill() : fill(color); if (i >= 0) { rect(x, y - i * this.tubeSize, this.tubeSize); } } } getTubeIdAt(x, y) { if (!this.isInboundsCanvas(x,y)) return -1; let idWithPadding = (x - this.padding) / (this.tubeSize + this.padding); return idWithPadding % 1 > 1 - (this.padding / (this.tubeSize + this.padding)) ? -1 : int(idWithPadding); } isInboundsCanvas(x, y) { return x >= this.padding && y >= this.padding && x < this.#canvasWidth - this.padding && y < this.#canvasHeight - this.padding; } }