您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

HTML5游戏框架cnGameJS开发实录-游戏场景对象

2024/2/24 23:42:04发布14次查看
1.什么时候需要场景对象?
场景对象有区别于上一篇介绍的地图对象,它们分别应用于不同类型的游戏。之前的地图对象应用于格子类的游戏,例如推箱子,坦克大战。而本节介绍的场景对象,则适用于拥有特定场景的游戏,例如超级玛丽,恐龙快打等。这类游戏通常在2d场景内控制一个玩家对象,随着玩家的移动,场景跟着移动。
2.场景示例:
效果:(左右键控制超级玛丽的移动)
代码:
<body> <div><canvas id="gamecanvas">请使用支持canvas的浏览器查看</canvas></div> </body> <script src="cngame_v1.0.js"></script> <script> var src="http://images.cnblogs.com/cnblogs_com/cson/290336/o_player.png"; var background="background.png"; /* 初始化 */ cngame.init('gamecanvas',{width:500,height:400}); var floory=cngame.height-40; var gameobj=(function(){ /* 玩家对象 */ var player=function(options){ this.init(options); this.speedx=0; this.movedir; this.isjump=false; } cngame.core.inherit(player,cngame.sprite); player.prototype.initialize=function(){ this.addanimation(new cngame.spritesheet("playerright",src,{framesize:[50,60],loop:true,width:150,height:60})); this.addanimation(new cngame.spritesheet("playerleft",src,{framesize:[50,60],loop:true,width:150,height:120,beginy:60})); } player.prototype.moveright=function(){ if(cngame.core.isundefined(this.movedir)||this.movedir!="right"){ this.movedir="right"; this.speedx<0&&(this.speedx=0); this.setmovement({ax:10,maxspeedx:15}); this.setcurrentanimation("playerright"); } } player.prototype.moveleft=function(){ if(cngame.core.isundefined(this.movedir)||this.movedir!="left"){ this.movedir="left"; this.speedx>0&&(this.speedx=0); this.setmovement({ax:-10,maxspeedx:15}); this.setcurrentanimation("playerleft"); } } player.prototype.stopmove=function(){ if(this.speedx<0){ this.setcurrentimage(src,0,60); } else if(this.speedx>0){ this.setcurrentimage(src); } this.movedir=undefined; this.resetmovement(); } player.prototype.update=function(){ player.prototype.parent.prototype.update.call(this);//调用父类update if(cngame.input.ispressed("right")){ this.moveright(); } else if(cngame.input.ispressed("left")){ this.moveleft(); } else{ this.stopmove(); } } return { initialize:function(){ cngame.input.preventdefault(["left","right","up","down"]); this.player=new player({src:src,width:50,height:60,x:0,y:floory-60}); this.player.initialize(); this.background=new cngame.view({src:background,player:this.player,imgwidth:2301}); this.background.centerplayer(true); this.background.insideview(this.player,"x"); }, update:function(){ this.player.update(); this.background.update([this.player]); }, draw:function(){ this.background.draw(); this.player.draw(); } }; })(); cngame.loader.start([src,background],gameobj); </script>
3.代码实现:
要构造一个场景,首先需要一张足够宽的背景图片,当player向右移动时,使player始终处于背景中点,player的速度转换为背景向相反方向移动的速度。首先看初始化函数:
/** *初始化 **/ init:function(options){ /** *默认对象 **/ var defaultobj={ width:cg.width, height:cg.height, imgwidth:cg.width, imgheight:cg.height, x:0, y:0 } options=options||{}; options=cg.core.extend(defaultobj,options); this.player=options.player; this.width=options.width; this.height=options.height; this.imgwidth=options.imgwidth; this.imgheight=options.imgheight; this.centerx=this.width/2; this.src=options.src; this.x=options.x; this.y=options.y; this.insidearr=[]; this.isloop=false;; this.iscenterplayer=false; this.onend=options.onend; },
用户传入的参数除了xy以及尺寸外,另外还有三个参数,一个参数是设置是否把玩家对象置于中心,只移动背景而不移动玩家。如果要实现上面的背景移动效果,该参数要设置为true。另一个参数是设置是否循环。如果设置为循环,在背景移动到极点后,会重新回到初始位置。最后一个参数是onend,如果设置为非循环,那么背景移动到极点后,会触发该回调函数。
场景对象的重点在于update方法:
/** *背景移动时的更新 **/ update:function(spritelist){//传入所有sprite的数组 if(this.iscenterplayer){ if(this.player.x>this.centerx){ if(this.x<this.imgwidth-this.width){ var marginx=this.player.x-this.centerx; this.x+=marginx; if(spritelist){ for(var i=0,len=spritelist.length;i<len;i++){ if(spritelist[i]==this.player){ spritelist[i].x=this.centerx; } else{ spritelist[i].x-=marginx; } } } } else if(this.isloop){ if(spritelist){ for(var i=0,len=spritelist.length;i<len;i++){ if(spritelist[i]!=this.player){ spritelist[i].move(this.imgwidth-this.width); } } } this.x=0; } else{ this.onend&&this.onend(); } } } for(var i=0,len=this.insidearr.length;i<len;i++){ inside.call(this,this.insidearr[i]); } },
该方法首先判断player对象是否已经超过场景中心,如果已经超过,则计算超出的距离,并且把player固定在场景中心,超出的距离设置为背景向相反方向移动的距离与除了player外其他sprite向相反方向移动的距离,这样的话就只有背景移动和其他sprite对象移动,player固定。如果是循环的话,则在超出移动范围后重置背景和其他sprite的x坐标。如果非循环,则在移动结束后调用onend回调函数。另外如果需要限制player始终在显示区域内,还可以调用insideview方法。
附上场景对象所有代码:
/** * *场景 * **/ cngame.register("cngame",function(cg){ /** *使指定对象在可视区域view内 **/ var inside=function(sprite){ var dir=sprite.insidedir; if(dir!="y"){ if(sprite.x<0){ sprite.x=0; } else if(sprite.x>this.width-sprite.width){ sprite.x=this.width-sprite.width; } } if(dir!="x"){ if(sprite.y<0){ sprite.y=0; } else if(sprite.y>this.height-sprite.height){ sprite.y=this.height-sprite.height; } } } var view=function(options){ this.init(options); } view.prototype={ /** *初始化 **/ init:function(options){ /** *默认对象 **/ var defaultobj={ width:cg.width, height:cg.height, imgwidth:cg.width, imgheight:cg.height, x:0, y:0 } options=options||{}; options=cg.core.extend(defaultobj,options); this.player=options.player; this.width=options.width; this.height=options.height; this.imgwidth=options.imgwidth; this.imgheight=options.imgheight; this.centerx=this.width/2; this.src=options.src; this.x=options.x; this.y=options.y; this.insidearr=[]; this.isloop=false;; this.iscenterplayer=false; this.onend=options.onend; }, /** *使player的位置保持在场景中点之前的移动背景 **/ centerplayer:function(isloop){ isloop=isloop||false; this.isloop=isloop; this.iscenterplayer=true; }, /** *使对象的位置保持在场景内 **/ insideview:function(sprite,dir){//dir为限定哪个方向在view内,值为x或y,不传则两个方向皆限定 if(cg.core.isarray(sprite)){ for(var i=0,len=sprite.length;i<len;i++){ arguments.callee.call(this,sprite[i],dir); } } else{ sprite.insidedir=dir; this.insidearr.push(sprite); } }, /** *背景移动时的更新 **/ update:function(spritelist){//传入所有sprite的数组 if(this.iscenterplayer){ if(this.player.x>this.centerx){ if(this.x<this.imgwidth-this.width){ var marginx=this.player.x-this.centerx; this.x+=marginx; if(spritelist){ for(var i=0,len=spritelist.length;i<len;i++){ if(spritelist[i]==this.player){ spritelist[i].x=this.centerx; } else{ spritelist[i].x-=marginx; } } } } else if(this.isloop){ if(spritelist){ for(var i=0,len=spritelist.length;i<len;i++){ if(spritelist[i]!=this.player){ spritelist[i].move(this.imgwidth-this.width); } } } this.x=0; } else{ this.onend&&this.onend(); } } } for(var i=0,len=this.insidearr.length;i<len;i++){ inside.call(this,this.insidearr[i]); } }, /** *绘制场景 **/ draw:function(){ cg.context.drawimage(cg.loader.loadedimgs[this.src],this.x,this.y,this.width,this.height,0,0,this.width,this.height); } } this.view=view; });
以上就是html5游戏框架cngamejs开发实录-游戏场景对象的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product