class Drawer { #canvas; constructor(_padding, _scale) { this.padding = _padding; this.scale = _scale; this.#canvas = createCanvas(0, 0); } computeGameParams(_tubesNumbers, _tubeLevels) { let canvasWidth = _tubesNumbers * (this.scale + this.padding) + this.padding; let canvasHeight = 2 * this.padding + (_tubeLevels+1) * this.scale; resizeCanvas(canvasWidth, canvasHeight); } draw(game) { background('orange'); this.drawTubes(this.padding, this.padding+this.scale, game); } drawTubes(x, y, game) { let tubeX = x; let tubeY = y; let selectionOffset = 0; for (let i = 0; i < game.tubesNumber(); i++) { let tube = game.tubeAt(i); selectionOffset = (tube == game.selectedTube() ? this.scale : 0); this.drawTube(tubeX, tubeY - selectionOffset, tube); tubeX += this.padding + this.scale; } } drawTube(x, y, tube) { let tubeLevels = tube.height(); y += (tubeLevels-1) * this.scale; for(let i = 0; i < tubeLevels; i++) { color = tube.getColorAtLevel(i); color == null ? noFill() : fill(color); if (i >= 0) { rect(x, y - i * this.scale, this.scale); } } } getTubeIdAt(x, y) { if (!this.isInboundsCanvas(x,y)) return -1; let idWithPadding = (x - this.padding) / (this.scale + this.padding); return idWithPadding % 1 > 1 - (this.padding / (this.scale + this.padding)) ? -1 : int(idWithPadding); } isInboundsCanvas(x, y) { return x >= this.padding && y >= this.padding && x < this.#canvas.width - this.padding && y < this.#canvas.height - this.padding; } }