"use strict"; let tetris = function () { const grid_x = 10; const grid_y = 30; const tetrimonios = [ /*'I'*/{ mR:2, r:[ [ [0,0],[0,1],[0,2],[0,3] ], [ [0,0],[1,0],[2,0],[3,0] ] ] }, /*'O':*/{ mR:1, r:[ [ [0,0],[0,1],[1,0],[1,1] ] ] }, /*'L':*/{ mR:4, r:[ [ [0,0],[0,1],[0,2],[1,2] ], [ [0,0],[1,0],[2,0],[0,1] ], [ [0,0],[1,0],[1,1],[1,2] ], [ [2,0],[2,1],[1,1],[0,1] ] ] }, /*'L2':*/{ mR:4, r:[ [ [1,0],[1,1],[1,2],[0,2] ], [ [0,0],[0,1],[1,1],[2,1] ], [ [1,0],[0,0],[0,1],[0,2] ], [ [0,0],[1,0],[2,0],[2,1] ] ] }, /*'Z':*/{ mR:2, r:[ [ [0,0],[1,0],[1,1],[2,1] ], [ [1,0],[1,1],[0,1],[0,2] ] ] }, /*'Z2':*/{ mR:2, r:[ [ [0,1],[1,1],[1,0],[2,0] ], [ [0,0],[0,1],[1,1],[1,2] ] ] } ]; let timer, canvas, ctx, bs; let next_t; let board; let t = {t:null,x:0,y:0,r:0}; function control(e) { switch(e.key) { case 'r': clean(t); newGame(); break; case 'a': clean(t); nextT(); break; case 'ArrowUp': moveUp(t); break; case 'ArrowDown': moveDown(t); break; case 'ArrowLeft': moveLeft(t); break; case 'ArrowRight': moveRight(t);break; } } function clean(p) { ctx.fillStyle = "#FFFFFF"; drawBlocks(p,drawBlock_clean); } function draw(p) { ctx.fillStyle = "#666666"; drawBlocks(p,drawBlock_filled); } function drawBlocks(p, drawBlock) { p.t.r[p.r].forEach(b => drawBlock(p.x + b[0], p.y + b[1])); } function drawBlock_clean(x,y) { ctx.fillRect(bs*(1+x), bs*(1+y), bs, bs); } function drawBlock_filled(x,y) { ctx.fillRect(bs*(1+x), bs*(1+y), bs, bs); } function moveUp(p) { clean(t); let r = p.r; p.r = (++p.r)% p.t.mR; if ( collision(p) ) p.r = r; draw(t); } function moveDown(p) { clean(t); p.y++; if ( collision(p) ) { p.y--; glue(p); } draw(t); } function moveLeft(p) { clean(t); p.x--; if ( collision(p) ) p.x++; draw(t); } function moveRight(p) { clean(t); p.x++; if ( collision(p) ) p.x--; draw(t); } function glue(p) { p.t.r[p.r].forEach(b => { board[p.x+b[0]][p.y+b[1]]=1; } ); draw(t); dropShape(t); } function collision(p) { if ( p.x<0 || p.x>=grid_x || p.y<0 || p.y>=grid_y ) return true; if ( p.t.r[p.r].filter(b => ( p.x+b[0]>=grid_x || p.y+b[1]>=grid_y || board[p.x+b[0]][p.y+b[1]]==1 ) ).length>0 ) return true; return false } function getNextT() { let tNum = Math.floor(Math.random() * tetrimonios.length); return tetrimonios[ tNum ]; } function dropShape(p) { p.t = next_t; p.x = grid_x/2 - 1; p.y = 0; p.r = 0; next_t = getNextT(); } function newGame() { ctx.fillStyle = "#FFFFFF"; ctx.fillRect(0,0,canvas.getBoundingClientRect().width,canvas.getBoundingClientRect().height); board = Array.from(Array(grid_x), () => new Array(grid_y)); next_t = getNextT(); dropShape( t ); if (!timer) timer = setInterval(()=>moveDown(t), 1000); } function getBlockSize() { const space_top = 5; const space_right = 20; const { width, height } = canvas.getBoundingClientRect(); return Math.floor( Math.min( height / (space_top + grid_y), width / (space_right + grid_x) ) ); } function init() { canvas = document.getElementById("app"); canvas.width = window.innerWidth canvas.height = window.innerHeight ctx = canvas.getContext("2d"); bs = getBlockSize(); document.addEventListener('keydown', control); newGame(); } init(); } document.addEventListener('DOMContentLoaded', tetris );