• 技术文章 >web前端 >H5教程

    HTML5游戏框架cnGameJS开发实录-游戏循环篇

    黄舟黄舟2017-03-25 15:08:06原创889
      由于整个游戏都在一个游戏循环中进行,所以游戏循环可以说是游戏的核心部分。每次循环时,更新游戏对象的属性,以及绘制游戏元素。

      在之前的资源加载篇已经提到过,在资源加载完成后,启动游戏的同时会启动一个游戏循环,现在再来回顾这部分代码:

    /**
         *图像加载完毕的处理程序
        **/    
        var imgLoad=function(self){
            return function(){
                self.loadedCount+=1;
                self.loadedImgs[this.srcPath]=this;
                this.onLoad=null;                    //保证图片的onLoad执行一次后销毁
                self.loadedPercent=Math.floor(self.loadedCount/self.sum*100);
                self.onLoad&&self.onLoad(self.loadedPercent);
                if(self.loadedPercent===100){
                    self.loadedCount=0;
                    self.loadedPercent=0;
                    loadingImgs={};
                    if(self.gameObj&&self.gameObj.initialize){
                        self.gameObj.initialize();
                        if(cg.loop&&!cg.loop.stop){//结束上一个循环
                            cg.loop.end();
                        }
                        cg.loop=new cg.GameLoop(self.gameObj);//开始新游戏循环
                        cg.loop.start();
                    }
                    
                }
                
            
            }
        }

      图像资源加载完毕后,调用游戏对象的initialize方法,并且判断游戏循环对象是否存在,如果存在,则结束上一个循环(这种情况一般在切换关卡,传入新的游戏对象时出现),否则建立并开始游戏循环。

      好了,现在正式来看看游戏循环的实现代码:

    var gameLoop=function(gameObj,options){
        
            if(!(this instanceof arguments.callee)){
                return new arguments.callee(gameObj,options);
            }
            this.init(gameObj,options);    
        }

      首先游戏循环函数也必须保证是以构造函数的形式调用,在调用之后,为对象初始化:

    /**
             *初始化
            **/
            init:function(gameObj,options){
                /**
                 *默认对象
                **/    
                var defaultObj={
                    fps:30
                };
                options=options||{};
                
                options=cg.core.extend(defaultObj,options);
                this.gameObj=gameObj;
                this.fps=options.fps;
                interval=1000/this.fps;
                
                this.pause=false;
                this.stop=true;
            },

      用户需要设置的参数只有一个,就是fps(frame per second),该参数是每秒钟执行的帧的次数,根据该参数,我们可以计算出多少毫秒执行一次游戏循环(interval参数)。另外循环支持暂停和停止两种模式。

    /**
             *开始循环
            **/    
            start:function(){
                if(this.stop){        //如果是结束状态则可以开始
                    this.stop=false;
                    
                    this.now=new Date().getTime();
                    this.startTime=new Date().getTime();
                    this.duration=0;    
                    loop.call(this)();    
                }    
            },

      当循环开始,我们可以保存开始的时间,这样就可以不断更新循环所经历的时间(duration)。之后调用loop这个似有函数,实现循环。

    var timeId;
        var interval;
        /**
        *循环方法
        **/    
        var loop=function(){
            var self=this;
            return function(){
                if(!self.pause&&!self.stop){
                    
                    self.now=new Date().getTime();
                    self.duration=self.startTime-self.now;
                    
                    if(self.gameObj.update){
                        self.gameObj.update();
                    }
                    if(self.gameObj.draw){
                        cg.context.clearRect(0,0,cg.width,cg.height);
                        self.gameObj.draw();
                    }
                }
                timeId=window.setTimeout(arguments.callee,interval);
            }
        }

      如果不是暂停或停止,则调用游戏对象的update和draw(注意游戏对象的update负责调用该关卡所有元素的update,draw也一样)。之后调用setTimeout递归调用自己,实现循环。

    游戏循环所有源码:

    /**
     *
     *游戏循环
     *
    **/
    cnGame.register("cnGame",function(cg){
    
        var timeId;
        var interval;
        /**
        *循环方法
        **/    
        var loop=function(){
            var self=this;
            return function(){
                if(!self.pause&&!self.stop){
                    
                    self.now=new Date().getTime();
                    self.duration=self.startTime-self.now;
                    
                    if(self.gameObj.update){
                        self.gameObj.update();
                    }
                    if(self.gameObj.draw){
                        cg.context.clearRect(0,0,cg.width,cg.height);
                        self.gameObj.draw();
                    }
                }
                timeId=window.setTimeout(arguments.callee,interval);
            }
        }
        
        var gameLoop=function(gameObj,options){
        
            if(!(this instanceof arguments.callee)){
                return new arguments.callee(gameObj,options);
            }
            this.init(gameObj,options);    
        }
        gameLoop.prototype={
            /**
             *初始化
            **/
            init:function(gameObj,options){
                /**
                 *默认对象
                **/    
                var defaultObj={
                    fps:30
                };
                options=options||{};
                
                options=cg.core.extend(defaultObj,options);
                this.gameObj=gameObj;
                this.fps=options.fps;
                interval=1000/this.fps;
                
                this.pause=false;
                this.stop=true;
            },
                
            /**
             *开始循环
            **/    
            start:function(){
                if(this.stop){        //如果是结束状态则可以开始
                    this.stop=false;
                    
                    this.now=new Date().getTime();
                    this.startTime=new Date().getTime();
                    this.duration=0;    
                    loop.call(this)();    
                }    
            },
            /**
             *继续循环
            **/    
            run:function(){
                this.pause=false;    
            },
            /**
             *暂停循环
            **/    
            pause:function(){
                this.pause=true;    
            },
            /**
             *停止循环
            **/    
            end:function(){
                this.stop=true;
                window.clearTimeout(timeId);
            }
            
            
        }
        this.GameLoop=gameLoop;
    });

    以上就是HTML5游戏框架cnGameJS开发实录-游戏循环篇的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:HTML5游戏框架cnGameJS开发实录-精灵对象篇 下一篇:详细介绍HTML5的article和section的区别

    相关文章推荐

    • html5离线存储有哪些• h5新增标签audio与video的使用• 深入解析asp.net中mvc4自定义404页面(分享)• html5新增了什么• 你值得了解的HTTP缓存机制(代码详解)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网