• laya2.x的场景Scene和脚本Script


    laya2.x UI类结构

    新增加了一个Scene - > Sprite, Scene只有一个子类就是View,Dialog仍然继承View。

    - Component也出现了变化:Component implements ISingletonElement, IDestroy。现在的Component变成了一个脚本的基类,它的子类有相对布局插件

       Widget,Script,CommonScript。之前的Component现在被重命名为UIComponent。

    AnimationPlayerBase被重命名成为AnimationBase

    laya1.0创建的UI:xxUI->View->Box->Component->Sprite

    laya2.0创建的UI:xxUI->View->Scene->Sprite(创建时也可以选成Scene类型,xxUI->Scene->Sprite)

    需要说明一下,现在创建的UI文件后缀名统一为.scene。

    laya2.x的Scene类

     1 public function open(closeOther:Boolean = true, param:*=null):void{
     2   if(closeOther) closeAll();
     3   root.addChild(scene);
     4   onOpened(param);  
     5 }
     6 public function close():void{
     7   if(autoDestroyAtClosed) this.destory();
     8   else removeSelf();
     9   onClosed();  
    10 }
    11 
    12 override public function destroy(destroyChild:Boolean = true):void{
    13   _idMap = null;
    14   super.destroy(destroyChild);
    15   var list:Array = Scene.unDestroyedScenes;
    16   for(var i:int = 0, n:int = list.length; i<n;i++){
    17       if(lsit[i]===this){
    18         list.splice(i,1);
    19         return;
    20       }
    21    }
    22 }
    23 
    24 //创建后,还未被销毁的场景列表,方便查看还未被销毁的场景列表,方便内存管理,本属性只读,请不要直接修改
    25 public static var unDestroyedScenes:Array = [];
    26 public function Scene(){
    27    this._setBit(Const.NOT_READY,true);
    28    unDestroyedScenes.push(this);
    29    this._scene = this;
    30    createChildren();
    31 }
    32 
    33 public static function open(url:String,closeOther:Boolean = true,  complete:Handler = null, param:*=null):void{
    34   load(url,Handler.create(null,_onSceneLoaded,[closeOther,complete,param]));
    35 }
    36 
    37 private static function _onSceneLoaded(closeOther:Boolean,complete:Handler,param:*,scene:Scene):void{
    38     scene.open(closeOther,param);
    39     if (complete) complete.runWith(scene);
    40 }
    41 
    42 public static funcion close(url:String,name:String= ""):Boolean{
    43    var flag:Boolean = false;
    44    var list:Array  = Scene.unDestroyedScenes;
    45     for (var i:int=0,n:int=list.length;i<n;i++){
    46      var scene:Scene = list[i];
    47      if (scene.parent && scene.url === url && scene.name == name){
    48     scene.close();
    49     flag = true;
    50        }
    51     }
    52     return flag;
    53 }
    54 
    55 public static function closeAll():void {
    56     var root:Sprite = Scene.root;
    57     for (var i:int = 0, n:int = root.numChildren;i<n;i++){
    58       var scene:Scene = root.getChildAt(0) as Scene;
    59       if (scene is Scene) scene.close();
    60    }
    61 }
    62 
    63 public static function destroy(url:String,name:String=""):Boolean{
    64   var flag:Boolean = false;
    65   var list:Array = Scene.unDestroyedScenes;
    66   for (var i:int=0,n:int=list.length;i<n;i++){
    67        var scene:Scene = list[i];
    68        if (scene.url ===url && scene.name == name){
    69          scene.destroy();
    70          flag = true;
    71        }
    72    }
    73     return flag;
    74 }
    75 
    76 public static function get root():Sprite{
    77      if(!_root){
    78        _root = Laya.stage.addChild(new Sprite()) as Sprite;
    79        _root.name = "root";
    80        Laya.stage.on("resize",null,resize);
    81        function resize():void{
    82            _root.size(Laya.stage.width, Laya.stage.height);
    83            _root.event(Event.RESIZE);
    84            }
    85       resize();
    86       }
    87       return _root;
    88 }

    1. autoDestroyAtClosed : 场景被关闭后,是否自动销毁(销毁节点和使用到的资源),默认为false

    在close方法中,可以看到if (autoDestroyAtClosed) this.destroy();

    2.在open方法中,看到root.addChild(scene);,而在get root中看到_root = Laya.stage.addChild(new Sprite()) as Sprite,这说明所有打开的Scene都被添加到一个叫root的Sprite容器里,这个容器是直接放在stage上了。


    3.参考一下官方例子中如何使用scene的:

    1 static startScene:any = "test/Test2View.scene";
    2 Laya.Scene.open(GameConfig.startScene);

    这里直接调用static open方法,在里面调用了load方法

    public static function load(url:String,complete:Handler = null):void{
          Laya.loader.resetProgress();
          var loader:SceneLoader = new SceneLoader();
          loader.on(Event.COMPLETE,null,create);
          loader.load(url);
          
          function create():void {
            var obj:Object = Loader.getRes(url);
            if(!obj) throw "Can not find scene:" + url;
            if(!obj.props) throw "Scene data is error:" + url;
             var runtime:String = obj.props.runtime ? obj.props.runtime : obj.type;
             var clas:*=ClassUtils.getClass(runtime);
             if(obj.props.renderType=="instance"){
                    var scene:Scene = clas.instance || (clas.instance = new clas());
                    } else {
                     scene = new clas();
                   }
             if (scene && scene is Node){
                   scene.url = rul;
                   if (!scene._getBit(Const.NOT_READY)) complete.runWith(scene);
                   else{
                        scene.on("onViewCreated",null,functon():void{
                              complete && complete.runWith(scene)
                              })
                              scene.createView(obj);
                         }
               }else{
                    throw "Can not find scene:" + runtime;
                }
           }
    }

     

    牵涉到SceneLoader类

    public static const LoadableExtensions:Object = {"scene":Loader.JSON}

    这个映射会把test/Test2View.scene转化为去加载相应的json文件

    Dialog

    laya2.x创建的Dialog:xxDialogUI - > Dialog - > View - > Scene - > Sprite

    Dialog会把Scene中默认的open方法覆盖掉,转交给DialogManager处理

    //Dialog:
    override public function open(closeOther:Boolean = true, param:* = null):void {
        _dealDragArea();
        _param=param;
        manager.open(this, closeOther, isShowEffect);
        manager.lock(false);
    }
    
    //DialogManager:
    public class DialogManager extends Sprite
    
    public function DialogManager() {
        this.mouseEnabled = maskLayer.mouseEnabled = true;
        this.zOrder = 1000;
        
        Laya.stage.addChild(this);
        Laya.stage.on(Event.RESIZE, this, _onResize);
        if (UIConfig.closeDialogOnSide) maskLayer.on("click", this, _closeOnSide);
        _onResize(null);
    }
    
    public function open(dialog:Dialog, closeOther:Boolean = false, showEffect:Boolean=false):void {
        if (closeOther) _closeAll();
        if (dialog.isPopupCenter) _centerDialog(dialog);
        addChild(dialog);
        if (dialog.isModal || this._getBit(Const.HAS_ZORDER)) Laya.timer.callLater(this, _checkMask);
        if (showEffect && dialog.popupEffect != null) dialog.popupEffect.runWith(dialog);
        else doOpen(dialog);
        event(Event.OPEN);
    }

    总结:可以把Scene看做是官方提供的一个场景管理器,像closeOther,closeAll,onOpened,onClosed都是很实用的。

    实例:添加按钮切换场景

    LayaAir2.x开发思路为组件化,脚本化,场景管理开发,项目采用scene管理方式,来管理场景,LayaAir已经对scene做了一系列方案,使得开发者无需考虑场景,关卡,页面的资源,内存管理,只需要单纯的调用接口,管理场景,其它的交给引擎去做,只需要专注游戏逻辑开发即可。

    1.先新建一个脚本

    2.在Start.scene中放一个按钮,就可以添加组件了,这样运行时,点击按钮,就会触发onClick方法打开box2d.scene场景。

    3.按F9设置启动场景为Start.scene,现在运行后就能看到场景切换效果了。

    4.在GameConfig的init方法中就可以看到

    1 static init(){
    2     var reg: Function = Laya.ClassUtils.regClass;
    3     reg("script/Start.ts",Start);
    4 }
    5 //ClassUtils:
    6 public static function regClass(className:String, classDef:*):void {
    7     _classMap[className] = classDef;
    8 }

    注:参考文章https://www.jianshu.com/p/5701f9f854fa

  • 相关阅读:
    利用GetInvalidFileNameChars()得到有效的文件名
    C# 下载远程http文件到本地
    CLR无法从COM 上下文*****转换为COM上下文*****,这种状态已持续60秒。
    Wpf UserControl使用 KeyBinding,失效问题
    C# windows服务知识集锦
    制作Windows服务和安装程序(C#版)
    C语言内存管理
    Python初学注意问题
    msp430学习笔记-USART
    msp430学习笔记-ADC12
  • 原文地址:https://www.cnblogs.com/huayang1995/p/15892003.html
Copyright © 2020-2023  润新知