PHP前端开发

HTML5游戏框架cnGameJS开发实录-核心函数模块篇的代码实例

百变鹏仔 2个月前 (10-18) #H5教程
文章标签 实录

返回目录

1.cnGameJs框架的代码组织 

核心函数模块,主要的作用是为之后的框架开发和用户对游戏的开发提供方便,整个框架在一个闭包之中,避免对全局作用域的污染。之后每个不同的模块分别在自己的闭包内,使不同模块的分割更清晰。因此我们框架的模块划分会是这样:

(function(win,undefined){//最大的闭包var fun1=function(){//各模块公用的方法}//这里放各个小模块,它们有各自的闭包}(window,undefined)

那么我们如何再划分其他小模块呢?为了方便各个小模块有各自的命名空间,并且在各自的闭包中,我们新增一个register方法,该方法可以在不同命名空间下扩展自己的模块,我们需要传入的首先是命名空间的名称,该方法为我们生成该命名空间对象,之后我们执行自己的方法,为命名空间对象执行相应的扩展操作:

/**         *生成命名空间,并执行相应操作        **/        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]]==&#39;undefined&#39;)&&(parent[nsArr[i]]={});                parent=parent[nsArr[i]];            }            if(func){                func.call(parent,this);                }            return parent;        }

如上,首先可以把传入的命名空间字符串分割,然后生成对象,之后执行用户传入的函数进行扩展操作,如下:

立即学习“前端免费学习笔记(深入)”;

cnGame.register("cnGame.core",function(){this.func=function(){}});

这样就可以生成core模块,并且为该模块添加func方法,那么我们框架的代码组织看起来将是这样:

(function(win,undefined){var cnGame={    register:function(nameSpace,handler){    }}/*core模块*/cnGame.register("core",function(){  //添加该模块内容})/*input模块*/cnGame.register("input",function(){  //添加该模块内容})win["cnGame"]=cnGame;})(window,undefined);


2.框架的初始化

框架初始化的时候,需要保存的对象分别有:canvas对象,context对象,canvas的位置,尺寸等,我们可以先看看初始化的函数:

/**         *初始化        **/        init:function(id,options){            options=options||{};            this.canvas = this.core.$(id||"canvas");                this.context = this.canvas.getContext(&#39;2d&#39;);            this.width = options.width||800;            this.height = options.height||600;            this.title = this.core.$$(&#39;title&#39;)[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";                    },

非常简单,就是保存一些初始化值,方便后续使用。另外可以注意到我们调用了getCanvasPos方法来获取canvas的位置参数,该参数循环获取对象的offsetParent,并叠加offsetLeft和offsetTop,从而得到canvas在页面的位置。该函数源码如下:

/**    *获取canvas在页面的位置    **/          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.工具函数模块

之后我们就可以用上面的register方法添加第一个模块:core模块。该模块也很简单,主要功能就是添加工具函数,方便后续的框架开发和用户的游戏开发。这里包含了一些常用的工具函数,例如通过id获取元素,原型继承,对象复制,事件绑定等等。注意如果涉及不同浏览器的兼容问题,我们可以一开始就根据浏览器设置function,而不是每次都判断浏览器类型再进行相应操作,效率会更加高。拿事件绑定进行举例:

/**        事件绑定        **/        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);                            }                        }        })();

预先根据浏览器特性返回不同function,这样后续使用就不用再判断浏览器特性,提高效率。

附上所有工具函数的源码,由于都很简单,所以对该模块就不在详述了。

/** * *基本工具函数模块 ***/cnGame.register("cnGame.core",function(cg){        /**        按id获取元素        **/        this.$=function(id){            return document.getElementById(id);                };        /**        按标签名获取元素        **/        this.$$=function(tagName,parent){            parent=parent||document;            return parent.getElementsByTagName(tagName);            };        /**        按类名获取元素        **/        this.$Class=function(className,parent){            var arr=[],result=[];            parent=parent||document;            arr=this.$$("*");            for(var i=0,len=arr.length;i0){                    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);                            }                        }        })();        /**        获取事件对象        **/        this.getEventObj=function(eve){            return eve||win.event;        };        /**        获取事件目标对象        **/        this.getEventTarget=function(eve){            var eve=this.getEventObj(eve);            return eve.target||eve.srcElement;        };        /**        禁止默认行为        **/        this.preventDefault=function(eve){            if(eve.preventDefault){                eve.preventDefault();            }            else{                eve.returnValue=false;            }                    };        /**        获取对象计算的样式        **/        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';        },        /**        是否为数组        **/        this.isArray=function(elem){            return Object.prototype.toString.call(elem)==="[object Array]";        };        /**        是否为Object类型        **/        this.isObject=function(elem){            return elem===Object(elem);        };        /**        是否为字符串类型        **/        this.isString=function(elem){            return Object.prototype.toString.call(elem)==="[object String]";        };        /**        是否为数值类型        **/        this.isNum=function(elem){            return Object.prototype.toString.call(elem)==="[object Number]";        };        /**         *复制对象属性        **/        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;        };        /**         *原型继承对象        **/        this.inherit=function(child,parent){            var func=function(){};            func.prototype=parent.prototype;            child.prototype=new func();            child.prototype.constructor=child;            child.prototype.parent=parent;        };    });