class Renderer{ constructor(canvas, nextCanvas, eventBus, size, colors){ this.canvas = canvas; this.nextCanvas = nextCanvas; this.ctx = this.canvas.getContext('2d'); this.nextCtx = this.nextCanvas.getContext('2d'); this.eventBus = eventBus; this.size = size; this.colors = colors; this.unsubscribers = []; this.renderCallBack = ({matrix, piece, nextMatrix, nextPiece})=>{ this.draw(matrix, piece, nextMatrix, nextPiece); } this.animationRenderCallback = ({matrix, indexes, count})=>{ let matrixToDraw; if(count % 2 == 0){ matrixToDraw = matrix; } else{ matrixToDraw = this.prepareBlinkMatrix(matrix, indexes); } this.drawGrid(this.ctx, matrixToDraw); } this.modeCallback = ({mode})=>{ if(mode === "animation"){ if(this.off_main_render) this.off_main_render(); this.off_main_render = null; if(this.off_animation_render === null){ this.off_animation_render = this.eventBus.on("animation-render", this.animationRenderCallback); } }else if(mode === "game"){ if(this.off_animation_render) this.off_animation_render(); this.off_animation_render = null; if(this.off_main_render === null){ this.off_main_render = this.eventBus.on("render", this.renderCallBack); } } } ////////// this.off_main_render = this.eventBus.on("render", this.renderCallBack); this.off_animation_render = null; this.pauseForceRender = this.eventBus.on("force-render", this.renderCallBack) this.eventBus.on("set-render-mode", this.modeCallback); //////// } eventOn(eventName, callback){ const unsubscriber = this.eventBus.on(eventName, callback); this.unsubscribers.push(unsubscriber); } dispose(){ this.unsubscribers.forEach((unsubscriber) => unsubscriber()); this.unsubscribers = []; } drawCell(ctx, x, y, colorIndex){ const space = 1; ctx.fillStyle = this.colors[colorIndex]; ctx.fillRect(x * (this.size+space), y * (this.size+space), this.size, this.size); } drawGrid(ctx, matrix){ for(let y=0; y < matrix.length; y++){ for(let x=0; x < matrix[y].length; x++){ this.drawCell(ctx, x, y, matrix[y][x]); } } } drawPiece(ctx, matrix, piece){ if(piece === null) return; for(let y =0; y < piece.body.length; y++){ for(let x =0; x < piece.body[y].length; x++){ let gridX = piece.x + x; let gridY = piece.y + y; if(inArray(gridX, gridY, matrix) && piece.body[y][x] !== 0){ this.drawCell(ctx, gridX, gridY, piece.body[y][x]); } } } } draw(matrix, piece, nextMatrix, nextPiece){ this.drawGrid(this.ctx, matrix); this.drawPiece(this.ctx, matrix, piece); this.drawGrid(this.nextCtx, nextMatrix); this.drawPiece(this.nextCtx, nextMatrix, nextPiece); } prepareBlinkMatrix(matrix, blinkedIndexes, blinkColorIndex = 8){ let blinkedMatrix = matrix.map((row)=>[...row]); const blinkedRow =new Array(blinkedMatrix[0].length).fill(8); for(let i = 0; i < blinkedIndexes.length; i++){ const blinkedIndex = blinkedIndexes[i]; blinkedMatrix[blinkedIndex] = blinkedRow; } return blinkedMatrix; } }