对于练习JavaScript的同学来说,这个小练习项目是很有大帮助的,因为么有采用像JQuery、Vue等js库来编写,而是使用的元素js实现
这样对于加强js内功是有很大帮助的,
效果如下:
对于上示意图,点击相邻近的相同图片之后会自动消除
代码如下:(用到的图片素材下载地址:www.itprojects.cn/detail.html…)
html
<html>
<head>
<title>连连看 - it项目实例网 www.itprojects.cn</title>
</head>
<script src="link.js"></script>
<body>
<table cellpadding=0 cellspacing=0><tr><td><tbody style="background-color:black;" id="gamecanvas"></tbody></td></tr></table>
<script>
var width = 14;
var height = 14;
var eleWidth = 40;
var eleHeight = 40;
var gameEles = new Array();
var linkStack = new Array();
var lock = false;
function createCanvas(_width,_height){
var gc = document.getElementById("gamecanvas");
var tempEles;
var tempEle;
var tempTr;
var tempTd;
for(var x = 0 ; x < _width ; x++){
tempEles = new Array();
tempTr = document.createElement("tr");
tempTr.style.height = eleHeight+"px";
for(var y = 0 ; y < _height ; y++){
tempEle = document.createElement("img");
tempEle.setAttribute("src","img/"+points[x][y].value+".jpg");
tempEle.setAttribute("id","ele"+x+"_"+y);
tempEle.style.width = eleWidth+"px";
tempEle.style.height = eleHeight+"px";
if(x>1 && x<_width-2 && y>1 && y<_height-2){
tempEle.onclick = eleChoose;
}
tempTd = document.createElement("td");
tempTd.style.width = eleWidth+"px";
tempTd.style.textAlign = "center";
tempTd.appendChild(tempEle);
tempTr.appendChild(tempTd);
gc.appendChild(tempTr);
tempEles[y] = tempEle;
}
gameEles[x] = tempEles;
}
}
function eleChoose(_event){
if(lock){
return;
}
lock = true;
var event;
var p;
var path;
if(window.event){
event = window.event;
p = getPoint(event.srcElement.getAttribute("id"));
}
else{
event = _event;
p = getPoint(event.target.getAttribute("id"));
}
if(linkStack.length == 0){
choose(p);
linkStack.push(p);
}
else{
if(p.x == linkStack[0].x && p.y == linkStack[0].y){
unchoose(linkStack.pop());
lock = false;
return;
}
choose(p);
if(p.value == linkStack[0].value){
path = linkPoints(linkStack[0],p);
if(path){
unchoose(linkStack.pop());
unchoose(p);
linkSus(path);
}
else{
path = linkPoints(p,linkStack[0]);
if(path){
unchoose(linkStack.pop());
unchoose(p);
linkSus(path);
}
else{
unchoose(linkStack.pop());
linkStack.push(p);
}
}
}
else{
unchoose(linkStack.pop());
linkStack.push(p);
}
}
lock = false;
}
function choose(_point){
var gameEle = gameEles[_point.x][_point.y];
gameEle.style.width = eleWidth-2+"px";
gameEle.style.height = eleHeight-2+"px";
}
function unchoose(_point){
var gameEle = gameEles[_point.x][_point.y];
gameEle.style.width = eleWidth+"px";
gameEle.style.height = eleHeight+"px";
}
function linkSus(_path){
var sourcePoint = _path.shift();
var targetPoint = _path.pop();
sourcePoint.value = 0;
targetPoint.value = 0;
var sourceEle = gameEles[sourcePoint.x][sourcePoint.y];
var targetEle = gameEles[targetPoint.x][targetPoint.y];
sourceEle.onclick=null;
sourceEle.setAttribute("src","img/0.jpg");
targetEle.onclick=null;
targetEle.setAttribute("src","img/0.jpg");
}
function getPoint(_id){
var patterner = /ele(\d+)_(\d+)/;
var result = _id.match(patterner);
return points[result[1]][result[2]];
}
createPoints(width,height);
createCanvas(width,height);
</script>
</body>
</html>
JS
function _index(_value){
for(var v in this){
if(this[v] == _value){
return new Number(v)
}
}
return -1;
}
function _remove(_value){
var _index = this.index(_value);
this.splice(_index,1);
}
function _insert(_position,_value){
this.splice(_position,0,_value);
}
Array.prototype.index = _index;
Array.prototype.insert = _insert;
Array.prototype.remove = _remove;
function Point(_x,_y,_value){
this.x = _x;
this.y = _y;
this.value = _value;
this.directs = null;
this.changed = 0;
}
function _createDirect(_pre,_target){
this.directs = new Array();
var stx = _target.x - this.x;
var sty = _target.y - this.y;
if(stx >= 0){
this.directs.push("right");
this.directs.push("left");
}
else{
this.directs.push("left");
this.directs.push("right");
}
if(sty >= 0){
this.directs.insert(1,"up");
this.directs.push("down");
}
else{
this.directs.insert(1,"down");
this.directs.push("up");
}
if (_pre == null){
return ;
}
var spx = _pre.x - this.x;
var spy = _pre.y - this.y;
if (spx == 0){
if (spy == 1){
this.directs.remove("up");
}
else{
this.directs.remove("down");
}
}
else{
if (spx == 1){
this.directs.remove("right");
}
else{
this.directs.remove("left");
}
}
}
function _forward(_pre,_target){
if(this.directs == null){
this.createDirect(_pre,_target);
}
if(this.directs.length == 0){
return null;
}
var direct = null;
var tmpDirect = null;
var x = null;
var y = null;
var p = null;
while(true){
if(this.directs.length == 0){
break;
}
tmpDirect = this.directs.shift();
switch(tmpDirect){
case "up":
x = this.x;
y = this.y + 1;
break;
case "down":
x = this.x;
y = this.y - 1;
break;
case "left":
x = this.x - 1;
y = this.y;
break;
case "right":
x = this.x + 1;
y = this.y;
break;
default:
throw new Error("error direct");
break;
}
p = points[x][y];
if(p.value > 0 && p != _target){
continue;
}
else{
direct = tmpDirect;
if(_pre == null){
this.changed = 1;
}
else{
if((_pre.x - this.x) == 0 && (p.x - this.x) == 0){
this.changed = 0;
}
else{
if((_pre.y - this.y) == 0 && (p.y - this.y) == 0){
this.changed = 0;
}
else{
this.changed = 1;
}
}
}
break;
}
}
return direct;
}
function _equals(_point){
if (_point == null){
return false;
}
if (this.x == _point.x && this.y == _point.y){
return true;
}
else{
return false;
}
}
Point.prototype.createDirect = _createDirect;
Point.prototype.forward = _forward;
Point.prototype.equals = _equals;
var points = new Array();
var valueStack = new Array();
function createPoints(w,h){
var temp;
var tempValue;
pointStack(w,h);
for(var _x = 0 ; _x < w ; _x++){
temp = new Array();
for(var _y = 0 ; _y < h ; _y++){
if(_x == 0 || _x == (w-1) || _y == 0 || _y == (h-1)){
tempValue = 9;
}
else{
if(_x == 1 || _x == (w-2) || _y == 1 || _y == (h-2)){
tempValue = 0;
}
else{
tempValue = valueStack.pop();
}
}
temp[_y] = new Point(_x,_y,tempValue);
}
points[_x] = temp;
}
}
function pointStack(w,h){
var size = (w*h-(w*4+h*4-16))/2;
var pointValue;
for(var i = 0 ; i < size ; i++){
while(true){
pointValue = Math.floor(Math.random()*9);
if(pointValue != 0){
break;
}
}
valueStack.insert(Math.floor(Math.random()*valueStack.length),pointValue);
valueStack.insert(Math.floor(Math.random()*valueStack.length),pointValue);
}
}
function linkPoints(_source,_target){
var path = new Array();
var fail = new Object();
var change = 0;
var _current = _source;
var direct = null;
var _x,_y;
while(true){
//alert("current--"+pointStr(_current)+"change:"+change);
if(_current == _target && change < 4){
path.push(_target);
for(var p in path){
path[p].directs = null;
}
return path;
}
if(change == 4){
_current.directs = null;
fail[(_current.x+"_"+_current.y)] = change;
_current = path.pop();
change = change - _current.changed;
continue;
}
if(_current == _source){
direct = _current.forward(null,_target);
}
else{
direct = _current.forward(path[path.length-1],_target);
}
if(direct != null){
if(direct == "up"){
_x = _current.x;
_y = _current.y + 1;
}
if(direct == "down"){
_x = _current.x;
_y = _current.y - 1;
}
if(direct == "left"){
_x = _current.x - 1;
_y = _current.y ;
}
if(direct == "right"){
_x = _current.x + 1;
_y = _current.y;
}
if(fail[(_x+"_"+_y)] != null){
if (change >= fail[(_x+"_"+_y)]){
continue;
}
else{
delete fail[(_x+"_"+_y)];
}
}
change = change + _current.changed;
path.push(_current);
_current = points[_x][_y];
}
else{
if(_current == _source){
_source.directs = null;
return false;
}
else{
_current.directs = null;
fail[(_current.x+"_"+_current.y)] = change;
_current = path.pop();
change = change - _current.changed;
}
}
}
}
/*function pointStr(p){
return " x:"+p.x+" y:"+p.y+" value:"+p.value;
}
*/