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 = 2 * this.padding + (this.tubeLevels+1) * this.tubeSize; resizeCanvas(this.#canvasWidth, this.#canvasHeight); } draw(game) { let tubes = game.tubes; let selectedTube = game.selectedTube; background('white'); this.drawTubes(this.padding, this.padding+this.tubeSize, tubes, selectedTube); if(game.isCompleted) this.drawWinView(); } drawTubes(x, y, tubes, selectedTube) { let tubeX = x; let tubeY = y; let selectionOffset = 0; tubes.forEach(tube => { selectionOffset = (tube == selectedTube ? this.tubeSize : 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; } drawWinView(){ fill('red'); textSize(50); let textX = this.#canvasWidth / 2 - 175 + 10 * sin(frameCount/10); let textY = this.#canvasHeight / 2 + 10 * cos(frameCount/10); let message = "👑 You Win! 👑" text(message, textX, textY); textX ++; textY ++; fill('yellow'); text(message, textX, textY); } }