李俊良 发表于 2013-1-29 11:26:18

html5 canvas實踐

 
/*这部分是主要的js方面的,只测试过chrome浏览器*/Array.prototype.S=String.fromCharCode(2);Array.prototype.in_array=function(e){var r=new RegExp(this.S+e+this.S);return (r.test(this.S+this.join(this.S)+this.S));}Array.prototype.matching_math = function(){var re = 0;for(var i = 0 ; i < this.length ; i++){re += parseInt(this);}return re;}function Region(x,y,width,height){this.x = x;this.y = y;this.width = width;this.height = height;}function Matching(h_num,v_num,container,level,gamedata){this.regions = [];this.canvas = document.getElementById("canvas");this.ctx = canvas.getContext("2d");this.gamedata = gamedata;this.t = null;this.w = 60;this.h = 60;this.level = level;this.param = (h_num*v_num) / 2;this.h_num = h_num;this.v_num = v_num;this.container = $(container);this.linkpath = [];this.sourceNode = "";this.currentNode = "";this.loadcount = 0;this.mapdata = (function(){var imgarr = [];for(var i = 0 ; i < level ; i++){var temp = i+1;imgarr = temp;}return imgarr;})();this.paramdata = (function(){ //返回有對應圖片的對數var imgarr = [];var pushpos = 0;var maxData = (function(){var r = 0;for(var i = 0 ; i < gamedata.length ; i++){for(var j = 0 ; j < gamedata.length ; j++){if(gamedata == 0)r += 1;}}return r;})();while(parseInt(imgarr.matching_math()) < maxData/2){imgarr = imgarr ? imgarr + 1:1;pushpos = pushpos == (level-1) ? 0 : (pushpos +1);}return imgarr;})();this.couple = (h_num*v_num) / 2;}Matching.prototype = {getPoint:function(){var m = this.gamedata;var point = [];for(var i = 0 ; i < m.length ; i++){if(!m)break;for(var j = 0 ; j < m.length ; j++){if(m > -1){var p = i+"_"+j;point.push(p);}}}return point;},getparam:function(){return this.paramdata;},getmapdata:function(){return this.mapdata;},matchingoneline:function(pos,position){//console.log("開始查找路徑");/*matching just use one line水平判斷*/var sxpos = this.sourceNode.split(",");var sypos = this.sourceNode.split(",");var cxpos = this.currentNode.split(",");var cypos = this.currentNode.split(",");if(position == "yline"){//console.log("yline");var startpos = parseInt(cypos) > parseInt(sypos) ? sypos:cypos;var endpos = parseInt(cypos) < parseInt(sypos) ? sypos:cypos;var distance = Math.abs(parseInt(endpos) - parseInt(startpos));var loopcount = 0;//console.log("start pos:"+startpos+"   end pos:"+endpos);for(var i = parseInt(startpos)+1 ; i < parseInt(endpos) ; i++){//console.log($("div.map_"+pos+"_"+i).attr("data"));if(this.gamedata == "-1"){loopcount++;}}if(distance == 1 || loopcount ==distance-1){//console.log("["+cxpos+","+cypos+"] ["+sxpos+","+sypos+"] xline pos="+pos);this.drawline(this.sourceNode,pos+","+sypos,pos+","+cypos,this.currentNode);return true;}elsereturn false;}/*matching just use one line垂直方向判斷*/if(position == "xline"){//console.log("xline");var startpos = parseInt(cxpos) > parseInt(sxpos) ? sxpos:cxpos;var endpos = parseInt(cxpos) < parseInt(sxpos) ? sxpos:cxpos;var distance = Math.abs(parseInt(endpos) - parseInt(startpos));var loopcount = 0;//console.log("start pos:"+startpos+"   end pos:"+endpos);for(var i = parseInt(startpos)+1 ; i < parseInt(endpos) ; i++){if(this.gamedata == "-1" ){loopcount++;}}if(distance == 1 || loopcount ==distance-1){//console.log("["+cxpos+","+cypos+"] ["+sxpos+","+sypos+"] xline pos="+pos);this.drawline(this.sourceNode,sxpos+","+pos,cxpos+","+pos,this.currentNode);return true;}elsereturn false;}},findit:function(){var sxpos = parseInt(this.sourceNode.split(","));var sypos = parseInt(this.sourceNode.split(","));var cxpos = parseInt(this.currentNode.split(","));var cypos = parseInt(this.currentNode.split(","));/*新算法先查找對應的水平或者垂直方向的公共區域,然后判斷兩點是否連通*/var sxEl = [],cxEl = [],syEl = [],cyEl = [];// push sxpos and sypos where =-1for(var i = sxpos-1 ; i > -1 ; i--){if(this.gamedata == "-1")sxEl.push(i);elsebreak;}for(var i = sxpos+1 ; i < this.v_num+2 ; i++){if(this.gamedata == "-1")sxEl.push(i); elsebreak;}sxEl.push(sxpos);for(var i = sypos-1 ; i > -1 ; i--){if(this.gamedata == "-1")syEl.push(i); elsebreak;}for(var i = sypos+1 ; i < this.h_num+2; i++){if(this.gamedata == "-1")syEl.push(i); elsebreak;}syEl.push(sypos);// push cxpos and cypos where =-1for(var i = cxpos-1 ; i > -1 ; i--){if(this.gamedata == "-1")cxEl.push(i); elsebreak;}for(var i = cxpos+1 ; i < this.v_num+2 ; i++){if(this.gamedata == "-1")cxEl.push(i); elsebreak;}cxEl.push(cxpos);for(var i = cypos-1 ; i > -1 ; i--){if(this.gamedata == "-1")cyEl.push(i); elsebreak;}for(var i = cypos+1 ; i < this.h_num +2; i++){if(this.gamedata == "-1")cyEl.push(i); elsebreak;}cyEl.push(cypos);/*console.log("cxEl:"+cxEl);console.log("cyEl:"+cyEl);console.log("sxEl:"+sxEl);console.log("syEl:"+syEl);*//* 查找X方向相同點 */var samexpos = [],sameypos = [];for(var i = 0 ; i < sxEl.length ; i++){for(var j = 0 ; j < cxEl.length ; j++){if(sxEl == cxEl)sameypos.push(parseInt(cxEl));}}/* 查找y方向相同點 */for(var i = 0 ; i < syEl.length ; i++){for(var j = 0 ; j < cyEl.length ; j++){if(syEl == cyEl)samexpos.push(parseInt(cyEl));}}//console.log("same y pos:"+samexpos);//console.log("same x pos:"+sameypos);for(var i = 0 ; i < samexpos.length ; i++){if(this.matchingoneline(samexpos,"xline")){return true;break;}}for(var i = 0 ; i < sameypos.length ; i++){if(this.matchingoneline(sameypos,"yline")){return true;break;}}return false;},drawpoint:function(sourceEl,currentEl){var sxpos = parseInt(sourceEl.split(","));var sypos = parseInt(sourceEl.split(","));var cxpos = parseInt(currentEl.split(","));var cypos = parseInt(currentEl.split(","));if(sxpos == cxpos && sypos == cypos)return;      this.ctx.beginPath();this.ctx.lineWidth = 6;this.ctx.strokeStyle = "#1b85c1";      this.ctx.moveTo((sypos+1) * 66- 30 ,(sxpos+1) * 66- 30);      this.ctx.lineTo((cypos+1) * 66- 30 ,(cxpos+1) * 66- 30 );      this.ctx.stroke();},playerMp3:function(){var p = $("<div></div>");p.appendTo("body");var player = p.jPlayer({ready: function () {$(this).jPlayer("setMedia", {mp3: "js/dp.mp3"}).jPlayer("play");},ended: function (event) {$(this).jPlayer("destroy");p.remove();},swfPath: "js",supplied: "mp3"});},drawline:function(osEl,sEl,ocEl,cEl){//this.ctx.save();//console.log(osEl+" to "+sEl+" to "+ocEl+" to "+cEl);this.drawpoint(osEl,sEl);this.drawpoint(sEl,ocEl);this.drawpoint(ocEl,cEl);var _this = this;setTimeout(function(){_this.ctx.clearRect(0,0,_this.canvas.width,_this.canvas.height);var sxpos = parseInt(osEl.split(","));var sypos = parseInt(osEl.split(","));var cxpos = parseInt(cEl.split(","));var cypos = parseInt(cEl.split(","));_this.sourceNode = "";_this.currentNode = "";_this.gamedata =-1;_this.gamedata =-1;//重新绘制map_this.map();_this.drawCurrentMap();},200);this.playerMp3();},dbparam:function(){var param = this.getparam();for(var i = 0 ; i < param.length ; i++){param *= 2;}return param;},loadpic:function(){var _this = this;var param = this.getparam();var datas = this.getmapdata();var dbparam = this.dbparam();for(var i = 0 ; i < this.v_num+2 ; i++){for(var j = 0 ; j < this.h_num+2;j++){for(var m = 0 ; m < this.level ; m++){if(parseInt(dbparam) > 0 && this.gamedata == 0){dbparam--;this.gamedata = m;break;}}}}var localdata = this.gamedata;var allpoint = this.getPoint();//console.log(allpoint);var pointlen = allpoint.length;for(var i = 0 ; i < 2000 ; i++){var posrotate1=parseInt(Math.random()*pointlen);var posrotate2=parseInt(Math.random()*pointlen);var x1 = parseInt(allpoint.split("_"));var y1 = parseInt(allpoint.split("_"));var x2 = parseInt(allpoint.split("_"));var y2 = parseInt(allpoint.split("_"));var temp = localdata;localdata = localdata;localdata = temp;}//打亂了之后的數據this.drawCurrentMap();$(this.canvas).bind("click",{_this:this},this.clickFun);this.gamedata = localdata;},drawCurrentMap:function(){var _this = this;if(_this.loadcount == 17){for(var i = 0 ; i < _this.v_num+2 ; i++){for(var j = 0 ; j < _this.h_num+2;j++){if(_this.gamedata > -1){var p = new Image();p.src="images/"+(_this.gamedata + 1)+".png";_this.ctx.clearRect(j*60+6*(j+1), i*60+6*(i+1), 60, 60);_this.ctx.fillStyle="#FFF";_this.ctx.fillRect (j*60+6*(j+1), i*60+6*(i+1), 60, 60);_this.ctx.drawImage(p,j*60+6*(j+1), i*60+6*(i+1), 60, 60);//p = null;}}}}else{for(var i = 1; i <= 17 ; i++){var p = new Image();p.onload = function(){_this.loadcount++};p.src="images/"+i+".png";}var cc = setInterval(function(){if(_this.loadcount == 17){for(var i = 0 ; i < _this.v_num+2 ; i++){for(var j = 0 ; j < _this.h_num+2;j++){if(_this.gamedata > -1){var p = new Image();p.src="images/"+(_this.gamedata + 1)+".png";_this.ctx.clearRect(j*60+6*(j+1), i*60+6*(i+1), 60, 60);_this.ctx.fillStyle="#FFF";_this.ctx.fillRect (j*60+6*(j+1), i*60+6*(i+1), 60, 60);_this.ctx.drawImage(p,j*60+6*(j+1), i*60+6*(i+1), 60, 60);//p = null;}}}clearInterval(cc);cc = null;}},50);}},clickFun:function(e){var _this = e.data._this;//console.log(_this.gamedata);var mouseX = e.clientX - canvas.offsetLeft;var mouseY = e.clientY - canvas.offsetTop;var topStock = parseInt(mouseX / 66,10);// 判斷左側的格子個數var leftStock = parseInt(mouseY / 66,10);// 判斷頂部的格子個數if(_this.gamedata == "-1")return;if(_this.sourceNode == ""){_this.drawStoneImage(leftStock,topStock,0.5);//console.log("mouseX:"+mouseX + ",mouseY:"+mouseY);//console.log("leftStock:"+leftStock + ",topStock:"+topStock);_this.sourceNode = leftStock+","+topStock;}else{_this.currentNode = leftStock+","+topStock;var sx = parseInt(_this.sourceNode.split(","));var sy = parseInt(_this.sourceNode.split(","));var cx = parseInt(_this.currentNode.split(","));var cy = parseInt(_this.currentNode.split(","));if(_this.currentNode == _this.sourceNode || _this.gamedata != _this.gamedata){_this.drawStoneImage(cx,cy);_this.drawStoneImage(sx,sy);_this.currentNode = "";_this.sourceNode = "";//console.log("mouseX:"+mouseX + ",mouseY:"+mouseY);//console.log("leftStock:"+leftStock + ",topStock:"+topStock);}else{_this.drawStoneImage(cx,cy,0.5);// _this.findPath()if(_this.findit()){//console.log("find it");_this.clearImage(cx,cy);_this.clearImage(sx,sy);}else{//console.log("findn't it");_this.drawStoneImage(cx,cy);_this.drawStoneImage(sx,sy);}}}},drawStoneImage:function(x,y,transparent){var trans = transparent || 1;var p = new Image();p.src="images/"+(parseInt(this.gamedata) + 1)+".png";this.ctx.clearRect(y*60+6*(y+1), x*60+6*(x+1), 60, 60);this.ctx.fillStyle = "rgba(255, 255, 255, "+trans+")";if(trans != 1){/*畫上圖片*/this.ctx.drawImage(p,y*60+6*(y+1), x*60+6*(x+1), 60, 60);/*畫上透明背景*/this.ctx.fillRect (y*60+6*(y+1), x*60+6*(x+1), 60, 60);}else{this.ctx.fillRect (y*60+6*(y+1), x*60+6*(x+1), 60, 60);this.ctx.drawImage(p,y*60+6*(y+1), x*60+6*(x+1), 60, 60);}p = null;},clearImage:function(x,y){return;var trans = 1;this.ctx.clearRect(y*60+6*(y+1), x*60+6*(x+1), 60, 60);this.ctx.fillStyle = "rgba(255, 255, 255, "+trans+")";/*畫上透明背景*/this.ctx.fillRect (y*60+6*(y+1), x*60+6*(x+1), 60, 60);this.sourceNode = "";this.currentNode = "";this.gamedata = -1;},map:function(){var htmlstring = "";var box_count = 0;this.ctx.fillStyle = "rgb(0,0,0)";this.ctx.fillRect (0, 0, canvas.width, canvas.height);for(var i = 0 ; i < this.v_num+2 ; i++){for(var j = 0 ; j < this.h_num+2;j++){this.ctx.fillStyle="#FFF";this.ctx.fillRect (j*60+6*(j+1), i*60+6*(i+1), 60, 60);}}}}/*canvas event*/var mapdata = [,[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0],,,,[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0],,,];var matching = new Matching(9,6,"#canvas",17,mapdata);matching.map();$(".console a").click(function(e){e.preventDefault();matching.loadpic();}); 
再利用websockets就可以做成對戰版本了
源碼下載地址是
 http://www.css-ajax.com/html5/game/usecanvas.zip
页: [1]
查看完整版本: html5 canvas實踐