From cc4737d7a08de4d9f28a4be1601d471e80f103bf Mon Sep 17 00:00:00 2001 From: JDG Date: Tue, 19 Oct 2021 23:39:29 +0200 Subject: [PATCH] exploring other ways --- tetris_v2.js | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 tetris_v2.js diff --git a/tetris_v2.js b/tetris_v2.js new file mode 100644 index 0000000..bb48996 --- /dev/null +++ b/tetris_v2.js @@ -0,0 +1,234 @@ +"use strict"; + + +const grid_x = 10; +const grid_y = 20; +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] ] + ] + }, + /*'T':*/{ mR:4, + r:[ + [ [1,0],[0,1],[1,1],[2,1] ], + [ [0,0],[0,1],[0,2],[1,1] ], + [ [0,0],[1,0],[2,0],[1,1] ], + [ [1,0],[1,1],[1,2],[0,1] ] + ] + } +]; + +class Shape { + constructor(board) { + this.board = board; + this.set(null); + } + set(t) { + this.t = t; + this.x = this.board.w/2 -1; this.ox = this.x; + this.y = 0; this.oy = 0; + this.r = 0; this.or = 0 + } + rotate() { + let r = this.r; + this.r = (this.r + 1) % this.t.mR; + if ( this.board.collision(this) ) { + this.r = r; + } else { + this.or = r; + this.ox = this.x; + this.oy = this.y; + this.board.draw(this); // this.t, this.x, this.y, this.r); + } + } + down() { + this.y++; + if ( this.board.collision(this) ) { + this.y--; + this.board.glue(this); + } else { + this.ox = this.x; + this.oy = this.y -1; + this.or = this.r; + this.board.draw(this); + } + } + left() { + this.x--; + if ( this.board.collision(this) ) { + this.x++; + } else { + this.ox = this.x + 1; + this.oy = this.y; + this.or = this.r; + this.board.draw(this); + } + } + right() { + this.x++; + if ( this.board.collision(this) ) { + this.x--; + } else { + this.ox = this.x - 1; + this.oy = this.y; + this.or = this.r; + this.board.draw(this); + } + } +} + +class Board { + constructor(w,h,canvas) { + this.ctx = canvas.getContext("2d"); + + const space_top = 5; + const space_right = 10; + + const { width, height } = canvas.getBoundingClientRect(); + this.s = Math.floor( Math.min( height / (space_top + h), width / (space_right + w) ) ); + this.x = this.s*1; + this.y = canvas.height - this.s*h - this.s*1; + + this.w = w; + this.h = h; + this.next_t = this.getRandomT(); + this.reset(); + this.shape = new Shape(this); + this.shape.set(this.getRandomT()); + } + + reset() { + this.board = Array.from(Array(this.h), () => new Array(this.w)); // Board[Y][X] + this.clean(); + } + + collision(p /*:Shape*/ ) { + if ( p.x<0 || p.x>=this.w || p.y<0 || p.y>=this.h ) return true; + if ( p.t.r[p.r].filter(b => ( p.x+b[0]>=this.w || p.y+b[1]>=this.h || this.board[p.y+b[1]][p.x+b[0]]==1 ) ).length>0 ) return true; + return false + } + + glue(p /*:Shape*/) { + p.t.r[p.r].forEach(b => { this.board[p.y+b[1]][p.x+b[0]]=1; } ); + + this.draw(p,false); + + this.deleteRows( this.board.filter( r=>r.filter(c=>c==1).length==grid_x ) ); + + p.set(this.next_t); + this.next_t = this.getRandomT(); + } + getRandomT() { + return tetrimonios[ Math.floor(Math.random() * tetrimonios.length) ]; + } + + draw(p /*:Shape*/, live) { + live = typeof(live) == 'undefined' ? true : live; + + this.ctx.fillStyle = "#FFFFFF"; + p.t.r[p.or].forEach(b => this.drawBlock(p.ox + b[0], p.oy + b[1])); + + this.ctx.fillStyle = live?"#F66666":"#666666"; + p.t.r[p.r].forEach(b => this.drawBlock(p.x + b[0], p.y + b[1])); + } + drawBlock(x,y) { + this.ctx.fillRect(this.x + this.s*x, this.y + this.s*y, this.s, this.s); + } + + deleteRows(r) { + if (r.length>0) { + let newBoard = this.board.filter( r=>r.filter(c=>c==1).length new Array(this.w)); + this.board = this.board.concat(newBoard); + + this.clean(); + + this.ctx.fillStyle = "#666666"; + this.board.forEach((r,y)=>r.forEach((c,x)=>{if(c==1)this.drawBlock(x,y);})) + } + } + + clean() { + this.ctx.fillStyle = "#FFFFFF"; + this.ctx.fillRect(this.x, this.y, this.s*this.w, this.s*this.h); + } + +} + +let tetris = function () { + + // ---------------------------------------------------------- + let timer; + let canvas = document.getElementById("app"); + canvas.width = window.innerWidth + canvas.height = window.innerHeight + + let ctx = canvas.getContext("2d"); + let board = new Board(grid_x,grid_y,canvas); + document.addEventListener('keydown', control); + newGame(); + // ---------------------------------------------------------- + + function control(e) { + switch(e.key) { + case 'r': newGame(); break; + case 'ArrowUp': board.shape.rotate(); break; + case 'ArrowDown': board.shape.down(); break; + case 'ArrowLeft': board.shape.left(); break; + case 'ArrowRight': board.shape.right(); break; + } + } + + function newGame() { + drawBackground(); + board.reset(); + + if (!timer) timer = setInterval(()=>board.shape.down(), 1000); + } + + function drawBackground() { + ctx.fillStyle = "#FFFFFF"; + ctx.fillRect(0,0,canvas.getBoundingClientRect().width,canvas.getBoundingClientRect().height); + + ctx.strokeStyle = "#0074cc"; + ctx.strokeRect(board.x -1, board.y - 1, board.s*board.w +2, board.s*board.h +2); + } +} + + +document.addEventListener('DOMContentLoaded', tetris ); \ No newline at end of file