zoukankan      html  css  js  c++  java
  • 【CSON原创】HTML5游戏框架cnGameJS开发实录(游戏循环篇)

     返回目录

      由于整个游戏都在一个游戏循环中进行,所以游戏循环可以说是游戏的核心部分。每次循环时,更新游戏对象的属性,以及绘制游戏元素。

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

     

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







  • 相关阅读:
    cmd命令之set详解
    微信公众号之推送消息
    总结js(1)
    本地文件夹变远程仓库并且提交Github
    npm之使用淘宝源
    页面倒计时返回
    在线sass编译器
    js条件语句之职责链数组
    【轉】靜
    css 實現微信聊天類似的氣泡
  • 原文地址:https://www.cnblogs.com/Cson/p/2349878.html
Copyright © 2011-2022 走看看