首頁  >  文章  >  web前端  >  HTML5遊戲框架cnGameJS開發實錄-遊戲循環篇

HTML5遊戲框架cnGameJS開發實錄-遊戲循環篇

黄舟
黄舟原創
2017-03-25 15:08:061668瀏覽

  由於整個遊戲都在一個遊戲循環中進行,所以遊戲循環可以說是遊戲的核心部分。 每次迴圈時,更新遊戲物件的屬性,以及繪製遊戲元素。

  在先前的資源載入篇已經提到過,在資源載入完成後,啟動遊戲的同時會啟動一個遊戲循環,現在再來回顧這部分程式碼:

/**
     *图像加载完毕的处理程序
    **/    
    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