1 //事件处理对象 2 //addHandler() 方法接受3个参数:要操作的元素、事件名称和事件处理程序函数。 3 var EventUtil = { 4 addHandler: function (element, type, handler) { 5 if (element.addEventListener) { 6 element.addEventListener(type, handler, false); 7 } else if (element.attachEvent) { 8 element.attachEvent("on" + type, handler); 9 } else { 10 element["on" + type] = handler; 11 } //处理浏览器之间的差异 12 }, 13 14 //获取事件对象 15 getEvent: function (event) { 16 return event ? event : window.event; //兼容IE 17 } 18 19 } 20 21 //创建Game对象 22 function Game2048(tileCon, scoreEle, bestScoreEle) { 23 this.tileContainer = tileCon; 24 this.scoreEle = scoreEle; 25 this.bestScoreEle = bestScoreEle; 26 this.tiles = new Array(4);//创建存方块数值与dom对象的一维数组 27 28 } 29 30 Game2048.prototype = { //game的原型方法 31 init: function () { //初始化游戏 32 this.posArray = [];//创建存空白方块坐标的数组 position 33 for (let i = 0, len = this.tiles.length; i < len; i++) { 34 35 this.tiles[i] = []; //变成了二维数组 36 for (let j = 0; j < len; j++) { 37 this.tiles[i][j] = { num: 0 }; //初始化存方块数值与dom对象的数组 38 this.posArray.push({ "x": i, "y": j }); 39 40 //初始化存方块坐标的数组 41 } 42 } 43 this.deleteTile(true); //清空全部方块 自定义的方法 传入true 全部clear 44 this.score = 0; //初始化分数 45 this.bestScore = this.bestScore || 0; 46 this.newTile(); //创建两个方块 47 this.newTile(); 48 }, 49 //创建方块函数 50 newTile: function () { 51 var tile = document.createElement("div"); 52 var pos = this.randomPos(); //方块位置 53 var num = Math.random() < 0.9 ? 2 : 4; //新方块数值2或者4 54 this.tiles[pos.x][pos.y] = { num: num, tile: tile }; 55 //将新房块的数字与dom对象 存入数组 56 this.setTile(tile, num, pos.x, pos.y); //设置方块属性产生移动与淡入效果 57 this.tileContainer.appendChild(tile); 58 }, 59 //设置方块class和显示的数字 60 setTile: function (element, num, x, y) { //xy 是坐标位置 (x,y)让哪一个格子生成div 根据num的值渲染不同的颜色 61 element.innerHTML = num; 62 element.className = "tile tile-" + num + " tile-pos-" + x + "-" + y; 63 },//设置类名 64 65 randomPos: function () { //随机一个方块位置 66 let index = Math.floor(Math.random() * this.posArray.length); 67 // console.log(index); 68 let pos = this.posArray[index]; // posArray 存放的是16个格子的位置 随机产生一个数字即可 69 // console.log(pos); 70 this.posArray.splice(index, 1); // 产生之后就不是一个空白方块了???? 71 return pos; //返回的是一个对象 里面存放的位置信息 { "x": i, "y": j } 72 }, 73 74 //方块移动 core 75 moveTile: function (keyCode) { 76 let len = this.tiles.length; 77 let merge; //存合并状态 自定义函数 78 switch (keyCode) { 79 //左移 80 case 37: 81 for (let i = 1; i < len; i++) { 82 for (let j = 0; j < len; j++) { 83 if (this.tiles[i][j].num != 0 && this.leftMove(i, j)) { //遍历所有的格子不是空格子就左移 84 merge = this.merge(i, j); //合并 85 } 86 } 87 } 88 break; 89 //右移动 90 case 39: 91 for (let i = len - 2; i >= 0; i--) { 92 for (let j = 0; j < len; j++) { 93 if (this.tiles[i][j].num != 0 && this.rightMove(i, j)) {//遍历所有的格子不是空格子就right移 94 merge = this.merge(i, j); 95 } 96 } 97 } 98 break; 99 case 38: //shang yi dong 100 for (let i = 0; i < len; i++) { 101 for (let j = 1; j < len; j++) { 102 if (this.tiles[i][j].num != 0 && this.upMove(i, j)) {//遍历所有的格子不是空格子就 up 103 merge = this.merge(i, j); 104 } 105 } 106 } 107 break; 108 case 40: 109 for (let i = 0; i < len; i++) { 110 for (let j = len - 2; j >= 0; j--) { 111 if (this.tiles[i][j].num != 0 && this.downMove(i, j)) { //遍历所有的格子不是空格子就down 112 113 merge = this.merge(i, j); 114 } 115 } 116 } 117 break; 118 } 119 if (merge) { //产生了 合并事件就产生一个新的方块 120 this.newTile();//合并后创建一个新的方块 121 } else if (this.posArray.length == 0 && this.gameOverTest()) { 122 this.gameOver(); //游戏结束测试 123 } 124 }, 125 126 127 leftMove: function (i, j) { //左移函数 128 this.num = this.tiles[i][j].num; //找到该格子的数字 129 this.moveI = undefined; 130 this.moveJ = undefined; 131 for (let n = i - 1; n >= 0; n--) { //一直试探到碰壁为止 132 if (this.tiles[n][j].num == 0) { //试探左边的的格子是否为空 133 this.moveI = n; 134 } else if (this.tiles[n][j].num == this.num) { //如果左边的数字相同 则合并 135 this.num *= 2; 136 this.moveI = n; 137 if (this.num == 2048) { 138 this.gameWin(); //如果有2048出现 则闯关成功 139 } 140 this.getScore(this.num); //记录分数 141 break; 142 } else { 143 break; 144 } 145 } 146 this.moveJ = j; 147 if (!(this.moveI + 1) || !(this.moveJ + 1)) { //undefined + 1 = NaN; 148 return; //没有产生移动 直接进入的else break循环 149 } 150 return true; 151 }, 152 153 154 rightMove: function (i, j) { //与左移同理 155 let len = this.tiles.length; 156 this.num = this.tiles[i][j].num; 157 this.moveI = undefined; 158 this.moveJ = undefined; 159 for (let n = i + 1; n < len; n++) { 160 if (this.tiles[n][j].num == 0) { 161 this.moveI = n; 162 } else if (this.tiles[n][j].num == this.num) { 163 this.num *= 2; 164 this.moveI = n; 165 if (this.num == 2048) { 166 this.gameWin(); 167 } 168 this.getScore(this.num); 169 break; 170 } else { 171 break; 172 } 173 } 174 this.moveJ = j; 175 if (!(this.moveI + 1) || !(this.moveJ + 1)) { 176 return; 177 } 178 return true; 179 }, 180 181 182 upMove: function (i, j) { //与左移同理 183 184 this.num = this.tiles[i][j].num; 185 this.moveI = undefined; 186 this.moveJ = undefined; 187 for (let n = j - 1; n >= 0; n--) { 188 if (this.tiles[i][n].num == 0) { 189 this.moveJ = n; 190 } else if (this.tiles[i][n].num == this.num) { 191 this.moveJ = n; 192 this.num *= 2; 193 if (this.num == 2048) { 194 this.gameWin(); //同理 195 } 196 this.getScore(this.num); 197 break; 198 } 199 } 200 this.moveI = i; 201 if (!(this.moveI + 1) || !(this.moveJ + 1)) { 202 return; 203 } 204 return true; 205 }, 206 207 downMove: function (i, j) { //与左移同理 208 let len = this.tiles.length; 209 this.num = this.tiles[i][j].num; 210 this.moveI = undefined; 211 this.moveJ = undefined; 212 for (let n = j + 1; n < len; n++) { 213 if (this.tiles[i][n].num == 0) { 214 this.moveJ = n; 215 } else if (this.tiles[i][n].num == this.num) { 216 this.moveJ = n; 217 this.num *= 2; 218 if (this.num == 2048) { 219 this.gameWin(); //同理 220 } 221 this.getScore(this.num); 222 break; 223 } 224 } 225 this.moveI = i; 226 if (!(this.moveI + 1) || !(this.moveJ + 1)) { 227 return; 228 } 229 return true; 230 }, 231 232 //合并方块 233 merge: function (i, j) { 234 let me = this; //记录this指向 235 if (this.num > this.tiles[i][j].num) { 236 //this.num的值变化,即遇到相同值的方块,可移动到其位置,只需删除被覆盖的方块 237 this.deleteTile(false, this.tiles[this.moveI][this.moveJ].tile); 238 this.posArray.push({ x: i, y: j }); 239 } else if (this.num == this.tiles[i][j].num) { 240 this.posArray.forEach(function (item) { // binali 241 if (item.x == me.moveI && item.y == me.moveJ) { 242 item.x = i; 243 item.y = j; 244 } 245 }); 246 } 247 //设置将移动的方块的属性,产生移动效果 248 this.setTile(this.tiles[i][j].tile, this.num, this.moveI, this.moveJ); 249 //在存方块数值与dom对象的数组中将移动的方块的值设为空白值(即num:0),被覆盖的方块的值设为将移动的方块的值 250 this.tiles[this.moveI][this.moveJ] = { num: this.num, tile: this.tiles[i][j].tile }; 251 this.tiles[i][j] = { num: 0 }; 252 return true; 253 }, 254 255 256 //删除方块节点 257 deleteTile: function (all, tile) { 258 if (all) { 259 this.tileContainer.innerHTML = ""; //clear; 260 } else { 261 this.tileContainer.removeChild(tile);//删除单个方块 262 } 263 }, 264 265 266 //计算得分 267 getScore: function (score) { 268 this.score += score; 269 this.scoreEle.innerHTML = this.score; 270 if (this.score > this.bestScore) { 271 this.bestScore = this.score // 分数超过时 , 就刷新 最高记录 272 this.bestScoreEle.innerHTML = this.bestScore; 273 } 274 }, 275 276 //出现2048 gameOver 也可以继续挑战 277 gameWin: function () { 278 let me = this; 279 let win = document.createElement("div"); 280 let continueBtn = document.createElement("button"); 281 continueBtn.className = "game-win-again"; 282 win.className = "game-win"; 283 win.appendChild(continueBtn); 284 this.tileContainer.appendChild(win); 285 EventUtil.addHandler(continueBtn, "click", function () { 286 me.deleteTile(false, win); 287 }); 288 }, 289 290 // 没有方向移动 gameOver 291 //test 292 gameOverTest: function () { 293 let len = this.tiles.length; 294 for (let i = 0; i < len; i++) { 295 for (let j = 0; j < len; j++) { 296 if (this.leftMove(i, j) || this.rightMove(i, j) || this.upMove(i, j) || this.downMove(i, j)) { 297 return; //任意方向 可以移动就继续游戏 298 } 299 } 300 } 301 return true; 302 }, 303 304 //游戏结束 消息 305 gameOver: function () { 306 let message = document.createElement("div"); 307 message.className = "game-over"; 308 this.tileContainer.appendChild(message); 309 }, 310 311 312 //添加事件处理程序???? 313 initEvent: function () { 314 let me = this; 315 console.log(this); //指向了game2048 对象 ; 316 //限制键盘一直重复触发 317 EventUtil.addHandler(window, "keyup", function (event) { 318 me.moveTile(EventUtil.getEvent(event).keyCode); 319 }) 320 }, 321 322 } 323 324 325 window.onload = function () { 326 let btn = document.getElementById("newGame"); 327 let tileContainer = document.getElementById("tile-container"); 328 let scoreEle = document.getElementById("game-score"); 329 let bestScoreEle = document.getElementById("game-best-score"); 330 var startX, startY, endX, endY; 331 var game = game || new Game2048(tileContainer, scoreEle, bestScoreEle); 332 //创建Game对象 传入game需要的参数 333 334 game.initEvent();//初始化事件处理??? 335 game.init(); //初始化游戏 336 337 EventUtil.addHandler(btn, "click", function () { 338 game.init(); 339 //点击newgame 初始化游戏 340 }); 341 }
上面是js部分
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> 7 <link rel="stylesheet" type="text/css" href="style.css"> 8 <title>2048</title> 9 </head> 10 11 <body> 12 <div class="container" id="container"> 13 <div class="header"> 14 <h1 class="game-title">2048</h1> 15 <div class="game-info"> 16 <span id="game-best-score">0</span> 17 <span id="game-score">0</span> 18 <button id="newGame" type="button">New Game</button> 19 </div> 20 </div> 21 <div class="game-container" id="game-container"> 22 <div class="game-result"> 23 <p></p> 24 </div> 25 <div class="gird-container"> 26 <div class="gird-row"> 27 <div class="gird-col"></div> 28 <div class="gird-col"></div> 29 <div class="gird-col"></div> 30 <div class="gird-col"></div> 31 </div> 32 <div class="gird-row"> 33 <div class="gird-col"></div> 34 <div class="gird-col"></div> 35 <div class="gird-col"></div> 36 <div class="gird-col"></div> 37 </div> 38 <div class="gird-row"> 39 <div class="gird-col"></div> 40 <div class="gird-col"></div> 41 <div class="gird-col"></div> 42 <div class="gird-col"></div> 43 </div> 44 <div class="gird-row"> 45 <div class="gird-col"></div> 46 <div class="gird-col"></div> 47 <div class="gird-col"></div> 48 <div class="gird-col"></div> 49 </div> 50 </div> 51 <div class="tile-container" id="tile-container"></div> 52 </div> 53 </div> 54 <!-- <script type="text/javascript" src="main.js"></script> --> 55 <script type="text/javascript" src="Game2048.js"></script> 56 </body> 57 58 </html>
HTML部分
1 * { 2 margin: 0; 3 padding: 0; 4 } 5 6 .container { 7 width: 500px; 8 height: 640px; 9 position: absolute; 10 top: 0; 11 left: 0; 12 right: 0; 13 bottom: 0; 14 margin: auto; 15 font-family: "微软雅黑"; 16 } 17 18 .header { 19 height: 120px; 20 margin-bottom: 20px; 21 } 22 23 .game-title { 24 font-size: 50px; 25 color: #776e65; 26 text-align: center; 27 margin-bottom: 10px; 28 } 29 30 .game-info { 31 height: 40px; 32 } 33 34 #game-score, #game-best-score { 35 height: 100%; 36 float: left; 37 min-width: 65px; 38 background-color: #bbada0; 39 color: #fff; 40 font-size: 18px; 41 border-radius: 5px; 42 text-align: center; 43 line-height: 58px; 44 position: relative; 45 } 46 47 #game-score:after { 48 content: "Score"; 49 position: absolute; 50 width: 100%; 51 left: 0; 52 top: -21px; 53 text-align: center; 54 color: #e9dfd4; 55 font-size: 13px; 56 } 57 58 #game-best-score { 59 margin-right: 15px; 60 } 61 62 #game-best-score:after { 63 content: "Best"; 64 position: absolute; 65 width: 100%; 66 left: 0; 67 top: -21px; 68 text-align: center; 69 color: #e9dfd4; 70 font-size: 13px; 71 } 72 73 #newGame { 74 height: 100%; 75 width: 100px; 76 float: right; 77 border-radius: 5px; 78 background-color: #8f7a66; 79 border: none; 80 box-shadow: none; 81 color: #fff; 82 font-size: 16px; 83 cursor: pointer; 84 } 85 86 #newGame:focus { 87 outline: none; 88 } 89 90 .game-container { 91 width: 500px; 92 height: 500px; 93 position: relative; 94 background-color: #bbada0; 95 padding: 15px; 96 border-radius: 5px; 97 box-sizing: border-box; 98 -moz-box-sizing: border-box; 99 /* Firefox */ 100 -webkit-box-sizing: border-box; 101 /* Safari */ 102 } 103 104 .gird-container { 105 width: 470px; 106 height: 470px; 107 } 108 109 .gird-row { 110 width: 470px; 111 height: 106.25px; 112 margin-bottom: 15px; 113 clear: both; 114 } 115 116 .gird-row:last-child { 117 margin-bottom: 0; 118 } 119 120 .gird-col { 121 width: 106.25px; 122 height: 106.25px; 123 margin-right: 15px; 124 background-color: #cdc1b4; 125 float: left; 126 } 127 128 .gird-col:last-child { 129 margin-right: 0; 130 } 131 132 .tile-container { 133 color: #f9f6f2; 134 width: 470px; 135 height: 470px; 136 position: absolute; 137 top: 15px; 138 } 139 140 .game-over { 141 position: absolute; 142 top: 0; 143 bottom: 0; 144 left: 0; 145 right: 0; 146 z-index: 10; 147 background-color: rgba(204, 204, 204, 0.5); 148 } 149 150 .game-over:after { 151 content: "Game Over"; 152 font-size: 60px; 153 color: #fff; 154 position: absolute; 155 top: 0; 156 bottom: 0; 157 left: 0; 158 right: 0; 159 height: 70px; 160 margin: auto; 161 text-align: center; 162 } 163 164 .game-win { 165 position: absolute; 166 top: 0; 167 bottom: 0; 168 left: 0; 169 right: 0; 170 z-index: 10; 171 background-color: rgba(204, 204, 204, 0.5); 172 } 173 174 .game-win:after { 175 content: "You Win"; 176 font-size: 60px; 177 color: #fff; 178 position: absolute; 179 top: 0; 180 bottom: 0; 181 left: 0; 182 right: 0; 183 height: 70px; 184 margin: auto; 185 text-align: center; 186 } 187 188 .game-win-again { 189 width: 160px; 190 height: 50px; 191 border-radius: 5px; 192 background-color: #8f7a66; 193 border: none; 194 box-shadow: none; 195 color: #fff; 196 cursor: pointer; 197 position: absolute; 198 bottom: 120px; 199 left: 0; 200 right: 0; 201 margin: auto; 202 font-size: 30px; 203 } 204 205 .game-win-again:after { 206 content: "Continue"; 207 } 208 209 .tile { 210 position: absolute; 211 width: 106.25px; 212 height: 106.25px; 213 text-align: center; 214 line-height: 106.25px; 215 font-size: 50px; 216 top: 0; 217 transition: transform 150ms ease-out; 218 -moz-transition: transform 150ms ease-out; 219 /* Firefox 4 */ 220 -webkit-transition: transform 150ms ease-out; 221 /* Safari 和 Chrome */ 222 -o-transition: transform 150ms ease-out; 223 /* Opera */ 224 animation: tiledisplay 300ms 1; 225 -webkit-animation: tiledisplay 300ms 1; 226 /* Safari 和 Chrome */ 227 } 228 229 @keyframes tiledisplay { 230 0% { 231 opacity: 0; 232 filter: alpha(opacity=0); 233 } 234 50% { 235 opacity: 0; 236 filter: alpha(opacity=0); 237 } 238 100% { 239 opacity: 1; 240 filter: alpha(opacity=100); 241 } 242 } 243 244 @-webkit-keyframes tiledisplay 245 /* Safari and Chrome */ 246 247 { 248 0% { 249 opacity: 0; 250 filter: alpha(opacity=0); 251 } 252 50% { 253 opacity: 0; 254 filter: alpha(opacity=0); 255 } 256 100% { 257 opacity: 1; 258 filter: alpha(opacity=100); 259 } 260 } 261 262 .tile-container .tile-2 { 263 color: #776e65; 264 background: #eee4da; 265 } 266 267 .tile-container .tile-4 { 268 color: #776e65; 269 background: #ede0c8; 270 } 271 272 .tile-container .tile-8 { 273 background: #f2b179; 274 } 275 276 .tile-container .tile-16 { 277 background: #f59563; 278 } 279 280 .tile-container .tile-32 { 281 background: #f67c5f; 282 } 283 284 .tile-container .tile-64 { 285 background: #f65e3b; 286 } 287 288 .tile-container .tile-128 { 289 background: #edcf72; 290 } 291 292 .tile-container .tile-256 { 293 background: #edcc61; 294 } 295 296 .tile-container .tile-512 { 297 background: #edc850; 298 } 299 300 .tile-container .tile-1024 { 301 background: #edc53f; 302 } 303 304 .tile-container .tile-2048 { 305 background: #edc22e; 306 } 307 308 .tile-container .tile-pos-0-0 { 309 -webkit-transform: translate(0, 0); 310 -ms-transform: translate(0, 0); 311 -o-transform: translate(0, 0); 312 transform: translate(0, 0); 313 } 314 315 .tile-container .tile-pos-0-1 { 316 -webkit-transform: translate(0, 121.25px); 317 -ms-transform: translate(0, 121.25px); 318 -o-transform: translate(0, 121.25px); 319 transform: translate(0, 121.25px); 320 } 321 322 .tile-container .tile-pos-0-2 { 323 -webkit-transform: translate(0, 242.5px); 324 -ms-transform: translate(0, 242.5px); 325 -o-transform: translate(0, 242.5px); 326 transform: translate(0, 242.5px); 327 } 328 329 .tile-container .tile-pos-0-3 { 330 -webkit-transform: translate(0, 363.75px); 331 -ms-transform: translate(0, 363.75px); 332 -o-transform: translate(0, 363.75px); 333 transform: translate(0, 363.75px); 334 } 335 336 .tile-container .tile-pos-1-0 { 337 -webkit-transform: translate(121.25px, 0); 338 -ms-transform: translate(121.25px, 0); 339 -o-transform: translate(121.25px, 0); 340 transform: translate(121.25px, 0); 341 } 342 343 .tile-container .tile-pos-1-1 { 344 -webkit-transform: translate(121.25px, 121.25px); 345 -ms-transform: translate(121.25px, 121.25px); 346 -o-transform: translate(121.25px, 121.25px); 347 transform: translate(121.25px, 121.25px); 348 } 349 350 .tile-container .tile-pos-1-2 { 351 -webkit-transform: translate(121.25px, 242.5px); 352 -ms-transform: translate(121.25px, 242.5px); 353 -o-transform: translate(121.25px, 242.5px); 354 transform: translate(121.25px, 242.5px); 355 } 356 357 .tile-container .tile-pos-1-3 { 358 -webkit-transform: translate(121.25px, 363.75px); 359 -ms-transform: translate(121.25px, 363.75px); 360 -o-transform: translate(121.25px, 363.75px); 361 transform: translate(121.25px, 363.75px); 362 } 363 364 .tile-container .tile-pos-2-0 { 365 -webkit-transform: translate(242.5px, 0); 366 -ms-transform: translate(242.5px, 0); 367 -o-transform: translate(242.5px, 0); 368 transform: translate(242.5px, 0); 369 } 370 371 .tile-container .tile-pos-2-1 { 372 -webkit-transform: translate(242.5px, 121.25px); 373 -ms-transform: translate(242.5px, 121.25px); 374 -o-transform: translate(242.5px, 121.25px); 375 transform: translate(242.5px, 121.25px); 376 } 377 378 .tile-container .tile-pos-2-2 { 379 -webkit-transform: translate(242.5px, 242.5px); 380 -ms-transform: translate(242.5px, 242.5px); 381 -o-transform: translate(242.5px, 242.5px); 382 transform: translate(242.5px, 242.5px); 383 } 384 385 .tile-container .tile-pos-2-3 { 386 -webkit-transform: translate(242.5px, 363.75px); 387 -ms-transform: translate(242.5px, 363.75px); 388 -o-transform: translate(242.5px, 363.75px); 389 transform: translate(242.5px, 363.75px); 390 } 391 392 .tile-container .tile-pos-3-0 { 393 -webkit-transform: translate(363.75px, 0); 394 -ms-transform: translate(363.75px, 0); 395 -o-transform: translate(363.75px, 0); 396 transform: translate(363.75px, 0); 397 } 398 399 .tile-container .tile-pos-3-1 { 400 -webkit-transform: translate(363.75px, 121.25px); 401 -ms-transform: translate(363.75px, 121.25px); 402 -o-transform: translate(363.75px, 121.25px); 403 transform: translate(363.75px, 121.25px); 404 } 405 406 .tile-container .tile-pos-3-2 { 407 -webkit-transform: translate(363.75px, 242.5px); 408 -ms-transform: translate(363.75px, 242.5px); 409 -o-transform: translate(363.75px, 242.5px); 410 transform: translate(363.75px, 242.5px); 411 } 412 413 .tile-container .tile-pos-3-3 { 414 -webkit-transform: translate(363.75px, 363.75px); 415 -ms-transform: translate(363.75px, 363.75px); 416 -o-transform: translate(363.75px, 363.75px); 417 transform: translate(363.75px, 363.75px); 418 } 419 420 @media screen and (max-width: 525px) { 421 .container { 422 width: 280px; 423 height: 405px; 424 } 425 .header { 426 height: 110px; 427 margin-bottom: 15px; 428 } 429 .game-info { 430 height: 40px; 431 } 432 .game-title { 433 font-size: 50px; 434 } 435 .game-container { 436 width: 280px; 437 height: 280px; 438 padding: 7px; 439 } 440 .gird-container { 441 width: 266px; 442 height: 266px; 443 } 444 .gird-row { 445 width: 266px; 446 height: 61.25px; 447 margin-bottom: 7px; 448 } 449 .gird-col { 450 width: 61.25px; 451 height: 61.25px; 452 margin-right: 7px; 453 } 454 .tile-container { 455 width: 266px; 456 height: 266px; 457 top: 7px; 458 } 459 .game-over:after { 460 font-size: 40px; 461 height: 70px; 462 } 463 .game-win:after { 464 font-size: 45px; 465 height: 60px; 466 } 467 .game-win-again { 468 width: 130px; 469 height: 40px; 470 bottom: 60px; 471 font-size: 25px; 472 } 473 .game-win-again:after { 474 content: "Continue"; 475 } 476 .tile { 477 width: 61.25px; 478 height: 61.25px; 479 line-height: 61.25px; 480 font-size: 35px; 481 } 482 .tile-container .tile-pos-0-1 { 483 -webkit-transform: translate(0, 68.25px); 484 -ms-transform: translate(0, 68.25px); 485 -o-transform: translate(0, 68.25px); 486 transform: translate(0, 68.25px); 487 } 488 .tile-container .tile-pos-0-2 { 489 -webkit-transform: translate(0, 136.5px); 490 -ms-transform: translate(0, 136.5px); 491 -o-transform: translate(0, 136.5px); 492 transform: translate(0, 136.5px); 493 } 494 .tile-container .tile-pos-0-3 { 495 -webkit-transform: translate(0, 204.75px); 496 -ms-transform: translate(0, 204.75px); 497 -o-transform: translate(0, 204.75px); 498 transform: translate(0, 204.75px); 499 } 500 .tile-container .tile-pos-1-0 { 501 -webkit-transform: translate(68.25px, 0); 502 -ms-transform: translate(68.25px, 0); 503 -o-transform: translate(68.25px, 0); 504 transform: translate(68.25px, 0); 505 } 506 .tile-container .tile-pos-1-1 { 507 -webkit-transform: translate(68.25px, 68.25px); 508 -ms-transform: translate(68.25px, 68.25px); 509 -o-transform: translate(68.25px, 68.25px); 510 transform: translate(68.25px, 68.25px); 511 } 512 .tile-container .tile-pos-1-2 { 513 -webkit-transform: translate(68.25px, 136.5px); 514 -ms-transform: translate(68.25px, 136.5px); 515 -o-transform: translate(68.25px, 136.5px); 516 transform: translate(68.25px, 136.5px); 517 } 518 .tile-container .tile-pos-1-3 { 519 -webkit-transform: translate(68.25px, 204.75px); 520 -ms-transform: translate(68.25px, 204.75px); 521 -o-transform: translate(68.25px, 204.75px); 522 transform: translate(68.25px, 204.75px); 523 } 524 .tile-container .tile-pos-2-0 { 525 -webkit-transform: translate(136.5px, 0); 526 -ms-transform: translate(136.5px, 0); 527 -o-transform: translate(136.5px, 0); 528 transform: translate(136.5px, 0); 529 } 530 .tile-container .tile-pos-2-1 { 531 -webkit-transform: translate(136.5px, 68.25px); 532 -ms-transform: translate(136.5px, 68.25px); 533 -o-transform: translate(136.5px, 68.25px); 534 transform: translate(136.5px, 68.25px); 535 } 536 .tile-container .tile-pos-2-2 { 537 -webkit-transform: translate(136.5px, 136.5px); 538 -ms-transform: translate(136.5px, 136.5px); 539 -o-transform: translate(136.5px, 136.5px); 540 transform: translate(136.5px, 136.5px); 541 } 542 .tile-container .tile-pos-2-3 { 543 -webkit-transform: translate(136.5px, 204.75px); 544 -ms-transform: translate(136.5px, 204.75px); 545 -o-transform: translate(136.5px, 204.75px); 546 transform: translate(136.5px, 204.75px); 547 } 548 .tile-container .tile-pos-3-0 { 549 -webkit-transform: translate(204.75px, 0); 550 -ms-transform: translate(204.75px, 0); 551 -o-transform: translate(204.75px, 0); 552 transform: translate(204.75px, 0); 553 } 554 .tile-container .tile-pos-3-1 { 555 -webkit-transform: translate(204.75px, 68.25px); 556 -ms-transform: translate(204.75px, 68.25px); 557 -o-transform: translate(204.75px, 68.25px); 558 transform: translate(204.75px, 68.25px); 559 } 560 .tile-container .tile-pos-3-2 { 561 -webkit-transform: translate(204.75px, 136.5px); 562 -ms-transform: translate(204.75px, 136.5px); 563 -o-transform: translate(204.75px, 136.5px); 564 transform: translate(204.75px, 136.5px); 565 } 566 .tile-container .tile-pos-3-3 { 567 -webkit-transform: translate(204.75px, 204.75px); 568 -ms-transform: translate(204.75px, 204.75px); 569 -o-transform: translate(204.75px, 204.75px); 570 transform: translate(204.75px, 204.75px); 571 } 572 }