tetris/js/renderer.js

93 lines
3.7 KiB
JavaScript

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;
}
}