小時候想玩沒的玩的小遊戲,如今本身寫一個.
簡單實現 俄羅斯方塊 初級版 ,有空實現個三維的。javascript
自己實現代碼都比較簡單,不對代碼做說明了。css
一、index.htmlhtml
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>rasian square</title> <style type="text/css"> *{margin: 0;padding: 0;} table{display: block;margin: 20px auto;width: 200px;} table,td{border: 1px solid #999999;border-collapse: collapse;} td{width: 20px;height: 20px;line-height: 20px;text-align: center;} .center{text-align: center;} </style> </head> <body> <div class="center"> 得分:<span id="score">0</span> </div> <table></table> <div class="center"> <button onclick="start()">開始</button> <button onclick="reload()">從新開始</button> <button onclick="rotate()">旋轉</button> </div> <script type="text/javascript" src="./js/common.js"></script> <script type="text/javascript" src="./js/data.js"></script> <script type="text/javascript" src="./js/game.js"></script> <script type="text/javascript" src="./js/block.js"></script> <script type="text/javascript"> var rows = 20, verticals = 10, speed = 200, datas = Array.prototype.slice.call(Object.keys(data)), g = new Game(rows, verticals), block, fixedData = [], scores = 0; function start() { block = new square[datas[Math.floor(Math.random()*datas.length)]](speed); var timer = setInterval(function(){ //觸底 for(var i = 0;i < 4;i++) { if(block.body[i]["x"] >= rows - 1) { fixedData = fixedData.concat(block.body); clearInterval(block.move); block = new square[datas[Math.floor(Math.random()*datas.length)]](speed); }; for(var j = 0;j < fixedData.length; j++) { //積累超出畫布,遊戲結束 if(block.body[i]["x"] + 1 == fixedData[j]["x"] && block.body[i]["y"] == fixedData[j]["y"] && block.body[i]["x"] < 0) { clearInterval(block.move); clearInterval(timer); }; //碰到已有塊 if(block.body[i]["x"] + 1 == fixedData[j]["x"] && block.body[i]["y"] == fixedData[j]["y"]) { fixedData = fixedData.concat(block.body); clearInterval(block.move); block = new square[datas[Math.floor(Math.random()*datas.length)]](speed); } }; }; score(); var renderData = fixedData.concat(block.body); g.render(renderData); },speed); }; function rotate() { clearInterval(block.move); block.rotate(); for(var i = 0;i < 4;i++) { if(block.body[i]["y"] < 0 || block.body[i]["y"] >= verticals || block.body[i]["x"] >= rows) { block.body = block.preBody; }; }; block.move = setInterval(function(){block.down()}, speed); }; function reload() { window.location.reload(); }; function judgeLeftOrRight(direction) { for(var i = 0;i < 4;i++) { if(direction == 'left' ? block.body[i]["y"] <= 0 : block.body[i]["y"] >= verticals - 1 ) { return true; }; for(var j = 0;j < fixedData.length; j++) { if(block.body[i]["x"] == fixedData[j]["x"] && (direction == 'left' ? block.body[i]["y"] - 1 : block.body[i]["y"] + 1) == fixedData[j]["y"]) { return true; } }; }; return false; }; function moveLeftOrRight(direction) { clearInterval(block.move); for(var i = 0;i < 4;i++) { direction == 'left' ? block.body[i].y -= 1 : block.body[i].y += 1; }; block.move = setInterval(function(){block.down()}, speed); }; function score() { var map = {}; for(var j = 0;j < fixedData.length; j++) { var temp = fixedData[j]["x"]; if(map[temp]) { map[temp] += 1; }else{ map[temp] = 1; } }; for(key in map) { if(map[key] == verticals) { fixedData = fixedData.filter(function(item) { return item.x != key; }); for(var j = 0;j < fixedData.length; j++) { if(fixedData[j]["x"] < key) { fixedData[j]["x"] += 1; } }; scores += 100; document.getElementById("score").innerHTML = scores; } }; }; document.onkeydown = function(event){ event = event || window.event; if(event.keyCode == 37) { //left if(!judgeLeftOrRight('left')) { moveLeftOrRight('left'); } } else if (event.keyCode == 39) { //right if(!judgeLeftOrRight('right')) { moveLeftOrRight('right'); } } else if (event.keyCode == 32) { //space rotate(); } }; </script> </body> </html>
二、common.js 這個方法以前百度上面看到,就蠻用了java
var util = (function () { var class2type = {}; ["Null", "Undefined", "Number", "Boolean", "String", "Object", "Function", "Array", "RegExp", "Date"].forEach(function (item) { class2type["[object " + item + "]"] = item.toLowerCase(); }) function isType(obj, type) { return getType(obj) === type; } function getType(obj) { return class2type[Object.prototype.toString.call(obj)] || "object"; } return { isType: isType, getType: getType } })(); //對象深,淺拷貝 function copy(obj, deep) { if (obj === null || typeof obj !== "object") { return obj; } var i, target = this.util.isType(obj, "array") ? [] : {}, value, valueType; for (i in obj) { value = obj[i]; valueType = this.util.getType(value); if (deep && (valueType === "array" || valueType === "object")) { target[i] = this.copy(value); } else { target[i] = value; } } return target; }
三、data.jsapp
var data = { /** * ###### * ## *下折線 **/ DLine : { init: [ {x: -2, y: 4}, {x: -3, y: 4}, {x: -3, y: 5}, {x: -3, y: 6} ], degree0_90: [ {x: -1, y: 0}, {x: 0, y: 1}, {x: 1, y: 0}, {x: 2, y: -1} ], degree90_180: [ {x: 0, y: 1}, {x: 1, y: 0}, {x: 0, y: -1}, {x: -1, y: -2} ], degree180_270: [ {x: 1, y: 0}, {x: 0, y: -1}, {x: -1, y: 0}, {x: -2, y: 1} ], degree270_360: [ {x: 0, y: -1}, {x: -1, y: 0}, {x: 0, y: 1}, {x: 1, y: 2} ] }, /** * ## * ###### *上折線 **/ ULine : { init: [ {x: -3, y: 4}, {x: -3, y: 5}, {x: -3, y: 6}, {x: -4, y: 4} ], degree0_90: [ {x: 0, y: 1}, {x: 1, y: 0}, {x: 2, y: -1}, {x: 1, y: 2} ], degree90_180: [ {x: 1, y: 0}, {x: 0, y: -1}, {x: -1, y: -2}, {x: 2, y: -1} ], degree180_270: [ {x: 0, y: -1}, {x: -1, y: 0}, {x: -2, y: 1}, {x: -1, y: -2} ], degree270_360: [ {x: -1, y: 0}, {x: 0, y: 1}, {x: 1, y: 2}, {x: -2, y: 1} ] }, /** * ## * ## * ## * ## *直線 **/ Line : { init: [ {x: -1, y: 4}, {x: -2, y: 4}, {x: -3, y: 4}, {x: -4, y: 4} ], degree0_90: [ {x: -2, y: -1}, {x: -1, y: 0}, {x: 0, y: 1}, {x: 1, y: 2} ], degree90_180: [ {x: -1, y: 2}, {x: 0, y: 1}, {x: 1, y: 0}, {x: 2, y: -1} ], degree180_270: [ {x: 2, y: 1}, {x: 1, y: 0}, {x: 0, y: -1}, {x: -1, y: -2} ], degree270_360: [ {x: 1, y: -2}, {x: 0, y: -1}, {x: -1, y: 0}, {x: -2, y: 1} ] }, /** * ## * ###### *凸 **/ Raised : { init: [ {x: -2, y: 3}, {x: -2, y: 4}, {x: -2, y: 5}, {x: -3, y: 4} ], degree0_90: [ {x: -2, y: 1}, {x: -1, y: 0}, {x: 0, y: -1}, {x: 0, y: 1} ], degree90_180: [ {x: 1, y: 2}, {x: 0, y: 1}, {x: -1, y: 0}, {x: 1, y: 0} ], degree180_270: [ {x: 2, y: -1}, {x: 1, y: 0}, {x: 0, y: 1}, {x: 0, y: -1} ], degree270_360: [ {x: -1, y: -2}, {x: 0, y: -1}, {x: 1, y: 0}, {x: -1, y: 0} ] }, /** * #### * #### *方塊 **/ Square : { init: [ {x: -2, y: 4}, {x: -2, y: 5}, {x: -3, y: 4}, {x: -3, y: 5} ], degree0_90: [ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0} ], degree90_180: [ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0} ], degree180_270: [ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0} ], degree270_360: [ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0} ] }, /** * #### * #### *左移塊 **/ LSquare : { init: [ {x: -2, y: 4}, {x: -2, y: 5}, {x: -3, y: 3}, {x: -3, y: 4} ], degree0_90: [ {x: -1, y: 0}, {x: 0, y: -1}, {x: -1, y: 2}, {x: 0, y: 1} ], degree90_180: [ {x: 1, y: 2}, {x: 0, y: 1}, {x: 1, y: 0}, {x: 0, y: -1} ], degree180_270: [ {x: 1, y: -2}, {x: 0, y: -1}, {x: 1, y: 0}, {x: 0, y: 1} ], degree270_360: [ {x: -1, y: 0}, {x: 0, y: 1}, {x: -1, y: -2}, {x: 0, y: -1} ] }, /** * #### * #### *右移塊 **/ RSquare : { init: [ {x: -2, y: 4}, {x: -2, y: 5}, {x: -3, y: 5}, {x: -3, y: 6} ], degree0_90: [ {x: -1, y: 0}, {x: 0, y: -1}, {x: 1, y: 0}, {x: 2, y: -1} ], degree90_180: [ {x: 0, y: 1}, {x: -1, y: 0}, {x: 0, y: -1}, {x: -1, y: -2} ], degree180_270: [ {x: 1, y: 0}, {x: 0, y: 1}, {x: -1, y: 0}, {x: -2, y: 1} ], degree270_360: [ {x: 0, y: -1}, {x: 1, y: 0}, {x: 0, y: 1}, {x: 1, y: 2} ] } };
四、game.jsdom
function Game(rows, verticals) { this.rows = rows; this.verticals = verticals; this.tds = []; this.init(); } Game.prototype = { constructor: Game, init: function() { var table= document.getElementsByTagName('table')[0]; for(var i = 0; i < this.rows; i++) { var tr = document.createElement('tr'); var tdsTr = []; for(var j = 0;j < this.verticals; j++) { var td = document.createElement('td'); tr.appendChild(td); tdsTr.push(td); }; table.appendChild(tr); this.tds.push(tdsTr); }; }, render: function(array) { var self = this; if(!util.isType(array, "array")) { console.log('game render data must be array'); return; }; for(var i = 0;i < self.tds.length;i++) { for(var j = 0;j < self.tds[i].length;j++) { self.tds[i][j].style.background = ''; } }; for(var i = 0;i < array.length; i++) { if(self.tds[array[i].x] && self.tds[array[i].x][array[i].y]) { self.tds[array[i].x][array[i].y].style.background = '#999999'; } }; } }
五、block.jsui
; var square = {}; Object.keys(data).forEach(function(obj) { square[obj] = function(speed) { this.speed = speed; this.body = copy(data[obj]['init'],"deep"); this.degree0_90 = data[obj]["degree0_90"]; this.degree90_180 = data[obj]["degree90_180"]; this.degree180_270 = data[obj]["degree180_270"]; this.degree270_360 = data[obj]["degree270_360"]; this.preBody = ''; this.move = ''; this.state = 0; this.init(); }; square[obj].prototype = { constructor: square[obj], init: function() { var self = this; self.move = setInterval(function() { self.down(); }, self.speed); }, down: function() { var self = this; self.preBody = copy(self.body,"deep"); self.body[0]["x"] += 1; self.body[1]["x"] += 1; self.body[2]["x"] += 1; self.body[3]["x"] += 1; // console.log('self.body'); // console.log(self.body); }, rotate: function() { var self = this; self.body[0]["x"] += self['degree'+self.state+'_'+(self.state+90)][0]["x"]; self.body[0]["y"] += self['degree'+self.state+'_'+(self.state+90)][0]["y"]; self.body[1]["x"] += self['degree'+self.state+'_'+(self.state+90)][1]["x"]; self.body[1]["y"] += self['degree'+self.state+'_'+(self.state+90)][1]["y"]; self.body[2]["x"] += self['degree'+self.state+'_'+(self.state+90)][2]["x"]; self.body[2]["y"] += self['degree'+self.state+'_'+(self.state+90)][2]["y"]; self.body[3]["x"] += self['degree'+self.state+'_'+(self.state+90)][3]["x"]; self.body[3]["y"] += self['degree'+self.state+'_'+(self.state+90)][3]["y"]; self.state = self.state == 270 ? 0 : self.state + 90; } } });