Link

首页

Tweet

书单

about me

Command

Category

AIR game (六) 资源管理模块


      在上一篇文章的最后笔者写到,当前的项目需要一个资源管理模块。那么这个模块是整个项目中比较重要的一部分。因为所有的媒体内容都是通过这个模块来加载的。所以我们先要来编写这一部分。在编写之前我先来整体这几一下这个模块的主要功能。首先是大量资源文件的加载。由于后期可能资源有变,所以需要使用到XML来配置当前资源文件。同时我们在程序中又希望对资源文件进行统一的访问。好比我把资源比作一个仓库,那么需要拿什么东西的时候我们可以从正门将货物运出去。这里也是同样的道理。对于资源文件来说,我们一方面希望它是隐藏的,另一方面希望它是可读的。但是对于资源文件的特殊性质,我们会在不同的地方使用到这些图片音频等等。换句话说,基本上每个场景都会使用到这些资源。此时我们应该如何去做呢?下面来看一下笔者的处理方法。

      首先我们建立一个包路径为org.mebius.res在这个包当中我们存储了所有的资源和资源管理器。然后我们建立三个类文件,分别是PublicData.as、ConfigManage.as和ResManage.as这三个类的功能非常清晰,第一个是用来存储所有数据和资源的,后两者则是管理器。那么我们先来看一下在PublicData.as中如何去定义这些数据。

/**
     * 公共数据
     * @author mebius
     *
     */
    internal class PublicData
    {
        /**
         * 配置数据
         */
        public static var CONFIG_XML_DATA:XML;
        //用户配置数据
        public static var USER_CONFIG_DATA_XML:XML;

以上是数据定义部分,还有一些是方法定义部分。例如:

public static function getConfigXml(type:String):XML
        {
            switch(type)
            {
                case ConfigManage.SYSTEM:
                    return PublicData.CONFIG_XML_DATA;
                    break;
                case ConfigManage.USER:
                    return PublicData.USER_CONFIG_DATA_XML;
                    break;
            }
            return null;
        }

这样定义后我们就可以通过另外两个类来对资源进行读取了,因为前面CONFIG_XML_DATA已经定义为static类型,所以我们可以直接访问,但是PublicData设置的访问权限为internal,所以包外是无法访问到这个类的。这就满足了我们隐藏资源同时有做到可获取的功能。这样做的目的最主要的是禁止外界对资源进行非法修改。

      OK!看完了数据之后我们来看一下ConfigManage.as。这是一个非常简单的功能,它只不过将我们的urlloader进行了一下小小的二次开发,或者说功能扩展。其最主要的功能就是实现了对数据的自动添加。关键代码如下:

/**
         * 配置文件加载完成
         * @param evt
         *
         */
        private function config_file_load_complete_header(evt:Event):void
        {
           
            this.config_loader.removeEventListener(Event.COMPLETE,config_file_load_complete_header);
            //
            //PublicData.getConfigXml(this.xmltypes) = new XML(evt.target.data);
            //trace(this.xmltypes);
            switch(this.xmltypes)
            {
                case ConfigManage.SYSTEM:
                    PublicData.CONFIG_XML_DATA = new XML(evt.target.data);
                    break;
                case ConfigManage.USER:
                    PublicData.USER_CONFIG_DATA_XML = new XML(evt.target.data);
                    break;
            }
            this.config_loader = null;
           
            //
            var loadcompleteevent:DataLoadEvents = new DataLoadEvents(DataLoadEvents.DATA_LOAD_COMPLETE);
            this.dispatchEvent( loadcompleteevent);
            loadcompleteevent = null;
        }

当我们的程序完成配置文件加载后,默认的就将数据放置到默认的对象中,等待下一步数据解析操作。

后面我们会在外部调用RecManage.as。通过这个类,我们将刚刚加载进来的资源配置数据进行解析,然后对所有外部资源进行统一加载并且处理。关键代码如下:

public function startLoadRes():void
        {
           
            var i:uint = 0;
            var length:uint = PublicData.CONFIG_XML_DATA.res.length();
           
            while(i<length)
            {
                //trace(PublicData.CONFIG_XML_DATA.res[i].@type);
               
                var typestr:String = PublicData.CONFIG_XML_DATA.res[i].@type;
                switch(typestr)
                {
                    case "image":
                       
                        var picload:PictureLoader = new PictureLoader(PublicData.CONFIG_XML_DATA.res[i]);
                        picload.name = PublicData.CONFIG_XML_DATA.res[i].@id;
                        picload.addEventListener(DataLoadEvents.DATA_LOAD_COMPLETE,picloadcomplete);
                        break;
                     case "gamebtn":
                        var buttonUI:ButtonUIManage = new ButtonUIManage(PublicData.CONFIG_XML_DATA.res[i],PublicData.CONFIG_XML_DATA.res[i].@*);
                        buttonUI.name = PublicData.CONFIG_XML_DATA.res[i].@id;
                        buttonUI.addEventListener(DataLoadEvents.DATA_LOAD_COMPLETE,gamebtnloadcomplete);
                        break;
                    case "sprite":
                        var spicload:PictureLoader = new PictureLoader(PublicData.CONFIG_XML_DATA.res[i]);
                        spicload.name = PublicData.CONFIG_XML_DATA.res[i].@id;
                        spicload.addEventListener(DataLoadEvents.DATA_LOAD_COMPLETE,spriteloadcomplete);
                        break;
                }
                //
                i++;
            }
        }
       
        private function picloadcomplete(evt:DataLoadEvents):void
        {
            //Image.fromBitmap( (evt.currentTarget as PictureLoader).bitmap );
            //trace( (evt.currentTarget as PictureLoader).bitmap+"+++");
            var images:Image = Image.fromBitmap( (evt.currentTarget as PictureLoader).bitmap );
            images.name = evt.currentTarget.name;
            this.publicdaya.addImage( images );
            images = null;
            loadok();
            //trace("Image对象加载完成!");
        }
       
        private function gamebtnloadcomplete(evt:DataLoadEvents):void
        {
            //trace(evt.currentTarget+"+++");
           
            var gbtn:GameButton = new GameButton(evt.currentTarget as ButtonUIManage);
            gbtn.name = evt.currentTarget.name;
            this.publicdaya.addGameBtn( gbtn );
            gbtn = null;
            loadok();
        }
       
        private function spriteloadcomplete(evt:DataLoadEvents):void
        {
            //trace(evt.currentTarget+"+++");
            var spr:Sprite = new Sprite();
            spr.name = evt.currentTarget.name;
            spr.addChild( Image.fromBitmap( (evt.currentTarget as PictureLoader).bitmap ) );
            this.publicdaya.addSprite( spr );
            spr = null;
            loadok();
        }
       
        private function loadok():void
        {
            this.loadoknun++;
            var lengths:int = PublicData.CONFIG_XML_DATA.res.length();
           
            if(this.loadoknun == lengths)
            {
                this.loadoknun = 0;
                var shijian:DataLoadEvents = new DataLoadEvents(DataLoadEvents.DATA_LOAD_COMPLETE);
                this.dispatchEvent(shijian);
            }
        }

好了!以上这些内容就是这个游戏项目中资源加载模块的部分内容。我们再后面项目优化与重构部分继续对这个模块进行深入的介绍与剖析。