对于练习JavaScript的同学来说,这个小练习项目是很有大帮助的,因为么有采用像JQuery、Vue等js库来编写,而是使用的元素js实现
这样对于加强js内功是有很大帮助的,
效果如下:
对于上示意图,点击相邻近的相同图片之后会自动消除
代码如下:(用到的图片素材下载地址:https://www.itprojects.cn/detail.html?example_id=4b6c44ca4a3f7fc439a3f30880b14cc6)
html
1 <html> 2 <head> 3 <title>连连看 - it项目实例网 www.itprojects.cn</title> 4 </head> 5 <script src="link.js"></script> 6 <body> 7 <table cellpadding=0 cellspacing=0><tr><td><tbody style="background-color:black;" id="gamecanvas"></tbody></td></tr></table> 8 <script> 9 var width = 14; 10 var height = 14; 11 var eleWidth = 40; 12 var eleHeight = 40; 13 var gameEles = new Array(); 14 var linkStack = new Array(); 15 var lock = false; 16 function createCanvas(_width,_height){ 17 var gc = document.getElementById("gamecanvas"); 18 var tempEles; 19 var tempEle; 20 var tempTr; 21 var tempTd; 22 for(var x = 0 ; x < _width ; x++){ 23 tempEles = new Array(); 24 tempTr = document.createElement("tr"); 25 tempTr.style.height = eleHeight+"px"; 26 for(var y = 0 ; y < _height ; y++){ 27 tempEle = document.createElement("img"); 28 tempEle.setAttribute("src","img/"+points[x][y].value+".jpg"); 29 tempEle.setAttribute("id","ele"+x+"_"+y); 30 tempEle.style.width = eleWidth+"px"; 31 tempEle.style.height = eleHeight+"px"; 32 if(x>1 && x<_width-2 && y>1 && y<_height-2){ 33 tempEle.onclick = eleChoose; 34 } 35 tempTd = document.createElement("td"); 36 tempTd.style.width = eleWidth+"px"; 37 tempTd.style.textAlign = "center"; 38 tempTd.appendChild(tempEle); 39 tempTr.appendChild(tempTd); 40 gc.appendChild(tempTr); 41 tempEles[y] = tempEle; 42 } 43 gameEles[x] = tempEles; 44 } 45 } 46 function eleChoose(_event){ 47 if(lock){ 48 return; 49 } 50 lock = true; 51 var event; 52 var p; 53 var path; 54 if(window.event){ 55 event = window.event; 56 p = getPoint(event.srcElement.getAttribute("id")); 57 } 58 else{ 59 event = _event; 60 p = getPoint(event.target.getAttribute("id")); 61 } 62 if(linkStack.length == 0){ 63 choose(p); 64 linkStack.push(p); 65 } 66 else{ 67 if(p.x == linkStack[0].x && p.y == linkStack[0].y){ 68 unchoose(linkStack.pop()); 69 lock = false; 70 return; 71 } 72 choose(p); 73 if(p.value == linkStack[0].value){ 74 path = linkPoints(linkStack[0],p); 75 if(path){ 76 unchoose(linkStack.pop()); 77 unchoose(p); 78 linkSus(path); 79 } 80 else{ 81 path = linkPoints(p,linkStack[0]); 82 if(path){ 83 unchoose(linkStack.pop()); 84 unchoose(p); 85 linkSus(path); 86 } 87 else{ 88 unchoose(linkStack.pop()); 89 linkStack.push(p); 90 } 91 } 92 } 93 else{ 94 unchoose(linkStack.pop()); 95 linkStack.push(p); 96 } 97 } 98 lock = false; 99 } 100 101 function choose(_point){ 102 var gameEle = gameEles[_point.x][_point.y]; 103 gameEle.style.width = eleWidth-2+"px"; 104 gameEle.style.height = eleHeight-2+"px"; 105 } 106 107 function unchoose(_point){ 108 var gameEle = gameEles[_point.x][_point.y]; 109 gameEle.style.width = eleWidth+"px"; 110 gameEle.style.height = eleHeight+"px"; 111 } 112 113 function linkSus(_path){ 114 var sourcePoint = _path.shift(); 115 var targetPoint = _path.pop(); 116 sourcePoint.value = 0; 117 targetPoint.value = 0; 118 var sourceEle = gameEles[sourcePoint.x][sourcePoint.y]; 119 var targetEle = gameEles[targetPoint.x][targetPoint.y]; 120 sourceEle.onclick=null; 121 sourceEle.setAttribute("src","img/0.jpg"); 122 targetEle.onclick=null; 123 targetEle.setAttribute("src","img/0.jpg"); 124 } 125 126 function getPoint(_id){ 127 var patterner = /ele(\d+)_(\d+)/; 128 var result = _id.match(patterner); 129 return points[result[1]][result[2]]; 130 } 131 132 createPoints(width,height); 133 createCanvas(width,height); 134 </script> 135 </body> 136 </html>
JS
1 function _index(_value){ 2 for(var v in this){ 3 if(this[v] == _value){ 4 return new Number(v) 5 } 6 } 7 return -1; 8 } 9 10 function _remove(_value){ 11 var _index = this.index(_value); 12 this.splice(_index,1); 13 } 14 15 function _insert(_position,_value){ 16 this.splice(_position,0,_value); 17 } 18 19 Array.prototype.index = _index; 20 Array.prototype.insert = _insert; 21 Array.prototype.remove = _remove; 22 23 function Point(_x,_y,_value){ 24 this.x = _x; 25 this.y = _y; 26 this.value = _value; 27 this.directs = null; 28 this.changed = 0; 29 } 30 31 function _createDirect(_pre,_target){ 32 this.directs = new Array(); 33 var stx = _target.x - this.x; 34 var sty = _target.y - this.y; 35 if(stx >= 0){ 36 this.directs.push("right"); 37 this.directs.push("left"); 38 } 39 else{ 40 this.directs.push("left"); 41 this.directs.push("right"); 42 } 43 if(sty >= 0){ 44 this.directs.insert(1,"up"); 45 this.directs.push("down"); 46 } 47 else{ 48 this.directs.insert(1,"down"); 49 this.directs.push("up"); 50 } 51 if (_pre == null){ 52 return ; 53 } 54 var spx = _pre.x - this.x; 55 var spy = _pre.y - this.y; 56 if (spx == 0){ 57 if (spy == 1){ 58 this.directs.remove("up"); 59 } 60 else{ 61 this.directs.remove("down"); 62 } 63 } 64 else{ 65 if (spx == 1){ 66 this.directs.remove("right"); 67 } 68 else{ 69 this.directs.remove("left"); 70 } 71 } 72 } 73 74 function _forward(_pre,_target){ 75 if(this.directs == null){ 76 this.createDirect(_pre,_target); 77 } 78 if(this.directs.length == 0){ 79 return null; 80 } 81 var direct = null; 82 var tmpDirect = null; 83 var x = null; 84 var y = null; 85 var p = null; 86 while(true){ 87 if(this.directs.length == 0){ 88 break; 89 } 90 tmpDirect = this.directs.shift(); 91 switch(tmpDirect){ 92 case "up": 93 x = this.x; 94 y = this.y + 1; 95 break; 96 case "down": 97 x = this.x; 98 y = this.y - 1; 99 break; 100 case "left": 101 x = this.x - 1; 102 y = this.y; 103 break; 104 case "right": 105 x = this.x + 1; 106 y = this.y; 107 break; 108 default: 109 throw new Error("error direct"); 110 break; 111 } 112 p = points[x][y]; 113 if(p.value > 0 && p != _target){ 114 continue; 115 } 116 else{ 117 direct = tmpDirect; 118 if(_pre == null){ 119 this.changed = 1; 120 } 121 else{ 122 if((_pre.x - this.x) == 0 && (p.x - this.x) == 0){ 123 this.changed = 0; 124 } 125 else{ 126 if((_pre.y - this.y) == 0 && (p.y - this.y) == 0){ 127 this.changed = 0; 128 } 129 else{ 130 this.changed = 1; 131 } 132 } 133 } 134 break; 135 } 136 } 137 return direct; 138 } 139 140 function _equals(_point){ 141 if (_point == null){ 142 return false; 143 } 144 if (this.x == _point.x && this.y == _point.y){ 145 return true; 146 } 147 else{ 148 return false; 149 } 150 } 151 152 Point.prototype.createDirect = _createDirect; 153 Point.prototype.forward = _forward; 154 Point.prototype.equals = _equals; 155 156 var points = new Array(); 157 var valueStack = new Array(); 158 159 function createPoints(w,h){ 160 var temp; 161 var tempValue; 162 pointStack(w,h); 163 for(var _x = 0 ; _x < w ; _x++){ 164 temp = new Array(); 165 for(var _y = 0 ; _y < h ; _y++){ 166 if(_x == 0 || _x == (w-1) || _y == 0 || _y == (h-1)){ 167 tempValue = 9; 168 } 169 else{ 170 if(_x == 1 || _x == (w-2) || _y == 1 || _y == (h-2)){ 171 tempValue = 0; 172 } 173 else{ 174 tempValue = valueStack.pop(); 175 } 176 } 177 temp[_y] = new Point(_x,_y,tempValue); 178 } 179 points[_x] = temp; 180 } 181 } 182 183 function pointStack(w,h){ 184 var size = (w*h-(w*4+h*4-16))/2; 185 var pointValue; 186 for(var i = 0 ; i < size ; i++){ 187 while(true){ 188 pointValue = Math.floor(Math.random()*9); 189 if(pointValue != 0){ 190 break; 191 } 192 } 193 valueStack.insert(Math.floor(Math.random()*valueStack.length),pointValue); 194 valueStack.insert(Math.floor(Math.random()*valueStack.length),pointValue); 195 } 196 } 197 198 function linkPoints(_source,_target){ 199 var path = new Array(); 200 var fail = new Object(); 201 var change = 0; 202 var _current = _source; 203 var direct = null; 204 var _x,_y; 205 while(true){ 206 //alert("current--"+pointStr(_current)+"change:"+change); 207 if(_current == _target && change < 4){ 208 path.push(_target); 209 for(var p in path){ 210 path[p].directs = null; 211 } 212 return path; 213 } 214 if(change == 4){ 215 _current.directs = null; 216 fail[(_current.x+"_"+_current.y)] = change; 217 _current = path.pop(); 218 change = change - _current.changed; 219 continue; 220 } 221 if(_current == _source){ 222 direct = _current.forward(null,_target); 223 } 224 else{ 225 direct = _current.forward(path[path.length-1],_target); 226 } 227 if(direct != null){ 228 if(direct == "up"){ 229 _x = _current.x; 230 _y = _current.y + 1; 231 } 232 if(direct == "down"){ 233 _x = _current.x; 234 _y = _current.y - 1; 235 } 236 if(direct == "left"){ 237 _x = _current.x - 1; 238 _y = _current.y ; 239 } 240 if(direct == "right"){ 241 _x = _current.x + 1; 242 _y = _current.y; 243 } 244 if(fail[(_x+"_"+_y)] != null){ 245 if (change >= fail[(_x+"_"+_y)]){ 246 continue; 247 } 248 else{ 249 delete fail[(_x+"_"+_y)]; 250 } 251 } 252 change = change + _current.changed; 253 path.push(_current); 254 _current = points[_x][_y]; 255 } 256 else{ 257 if(_current == _source){ 258 _source.directs = null; 259 return false; 260 } 261 else{ 262 _current.directs = null; 263 fail[(_current.x+"_"+_current.y)] = change; 264 _current = path.pop(); 265 change = change - _current.changed; 266 } 267 } 268 } 269 } 270 271 /*function pointStr(p){ 272 return " x:"+p.x+" y:"+p.y+" value:"+p.value; 273 } 274 */