diff --git a/PlayButton.png b/PlayButton.png new file mode 100644 index 0000000..602cd08 Binary files /dev/null and b/PlayButton.png differ diff --git a/css/styles.css b/css/styles.css index ba018ee..1f25a6d 100644 --- a/css/styles.css +++ b/css/styles.css @@ -15,7 +15,7 @@ body{ top:50%; position: absolute; background: #555; - + } #scene{ @@ -93,9 +93,93 @@ body{ font-weight: bold; height:20px; } +#restartInfo{ + color:#fff; + font-weight: bold; + font-size: 18px; +} +#restart_button{ + height: 50px; + width: 50px; +} +#pause_button{ + height:50px; + width: 50px; +} +#play_button{ + height: 50px; + width: 50px; +} + +#info_button{ + position: absolute; + height: 40px; + width: 40px; + bottom: 0; + right: 0; +} + + +#modal_backdrop{ + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1000; + background-color: rgba(0, 0, 0, 0.65); +} +#info_modal{ + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + z-index: 1010; + overflow: scroll; +} +.info_dialog{ + width: auto; + max-width: 600px; + min-width: 350px; + min-height: 300px; + margin: 40px auto; + background-color: #fff; + border-radius: 15px; +} +.info_header{ + position: relative; + padding: 10px 20px; + height: 20px; +} + +.info_controls_header{ + position: relative; + padding: 10px 20px; +} + +.info_instructions_header{ + position: relative; + padding: 10px 20px; +} + +.info_close_button{ + float: right; + border: none; + background: none; + cursor: pointer; + font-size: large; + padding: 10px; + position: relative; + z-index: 1000; +} + +.hidden{ + display: none; +} .invisible{ @@ -138,4 +222,4 @@ body{ .fadeOutUp { -webkit-animation-name: fadeOutUp; animation-name: fadeOutUp; -} \ No newline at end of file +} diff --git a/dist/tetris.js b/dist/tetris.js index dd30e84..474c257 100644 --- a/dist/tetris.js +++ b/dist/tetris.js @@ -13,10 +13,10 @@ var drawLine = function(ctx,p1,p2,color){ ctx.beginPath(); ctx.moveTo(p1.x,p1.y); ctx.lineTo(p2.x,p2.y); - + ctx.lineWidth=1; ctx.strokeStyle= color; - + ctx.stroke(); ctx.closePath(); }; @@ -25,7 +25,7 @@ var drawLine = function(ctx,p1,p2,color){ //Draw game grids var drawGrids = function(el,gridSize,colCount,rowCount,color1,color2){ - + var ctx = el.getContext('2d'); var width = el.width; @@ -34,11 +34,11 @@ var drawGrids = function(el,gridSize,colCount,rowCount,color1,color2){ ctx.rect(0, 0, width, height); var grd = ctx.createLinearGradient(0, 0, 0, height); - grd.addColorStop(0, color1); + grd.addColorStop(0, color1); grd.addColorStop(1, color2); ctx.fillStyle = grd; ctx.fill(); - + for (var i = 1; i < colCount; i++) { var x = gridSize*i+0.5; @@ -81,7 +81,7 @@ var tetrisCanvas = { this.previewGridSize = preview.width / consts.PREVIEW_COUNT; this.drawScene(); - + }, //Clear game canvas @@ -108,7 +108,7 @@ var tetrisCanvas = { drawBox(this.sceneContext,row[j],j*this.gridSize,i*this.gridSize,this.gridSize); } } - } + } }, //Draw preview data drawPreview:function(){ @@ -179,10 +179,10 @@ var rowCount = 20; //previewCount var previewCount = 6; -//scene gradient start color +//scene gradient start color var sceneBgStart = '#8e9ba6'; -//scene gradient end color +//scene gradient end color var sceneBgEnd = '#5c6975'; //preview background color @@ -199,8 +199,8 @@ var boxBorderColor = 'rgba(255,255,255,0.5)'; var defaultInterval = 600; -// Level update interval -var levelInterval = 120 * 1000; +// Level update interval +var levelInterval = 120 * 1000; @@ -285,11 +285,11 @@ var checkFullRows = function(matrix){ } } - return rowNumbers; + return rowNumbers; }; /** - Remove one row from game matrix. + Remove one row from game matrix. copy each previous row data to next row which row number less than row; */ var removeOneRow = function(matrix,row){ @@ -300,9 +300,9 @@ var removeOneRow = function(matrix,row){ matrix[i][j] = matrix[i-1][j]; }else{ matrix[i][j] = 0 ; - } + } } - } + } }; /** Remove rows from game matrix by row numbers. @@ -332,7 +332,7 @@ var checkGameOver = function(matrix){ */ var calcRewards = function(rows){ if (rows&&rows.length>1){ - return Math.pow(2,rows.length - 1)*100; + return Math.pow(2,rows.length - 1)*100; } return 0; }; @@ -372,11 +372,11 @@ function Tetris(id){ Tetris.prototype = { init:function(options){ - + var cfg = this.config = utils.extend(options,defaults); this.interval = consts.DEFAULT_INTERVAL; - - + + views.init(this.id, cfg.maxWidth,cfg.maxHeight); canvas.init(views.scene,views.preview); @@ -416,16 +416,29 @@ Tetris.prototype = { this.currentTime = new Date().getTime(); this.prevTime = this.currentTime; }, + //New pause + Newpause:function(){ + if(PlayBool == true){ + this.running = false; + this.currentTime = new Date().getTime(); + this.prevTime = this.currentTime; + PlayBool = false; + } + else{ + start(); + } + + }, //Game over gamveOver:function(){ }, // All key event handlers _keydownHandler:function(e){ - + var matrix = this.matrix; - if(!e) { + if(!e) { var e = window.event; } if (this.isGameOver||!this.shape){ @@ -435,10 +448,10 @@ Tetris.prototype = { switch(e.keyCode){ case 37:{this.shape.goLeft(matrix);this._draw();} break; - + case 39:{this.shape.goRight(matrix);this._draw();} break; - + case 38:{this.shape.rotate(matrix);this._draw();} break; @@ -458,6 +471,10 @@ Tetris.prototype = { _initEvents:function(){ window.addEventListener('keydown',utils.proxy(this._keydownHandler,this),false); views.btnRestart.addEventListener('click',utils.proxy(this._restartHandler,this),false); + views.NewRestart.addEventListener('click',utils.proxy(this._restartHandler,this),false); + views.NewPause.addEventListener('click',utils.proxy(this.pause,this),false); + views.NewPlay.addEventListener('click',utils.proxy(this.start,this),false); + }, // Fire a new random shape @@ -467,10 +484,10 @@ Tetris.prototype = { this._draw(); canvas.drawPreviewShape(this.preparedShape); }, - + // Draw game data _draw:function(){ - canvas.drawScene(); + canvas.drawScene(); canvas.drawShape(this.shape); canvas.drawMatrix(this.matrix); }, @@ -486,7 +503,7 @@ Tetris.prototype = { this._checkLevel(); } if (!this.isGameOver){ - window.requestAnimationFrame(utils.proxy(this._refresh,this)); + window.requestAnimationFrame(utils.proxy(this._refresh,this)); } }, // Update game data @@ -510,7 +527,7 @@ Tetris.prototype = { var rows = checkFullRows(this.matrix); if (rows.length){ removeRows(this.matrix,rows); - + var score = calcScore(rows); var reward = calcRewards(rows); this.score += score + reward; @@ -546,7 +563,7 @@ var COLORS = consts.COLORS; var COLUMN_COUNT = consts.COLUMN_COUNT; /** - Defined all shapes used in Tetris game. + Defined all shapes used in Tetris game. You can add more shapes if you wish. */ @@ -801,7 +818,7 @@ ShapeZR.prototype = { canDown:function(matrix){ return isShapeCanMove(this,matrix,'down'); }, - //Move the shape down + //Move the shape down goDown:function(matrix){ if (isShapeCanMove(this,matrix,'down')){ this.y+=1; @@ -999,6 +1016,10 @@ var rewardInfo = $('rewardInfo'); var reward = $('reward'); var gameOver = $('gameOver'); var btnRestart = $('restart'); +var NewRestart = $('restart_button'); +var NewPause = $('pause_button'); +var NewPlay = $('play_button'); +var btnInfo = $('info_button'); var finalScore = $('finalScore'); @@ -1006,6 +1027,39 @@ var finalScore = $('finalScore'); var SIDE_WIDTH = consts.SIDE_WIDTH; +function showInfoModal() { + + var modalBackdrop = document.getElementById('modal_backdrop'); + var infoModal = document.getElementById('info_modal'); + + // Show the modal and its backdrop. + modalBackdrop.classList.remove('hidden'); + infoModal.classList.remove('hidden'); + +} + +function hideInfoModal() { + + var modalBackdrop = document.getElementById('modal_backdrop'); + var infoModal = document.getElementById('info_modal'); + + // Show the modal and its backdrop. + modalBackdrop.classList.add('hidden'); + infoModal.classList.add('hidden'); + +} + +var infoButton = document.getElementById('info_button'); +if (infoButton) { + infoButton.addEventListener('click', showInfoModal); +}; + +var modalCloseButton = document.querySelector('#info_modal .info_close_button'); +if (modalCloseButton) { + modalCloseButton.addEventListener('click', hideInfoModal); +}; + + /** Caculate the game container size */ @@ -1065,6 +1119,10 @@ var tetrisView = { this.scene = scene; this.preview = preview; this.btnRestart = btnRestart; + this.NewPlay = NewPlay; + this.NewRestart = NewRestart; + this.NewPause = NewPause; + layoutView(this.container,maxW,maxH); this.scene.focus(); @@ -1072,9 +1130,9 @@ var tetrisView = { rewardInfo.className = 'invisible'; }); }, - // Update the score + // Update the score setScore:function(scoreNumber){ - score.innerHTML = scoreNumber; + score.innerHTML = scoreNumber; }, // Update the finnal score setFinalScore:function(scoreNumber){ @@ -1088,7 +1146,7 @@ var tetrisView = { setReward:function(rewardScore){ if (rewardScore>0){ reward.innerHTML = rewardScore; - rewardInfo.className = 'fadeOutUp animated'; + rewardInfo.className = 'fadeOutUp animated'; }else{ rewardInfo.className = 'invisible'; } diff --git a/images/info.png b/images/info.png new file mode 100644 index 0000000..5e94354 Binary files /dev/null and b/images/info.png differ diff --git a/index.html b/index.html index 3ae0174..a6ccc66 100644 --- a/index.html +++ b/index.html @@ -15,7 +15,7 @@

Game Over !

Score: 0

Restart

- +
@@ -23,10 +23,42 @@

Level:
1

Score:
0

+ + + +

Click above to restart game

+
+
+ + + diff --git a/pause.png b/pause.png new file mode 100644 index 0000000..1f82daa Binary files /dev/null and b/pause.png differ diff --git a/restart.png b/restart.png new file mode 100644 index 0000000..04b8768 Binary files /dev/null and b/restart.png differ diff --git a/src/canvas.js b/src/canvas.js index 89498c3..5bf2d26 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -7,63 +7,85 @@ var lineColor = consts.GRID_LINE_COLOR; var boxBorderColor = consts.BOX_BORDER_COLOR; +function lineProperties(ctx,p1,p2,color){ + this.ctx = ctx; + this.p1 = p1; + this.p2 = p2; + this.color = color; +} + +function gridProperties(el,gridSize,colCount,rowCount,color1,color2){ + this.el = el; + this.gridSize = gridSize; + this.colCount = colCount; + this.rowCount = rowCount; + this.color1 = color1; + this.color2 = color2; +} + //Draw a single line in canvas context -var drawLine = function(ctx,p1,p2,color){ - ctx.beginPath(); - ctx.moveTo(p1.x,p1.y); - ctx.lineTo(p2.x,p2.y); - - ctx.lineWidth=1; - ctx.strokeStyle= color; - - ctx.stroke(); - ctx.closePath(); -}; +var drawLine = function(lineProps){ + lineProps.ctx.beginPath(); + + var p1 = lineProps.p1; + var p2 = lineProps.p2; + + lineProps.ctx.moveTo(p1.x,p1.y); + lineProps.ctx.lineTo(p2.x,p2.y); + lineProps.ctx.lineWidth = 1; + lineProps.ctx.strokeStyle = color; + + lineProps.ctx.stroke(); + lineProps.ctx.closePath(); +}; //Draw game grids -var drawGrids = function(el,gridSize,colCount,rowCount,color1,color2){ - - - - var ctx = el.getContext('2d'); - var width = el.width; - var height = el.height; - - ctx.rect(0, 0, width, height); - - var grd = ctx.createLinearGradient(0, 0, 0, height); - grd.addColorStop(0, color1); - grd.addColorStop(1, color2); - ctx.fillStyle = grd; - ctx.fill(); - - - for (var i = 1; i < colCount; i++) { - var x = gridSize*i+0.5; - drawLine(ctx,{x:x,y:0},{x:x,y:height},lineColor); - }; - for (var i = 1; i < rowCount; i++) { - var y = gridSize*i+0.5; - drawLine(ctx,{x:0,y:y},{x:width,y:y},lineColor); - }; +var drawGrids = function(gridProps){ + var ctx = gridProps.el.getContext('2d'); + var width = gridProps.el.width; + var height = gridProps.el.height; + + ctx.rect(0, 0, width, height); + + var grd = ctx.createLinearGradient(0, 0, 0, height); + grd.addColorStop(0, gridProps.color1); + grd.addColorStop(1, gridProps.color2); + ctx.fillStyle = grd; + ctx.fill(); + + var lineProps = lineProperties(ctx, 0, 0, lineColor); + + for (var i = 1; i < gridProps.colCount; i++) { + var x = gridProps.gridSize*i+0.5; + lineProps.p1 = {x:x,y:0}; + lineProps.p2 = {x:x,y:height}; + drawLine(lineProps); + }; + + for (var i = 1; i < gridProps.rowCount; i++) { + var y = gridProps.gridSize*i+0.5; + lineProps.p1 = {x:0,y:y}; + lineProps.p2 = {x:width,y:y}; + drawLine(lineProps); + }; }; //Draw box of shape (shape is the composition of boxes) -var drawBox = function(ctx,color,x,y,gridSize){ - if (y<0){ - return; - } + var drawBox = function(ctx,color,x,y,gridSize){ + if (y<0){ + return; + } - ctx.beginPath(); - ctx.rect(x,y,gridSize,gridSize); - ctx.fillStyle = color; - ctx.fill(); - ctx.strokeStyle= boxBorderColor; - ctx.lineWidth=1; - ctx.stroke(); - ctx.closePath(); -} + ctx.beginPath(); + ctx.rect(x,y,gridSize,gridSize); + ctx.fillStyle = color; + ctx.fill(); + ctx.strokeStyle= boxBorderColor; + ctx.lineWidth=1; + ctx.stroke(); + ctx.closePath(); + } /* Canvas main object, use to draw all games data. @@ -94,9 +116,10 @@ var tetrisCanvas = { //Draw game scene, grids drawScene:function(){ this.clearScene(); - drawGrids(this.scene,this.gridSize, + var gridProps = gridProperties(this.scene,this.gridSize, consts.COLUMN_COUNT,consts.ROW_COUNT, - consts.SCENE_BG_START,consts.SCENE_BG_END); + consts.SCENE_BG_START,consts.SCENE_BG_END); /// + drawGrids(gridProps); }, //Draw game data drawMatrix:function(matrix){ @@ -111,9 +134,10 @@ var tetrisCanvas = { }, //Draw preview data drawPreview:function(){ - drawGrids(this.preview,this.previewGridSize, + var gridProps = gridProperties(this.preview,this.previewGridSize, consts.PREVIEW_COUNT,consts.PREVIEW_COUNT, consts.PREVIEW_BG,consts.PREVIEW_BG); + drawGrids(gridProps); /// }, //Draw acitve shape in game drawShape:function(shape){ @@ -124,8 +148,7 @@ var tetrisCanvas = { var gsize = this.gridSize; for(var i = 0;i