1.cnGameJs框架的代碼組織
核心函數(shù)模塊,主要的作用是為之后的框架開(kāi)發(fā)和用戶對(duì)游戲的開(kāi)發(fā)提供方便,整個(gè)框架在一個(gè)閉包之中,避免對(duì)全局作用域的污染。之后每個(gè)不同的模塊分別在自己的閉包內(nèi),使不同模塊的分割更清晰。因此我們框架的模塊劃分會(huì)是這樣:
(function(win,undefined){//最大的閉包 var fun1=function(){//各模塊公用的方法 } //這里放各個(gè)小模塊,它們有各自的閉包 }(window,undefined)
那么我們?nèi)绾卧賱澐制渌∧K呢?為了方便各個(gè)小模塊有各自的命名空間,并且在各自的閉包中,我們新增一個(gè)register方法,該方法可以在不同命名空間下擴(kuò)展自己的模塊,我們需要傳入的首先是命名空間的名稱(chēng),該方法為我們生成該命名空間對(duì)象,之后我們執(zhí)行自己的方法,為命名空間對(duì)象執(zhí)行相應(yīng)的擴(kuò)展操作:
/** *生成命名空間,并執(zhí)行相應(yīng)操作 **/ register:function(nameSpace,func){ var nsArr=nameSpace.split("."); var parent=win; for(var i=0,len=nsArr.length;i<len;i++){ (typeof parent[nsArr[i]]=='undefined')&&(parent[nsArr[i]]={}); parent=parent[nsArr[i]]; } if(func){ func.call(parent,this); } return parent; }
如上,首先可以把傳入的命名空間字符串分割,然后生成對(duì)象,之后執(zhí)行用戶傳入的函數(shù)進(jìn)行擴(kuò)展操作,如下:
cnGame.register("cnGame.core",function(){this.func=function(){}});
這樣就可以生成core模塊,并且為該模塊添加func方法,那么我們框架的代碼組織看起來(lái)將是這樣:
(function(win,undefined){ var cnGame={ register:function(nameSpace,handler){ } } /*core模塊*/ cnGame.register("core",function(){ //添加該模塊內(nèi)容 }) /*input模塊*/ cnGame.register("input",function(){ //添加該模塊內(nèi)容 }) win["cnGame"]=cnGame; })(window,undefined);
2.框架的初始化
框架初始化的時(shí)候,需要保存的對(duì)象分別有:canvas對(duì)象,context對(duì)象,canvas的位置,尺寸等,我們可以先看看初始化的函數(shù):
/** *初始化 **/ init:function(id,options){ options=options||{}; this.canvas = this.core.$(id||"canvas"); this.context = this.canvas.getContext('2d'); this.width = options.width||800; this.height = options.height||600; this.title = this.core.$$('title')[0]; canvasPos=getCanvasPos(this.canvas); this.x=canvasPos[0]||0; this.y=canvasPos[1]||0; this.canvas.width=this.width; this.canvas.height=this.height; this.canvas.style.left=this.x +"px"; this.canvas.style.top=this.y +"px"; },
非常簡(jiǎn)單,就是保存一些初始化值,方便后續(xù)使用。另外可以注意到我們調(diào)用了getCanvasPos方法來(lái)獲取canvas的位置參數(shù),該參數(shù)循環(huán)獲取對(duì)象的offsetParent,并疊加offsetLeft和offsetTop,從而得到canvas在頁(yè)面的位置。該函數(shù)源碼如下:
/** *獲取canvas在頁(yè)面的位置 **/ var getCanvasPos=function(canvas){ var left = 0; var top = 0; while (canvas.offsetParent) { left += canvas.offsetLeft; top += canvas.offsetTop; canvas = canvas.offsetParent; } return [left, top]; }
3.工具函數(shù)模塊
之后我們就可以用上面的register方法添加第一個(gè)模塊:core模塊。該模塊也很簡(jiǎn)單,主要功能就是添加工具函數(shù),方便后續(xù)的框架開(kāi)發(fā)和用戶的游戲開(kāi)發(fā)。這里包含了一些常用的工具函數(shù),例如通過(guò)id獲取元素,原型繼承,對(duì)象復(fù)制,事件綁定等等。注意如果涉及不同瀏覽器的兼容問(wèn)題,我們可以一開(kāi)始就根據(jù)瀏覽器設(shè)置function,而不是每次都判斷瀏覽器類(lèi)型再進(jìn)行相應(yīng)操作,效率會(huì)更加高。拿事件綁定進(jìn)行舉例:
/** 事件綁定 **/ this.bindHandler=(function(){ if(window.addEventListener){ return function(elem,type,handler){ elem.addEventListener(type,handler,false); } } else if(window.attachEvent){ return function(elem,type,handler){ elem.attachEvent("on"+type,handler); } } })();
預(yù)先根據(jù)瀏覽器特性返回不同function,這樣后續(xù)使用就不用再判斷瀏覽器特性,提高效率。
附上所有工具函數(shù)的源碼,由于都很簡(jiǎn)單,所以對(duì)該模塊就不在詳述了。
/** * *基本工具函數(shù)模塊 * **/ cnGame.register("cnGame.core",function(cg){ /** 按id獲取元素 **/ this.$=function(id){ return document.getElementById(id); }; /** 按標(biāo)簽名獲取元素 **/ this.$$=function(tagName,parent){ parent=parent||document; return parent.getElementsByTagName(tagName); }; /** 按類(lèi)名獲取元素 **/ this.$Class=function(className,parent){ var arr=[],result=[]; parent=parent||document; arr=this.$$("*"); for(var i=0,len=arr.length;i<len;i++){ if((" "+arr[i].className+" ").indexOf(" "+className+" ")>0){ result.push(arr[i]); } } return result; }; /** 事件綁定 **/ this.bindHandler=(function(){ if(window.addEventListener){ return function(elem,type,handler){ elem.addEventListener(type,handler,false); } } else if(window.attachEvent){ return function(elem,type,handler){ elem.attachEvent("on"+type,handler); } } })(); /** 事件解除 **/ this.removeHandler=(function(){ if(window.removeEventListerner){ return function(elem,type,handler){ elem.removeEventListerner(type,handler,false); } } else if(window.detachEvent){ return function(elem,type,handler){ elem.detachEvent("on"+type,handler); } } })(); /** 獲取事件對(duì)象 **/ this.getEventObj=function(eve){ return eve||win.event; }; /** 獲取事件目標(biāo)對(duì)象 **/ this.getEventTarget=function(eve){ var eve=this.getEventObj(eve); return eve.target||eve.srcElement; }; /** 禁止默認(rèn)行為 **/ this.preventDefault=function(eve){ if(eve.preventDefault){ eve.preventDefault(); } else{ eve.returnValue=false; } }; /** 獲取對(duì)象計(jì)算的樣式 **/ this.getComputerStyle=(function(){ var body=document.body; if(body.currentStyle){ return function(elem){ return elem.currentStyle; } } else if(document.defaultView.getComputedStyle){ return function(elem){ return document.defaultView.getComputedStyle(elem, null); } } })(); /** 是否為undefined **/ this.isUndefined=function(elem){ return typeof elem==='undefined'; }, /** 是否為數(shù)組 **/ this.isArray=function(elem){ return Object.prototype.toString.call(elem)==="[object Array]"; }; /** 是否為Object類(lèi)型 **/ this.isObject=function(elem){ return elem===Object(elem); }; /** 是否為字符串類(lèi)型 **/ this.isString=function(elem){ return Object.prototype.toString.call(elem)==="[object String]"; }; /** 是否為數(shù)值類(lèi)型 **/ this.isNum=function(elem){ return Object.prototype.toString.call(elem)==="[object Number]"; }; /** *復(fù)制對(duì)象屬性 **/ this.extend=function(destination,source,isCover){ var isUndefined=this.isUndefined; (isUndefined(isCover))&&(isCover=true); for(var name in source){ if(isCover||isUndefined(destination[name])){ destination[name]=source[name]; } } return destination; }; /** *原型繼承對(duì)象 **/ this.inherit=function(child,parent){ var func=function(){}; func.prototype=parent.prototype; child.prototype=new func(); child.prototype.constructor=child; child.prototype.parent=parent; }; });
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com