HTML5游戏开发进阶指南读书笔记

创建游戏图层#gamecanvas(游戏图层)、#scorescreen(得分显示图层)、#gamestartscreen(游戏开始图层)、#levelselectscreen(关卡选择图层)、#loadingscreen(资源加载图层)、#endingscreen(游戏结束图层)所有图层共用.gamelayer,所有图层放于#gamecontainer中。

解决动画函数requestanimationframe兼容性问题:

 1 (function(){
 2     var vendors = ['o','webkit','moz','ms'];
 3     var lastTime = 0;
 4     for(var i=0; i<vendors.length&&!window.requestAnimationFrame; i++){  
   //循环检测当前浏览器支持的方法名 5 window.requestAnimationFrame = window[vendors[i]+'requestAnimationFrame'];
//将不同浏览器动画函数名统一 6 window.cancelAnimationFrame = window[vendors[i]+'CancelAnimationFrame']|| 7 window[vendors[i]+'CancelRequestAnimationFrame']; 8 } 9 if(!window.requestAnimationFrame){
    //检测浏览器是否支持动画函数 10 window.requestAnimationFrame =function (callback,element) { 11 var currTime = new Date().getTime(); 12 var timeToCall = Math.max(0,16-(currTime-lastTime));
         //理想刷新率为60hz(每1/60秒重绘一次),不断尝试修正刷新率。 13 var id = window.setTimeout(callback(),timeToCall);
         //timeToCall为0时各浏览器将采用最小调用单位时间。 14 lastTime =currTime+timeToCall;
         //执行后的时间。 15 return id; 16 } 17 } 18 if (!window.cancelAnimationFrame){ 19 window.cancelAnimationFrame = function(id){ 20 clearTimeout(id); 21 } 22 } 23 24 }());

构建资源加载器:

 1 var loader = {
 2         totalCount : 0,
 3         loadedCount : 0,
 4         loaded : true,
 5         soundFileExtn:'mp3',
 6         init:function(){ 7 var audio = new Audio(); 8 if(audio.canPlayType){ 9 loader.soundFileExtn = audio.canPlayType('audio/mpeg')?'.mp3': 10 audio.canPlayType('audio/ogg')?'.ogg':undefined; 11  } 12  }, 13 loadImg:function (url) { 14 loader.totalCount++; 15 loader.loaded = false; 16 $('#loadingscreen').show(); 17 var img =new Image(); 18 img.src = url; 19 img.onload = loader.itemLoaded; 20 return img; 21  }, 22 loadSound:function (url) { 23 loader.totalCount++; 24 loader.loaded = false; 25 $('#loadingscreen').show(); 26 var audio =new Audio(); 27 audio.src = url; 28 audio.addEventListener("canplaythrough",loader.itemLoaded,false); 29 return audio; 30  }, 31 itemLoaded:function () {
       //某单个资源加载完成后触发该函数 32 loader.loadedCount++; 33 $('#loadingmessage').html('loaded: '+loader.loadedCount+' of '+loader.totalCount) 34 if (loader.totalCount == loader.loadedCount){
           //判断是否已全部加载完 35 loader.loaded = true; 36 $('#loadingscreen').hide(); 37 } 38 if (loader.onload){ 39 loader.onload(); 40 } 41 } 42 }

创建关卡加载器:

 1 var level = {
 2     data:[
    //创建data数组存储各关卡数据 3 { 4 foreground:'desert-foreground', 5 background:'clouds-background', 6 }, 7 { 8 foreground:'desert-foreground', 9 background:'clouds-background', 10 }, 11 { 12 foreground:'desert-foreground', 13 background:'clouds-background', 14 } 15 ], 16 init:function () { 17 var html=''; 18 for(var i =0; i<level.data.length; i++){ 19 html +='<input type="button" value="'+(i+1)+'">'; 20 }; 21 $('#levelselectscreen').html(html); 22 $('#levelselectscreen input').click(function () { 23 level.load(this.value-1);
         //加载各关卡数据。 24 $('#levelselectscreen').hide(); 25 }) 26 }, 27 load:function (number) { 28 game.score = 0; 29 $('#score').html("score:"+game.score); 30 game.currtLevel.foregroundImage = loader.loadImg("img/backgrounds/"+level.data[number].foreground+".png"); 31 game.currtLevel.backgroundImage = loader.loadImg("img/backgrounds/"+level.data[number].background+".png"); 32 //将当前关卡中的数据存储到game.currtLevel对象中。
       game.slingshotImage = loader.loadImg("img/slingshot.png"); 33 game.slingshotFrontImage = loader.loadImg("img/slingshot-front.png"); 34 if (loader.loaded){ 35 game.start();
         //当前关卡数据加载完成后执行game.start()。 36 } else{ 37 loader.onload = game.start(); 38 } 39 } 40 }

构建鼠标对象:

 1 var mouse = {
 2     x:0,
 3     y:0,
 4     down:false,
 5     dragging:false,
 6     init:function(){
//为在#gamecanvas上的鼠标事件绑定监听函数 7 $('#gamecanvas').mousemove(mouse.mousemovehandler); 8 $('#gamecanvas').mousedown(mouse.mousedownhandler); 9 $('#gamecanvas').mouseup(mouse.mouseuphandler); 10 $('#gamecanvas').mouseout(mouse.mouseuphandler); 11 }, 12 mousemovehandler:function (ev) { 13 var offset = $('#gamecanvas').offset(); 14 mouse.x = ev.pageX - offset.left; 15 mouse.y = ev.pageY - offset.right;
   //获取鼠标在画布中的坐标 16 if(mouse.down){
      //判断是否点击并移动 17 mouse.dragging = true; 18 } 19 }, 20 mousedownhandler:function (ev) { 21 mouse.down = true; 22 mouse.downX = mouse.x; 23 mouse.downY = mouse.y; 24 ev.originalEvent.preventDefault(); 25 }, 26 mouseuphandler:function () { 27 mouse.down = false; 28 mouse.dragging = false; 29 } 30 }

构建game对象

初始化init( ):调用loader对象初始化函数检测浏览器支持的音频格式;

调用level对象初始化函数获取内部定义的关卡数据,加载出#levelselectscreen关卡按钮并为按钮绑定关卡资源加载函数,对应关卡资源加载完毕调用game对象的start函数;

调用mouse对象初始化函数为鼠标行为绑定处理函数;

获取#gamecanvas绘制上下文;

为game对象创建start函数

1 start:function () {
2         $('.gamelayer').hide();
3         $('#gamecanvas').show();
4         $('#scorescreen').show();
5         game.mode = "intro";
      //进入'intro'状态 6 game.ended = false; 7 game.animateFrame = window.requestAnimationFrame(game.animate,game.canvas);
     //执行game.animate函数,开始过场动画 8 }

为game对象创建animate函数

 1 animate:function () {
 2         game.handlePanning();
       //确定game.offsetLeft大小和“方向” 3 game.context.drawImage(game.currtLevel.backgroundImage,game.offsetLeft/4,0,640,480,0,0,640,480); 4 game.context.drawImage(game.currtLevel.foregroundImage,game.offsetLeft,0,640,480,0,0,640,480);
       //动态绘制背景图 5 game.context.drawImage(game.slingshotImage,game.slingshotX,game.slingshotY); 6 game.context.drawImage(game.slingshotFrontImage,game.slingshotX,game.slingshotY); 7 if(!game.ended){
     //若游戏未结束不断重绘 8 game.animateFrame = window.requestAnimationFrame(game.animate,game.canvas); 9 } 10 }

为game对象创建handlePanning函数

 1 handlePanning:function(){
  //通过game.mode游戏状态确定移动方式并切换游戏状态 2 if(game.mode == "intro"){ 3 if(game.panTo(700)){
           //“激活”,判断当前是否移动到指定位置并进入下一个游戏状态 4 game.mode = "load-next-hero"; 5 }; 6 } 7 if(game.mode == "wait-for-firing"){ 8 if(mouse.dragging){ 9 game.panTo(mouse.x+game.offsetLeft); 10 }else { 11 game.panTo(game.slingshotX); 12 } 13 } 14 if(game.mode == "load-next-hero"){ 15 game.panTo(game.slingshotX); 16 game.mode == "wait-for-firing"; 17 } 18 19 }

为game对象创建panTo函数

 1 panTo:function(newcenter){
 2         if(Math.abs(newcenter-game.offsetLeft-game.canvas.width/4)>0 && game.offsetLeft >= game.minoffset&&
 3            game.offsetLeft <= game.maxoffset){
       //判断当前中心位置是否位于两临界点间或在制定中心位置附近 4 var deltaX = Math.round((newcenter-game.offsetLeft-game.canvas.width/4)/2);
         //初步确定单次移动量和移动方向 5 if (Math.abs(deltaX)>game.maxspeed){
         //控制在maxspeed中 6 deltaX = game.maxspeed*Math.abs(deltaX)/deltaX; 7 } 8 console.log("deltaX="+deltaX); 9 game.offsetLeft += deltaX; 10 console.log("game.offsetLeft="+game.offsetLeft); 11 }else{
       //完成指定中心位移return 结果停止位移(动画) 12 return true; 13 } 14 if (game.offsetLeft < game.minoffset) {
       //超过零界点重置 15 game.offsetLeft = game.minoffset; 16 return true; 17 } 18 if (game.offsetLeft > game.maxoffset) { 19 game.offsetLeft = game.maxoffset; 20 return true; 21 } 22 return false; 23 }

猜你喜欢

转载自www.cnblogs.com/LiuDiJun/p/9837039.html