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

早过忘川 提交于 2020-03-01 09:43:39

资源加载器 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也不是所有的浏览器都能直接播放的,下面是几种流行的音频格式被浏览器支持的情况(来源于网络,未全部测试,也许最新版本中已经有所变化,也说不定)。

虽然可以在<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的不在提交了(老是提示不能连接,有问题)。}

未完待续。。。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!