时间:2021-07-01 10:21:17 帮助过:27人阅读
在之前的资源加载篇已经提到过,在资源加载完成后,启动游戏的同时会启动一个游戏循环,现在再来回顾这部分代码:
- /**
- *图像加载完毕的处理程序
- **/
- 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开发实录-游戏循环篇的详细内容,更多请关注Gxl网其它相关文章!