评论

收藏

08、开源游戏-“胡子”开始游戏前02

游戏开发 游戏开发 发布于:2021-07-17 22:09 | 阅读数:560 | 评论:0

资源加载器 resourceloader.js
初始化
资源加载器用于读取图片和音乐,在前面的代码(main.js)中,我们初始化了它,下面我们详细说下,因为它在以后中会经常用到,游戏中所有的资源都由它来读取。
$(window).load(function() {
resourceloader.init();
sounds.init();
if (resourceloader.loaded){
sounds.bgMusic();
} else {
resourceloader.onload = sounds.bgMusic;
}
if(store.get('data')){
$("#checkbullet").css({"top":store.get('data').checkbullety});
}else{
store.set('data',{hero:"hero1",checkbullety:"160px",task:0});
}
});
资源加载器都干什么事情呢?读取资源,这个是最终我们想要干的事,我们还得考虑下,读取完了之后怎么办?图片也分很多类型,音乐同样如此,常用的.mp3也不是所有的浏览器都能直接播放的,下面是几种流行的音频格式被浏览器支持的情况(来源于网络,未全部测试,也许最新版本中已经有所变化,也说不定)。
DSC0000.jpg
虽然可以在<audio>标签中罗列多个格式的文件,浏览器会自动选择他支持的,但这样显然不是我们好的选择。目前我们是判断玩家浏览器的支持情况,然后加载这个音乐和音频。这也是在main.js中执行resourceloader.init();的原因,我们看下init方法:
init:function(){
    var mp3,ogg,wav;
    var audio = document.createElement('audio');
  if (audio.canPlayType) {
    mp3 = "" != audio.canPlayType('audio/mpeg');
    ogg = "" != audio.canPlayType('audio/ogg; codecs="vorbis"');
wav = "" != audio.canPlayType('audio/wav');
  } else {
  mp3 = false;
  ogg = false;
wav = false;
  }
    resourceloader.audioExt = ogg?".ogg":mp3?".mp3":wav?".wav":undefined;
  },
我们通过audio.canPlayType方法检查支持的情况,然后保存该音频的扩展名,以后要读取某音频,只需通过该文件的名称就可以了(需要我们准备多格式文件)。
canPlayType() 方法可返回下列值之一(来源http://www.w3school.com.cn/tags/av_met_canplaytype.asp):"probably" - 浏览器最可能支持该音频/视频类型;"maybe" - 浏览器也许支持该音频/视频类型;"" - (空字符串)浏览器不支持该音频/视频类型。
加载图片音频
这里我不在详细说明了,在js中使用new Image(),然后加载完后,他调用onload,我实现自己的onload方法就可以了。音频类似使用new Audio();然后我们监听canplaythrough事件,然后指定我们自己的方法就可以了。
var image = new Image();
    image.src = url;
    image.onload = resourceloader.itemLoaded;
var audio = new Audio();
audio.src = url+resourceloader.audioExt;
audio.addEventListener("canplaythrough", resourceloader.itemLoaded, false);
加载完毕,resourceloader.itemLoaded方法
通常我们加载完毕后,可能要执行某一操作,所以这里我们实现一个钩子方法,只要定义了这个方法,我们就执行一下,这个我感觉很强大,呵呵,以前在开发开源eternal框架时,在框架初始化时也定义了类似的方法,这样就可以动态的扩展这个框架。对于我们来说,资源加载器他有这样一个回调函数,如果ajax的回调一样。在图片和音频加载完后都调用itemLoaded方法。我们看下代码:
if (resourceloader.loadedCount >= resourceloader.totalCount){
      resourceloader.loaded = true;
      if(resourceloader.onload){
        resourceloader.onload();
        resourceloader.onload = undefined;
      }
    }
这里边有2个变量,已经加载的资源数目loadedCount和总资源数据totalCount,全部加载完后,我们就调用钩子方法,如果有的话。在我们播放背景音乐时就是使用它的,main.js中的:
if (resourceloader.loaded){
sounds.bgMusic();
} else {
resourceloader.onload = sounds.bgMusic;
}
如果音乐已经全部加载完,则播放背景音乐:bgMusic,没有则把播放方法赋给钩子,让资源加载去调用。还有singlegame.js中的初始化,同样如此:
if (resourceloader.loaded){
  singlegame.start();
 } else {
  resourceloader.onload = singlegame.start;
 }
小结
我们把资源加载器设计成一个通用的功能,并主要分成3个功能:初始化、加载、完毕后处理。这样我们不必操心各浏览器的音频兼容问题,而且也体验到了回调函数的强大,如做等待场景的退出功能,都可以用到。


声音处理
我们开发了一个专门的对象来播放声音,sounds.js。看一下代码:
var sounds = {
  list:{
    "background":["desolate"]
  },
  loaded:{},
  init: function(){
    for(var soundName in sounds.list){
      var sound = {};
      sound.audioObjects = [];
      for (var i=0; i < sounds.list[soundName].length; i++) {
        sound.audioObjects.push(resourceloader.loadSound('audio/' + sounds.list[soundName][i]));
      };      
      this.loaded [soundName] = sound;
    }    
  },
  bgMusic:function(){
    var sound = sounds.loaded["background"];
    if(sound && sound.audioObjects && sound.audioObjects.length>0){
var n = Math.floor(Math.round(sound.audioObjects.length));
      sound.audioObjects[n-1].play();
    }
  }
};
list音乐列表,init使用资源加载器加载音乐,bgMusic播放背景音乐。大家可能会想,游戏中的声音太多了,要都放在list里,然后加载?这里我想有2种情况,1、音频真的不多;2、音频真的很多,对于1那就把音频都放这,没什么问题啊,对于2肯定不行,胡子就属于2的情况。这里的list只是一些通用的音频,如背景音乐、抢声、大炮声、坦克声等,其他的音频则放到task.js中,即每个任务(可以理解为游戏的关卡)中,当然也有个问题就是,最大的任务,也许也有很多的音频,不知道大家有没有好的办法?我的想法是把这个问题留到最后阶段的来处理(前面章节中提到游戏的开发阶段),呵呵。
bgMusic是随机播放背景音乐,目前只有一个音乐desolate,最后我想应该有3个,即荒凉感觉的一个,让人兴奋的一个,战斗时一个。后面会增加其他播放方法,如随机播放(非背景音乐的某类音频)、顺序播放(同随机)等。
小结
音频的实现我们同资源加载器类似,实现3个功能:定义(list)、初始化(init)、播放(bgMusic等方法)。


总结
资源加载器和音频处理,我们实现的比较通用些,或者可以说模块化,一个游戏应该有清晰的代码结构,然后组装这些模块,协调这些模块,来实现游戏的功能,就像胡子游戏中的 大当家、四梁八柱、崽子(兵)一样,他们有共同的目的,又有不同的分工,由大当家领导他们去砸窑,不管软的硬的,都是无往不利,害得地主老财,天天提心吊胆,呵呵。
下次中我会总结一下游戏开始前的这个初始化阶段,之后就是到游戏主界面了。
{弄了个笑话,在群里,以为别人管我要源码那,结果是没人理我,哎。不管怎么样,代码已经提前上传到oschina啦,google的不在提交了(老是提示不能连接,有问题)。}
未完待续。。。

关注下面的标签,发现更多相似文章