Laya runtime 擴展腳本 附加腳本

參考
runtime使用
擴展腳本的使用
附加腳本的使用
按照上面的教程,發(fā)現(xiàn)擴展腳本實際上也是在用runtime,而附加腳本則是多了一個子元素:

一、IDE中不同表現(xiàn)

box1使用了擴展腳本,box2使用了runtime,box3使用了附加腳本,ui文件是這樣的:

//注意,擴展腳本和附加腳本的文件后綴不同,分別是prop和script
//MonkeyProp.prop:
<MonkeyProp className="game.MonkeyProp">
    <prop name="speed" tips="數(shù)字類型" type="number"/>
    <prop name="userName" tips="人物名稱" type="string"/>
</MonkeyProp>

//MonkeyProp2.script:
<MonkeyProp2 className="game.MonkeyProp2">
    <prop name="speed" tips="數(shù)字類型" type="number"/>
    <prop name="userName" tips="人物名稱" type="string"/>
</MonkeyProp2>

//TestGapUI.ui:
<Box x="268" y="150" appendProps="laya/pages/MonkeyProp.prop"
 speed="4" userName="xxa" var="box1" editorInfo="compId=45">
  <Image skin="game/doll_1.png" y="41" editorInfo="compId=43"/>
  <Label text="label" x="34" fontSize="36" width="102" height="36"
 name="userN" align="center" color="#100808" editorInfo="compId=44"/>
</Box>

<Box x="292" y="435" runtime="game.MonkeyProp" var="box2" editorInfo="compId=46">
  <Image skin="game/doll_1.png" y="41" editorInfo="compId=47"/>
  <Label text="label" x="34" fontSize="36" width="102" height="36"
 name="userN" align="center" color="#100808" editorInfo="compId=48"/>
</Box>

<Box y="703" x="302" var="box3" editorInfo="compId=49">
  <Image y="41" skin="game/doll_1.png" editorInfo="compId=50"/>
  <Label x="34" width="102" text="label" name="userN" height="36"
 fontSize="36" color="#100808" align="center" editorInfo="compId=51"/>
  <Script editorInfo="source=laya/pages/MonkeyProp2.script;compId=53"/>
</Box>

在IDE中,設(shè)置那兩個自定義屬性speed和userName的位置也不同。擴展腳本因為是繼承自組件本身,所以自定義屬性就在點擊box1時就能看到。而附加腳本,是直接變成box3的一個子元素了,需要選中子元素才能編輯。


image.png
二、生成的UI:

看一下生成的ui,box1和box2都是同樣的類型,而box3還是Box類型。

export class TestGapUI extends View {
    public box1:game.MonkeyProp;
    public box2:game.MonkeyProp;
        public box3:Laya.Box;

    public static  uiView:any ={"type":"View","props":{"width":750,"height":1334},"child":[...
    constructor(){ super()}
    createChildren():void {
                View.regComponent("game.MonkeyProp",game.MonkeyProp);
                View.regComponent("game.MonkeyProp2",game.MonkeyProp2);
        super.createChildren();
        this.createView(ui.TestGapUI.uiView);

    }

uiView部分太長,截取box1和box2看一下:

{"type":"Box","props":{"y":150,"x":268,"var":"box1","userName":"xxa","speed":4,"runtime":"game.MonkeyProp"},

{"type":"Box","props":{"y":435,"x":292,"var":"box2","runtime":"game.MonkeyProp"},

{"type":"Box","props":{"y":703,"x":302,"var":"box3"},
"child":[{"type":"Image","props":{"y":41,"skin":"game/doll_1.png"}},
{"type":"Label","props":{"x":34,"width":102,"text":"label","name":"userN",
"height":36,"fontSize":36,"color":"#100808","align":"center"}},
{"type":"Script","props":{"userName":"extraName","speed":3,"runtime":"game.MonkeyProp2"}

可以看到,擴展腳本是runtime的增強版:可以在IDE上指定屬性,然后把屬性值導(dǎo)出到ui配置中,并且把這個值自動映射類的屬性中。而附加腳本,直接就是多了一個Script類型的子元素。那么它是怎么解析的?
在View.as的createComp方法中可以看到:

if (node.type == "Script") {
    if ("owner" in tChild) {
        tChild["owner"] = comp;
    } else if ("target" in tChild) {
        tChild["target"] = comp;
    }
} else if (node.props.renderType == "mask" || node.props.name == "mask") {
    comp.mask = tChild;
} else {
    tChild is Sprite && comp.addChild(tChild);
}

所以,附加腳本就必需要定義owner或target屬性
另外,這個方法也能看到runtime那些屬性映射的操作:

var props:Object = uiView.props;
for (var prop:String in props) {
    var value:String = props[prop];
    setCompValue(comp, prop, value, view, dataMap);
}
三、擴展腳本和附加腳本對應(yīng)的類:

1.擴展腳本MonkeyProp.ts

namespace game {
    export class MonkeyProp extends Laya.Box {
        /**攻擊速度(也可以不用定義該變量,在這里定義是為了打開該類的時候能夠一目了然的看到對應(yīng)的腳本中添加了哪些屬性)**/
        public speed: number = 0;
        /**人物名稱(也可以不用定義該變量,在這里定義是為了打開該類的時候能夠一目了然的看到對應(yīng)的腳本中添加了哪些屬性)**/
        public userName: string = "";
        /**記錄狀態(tài)**/
        private boo: boolean = false;

        constructor() {
            super();
            console.log("MonkeyProp");
            //自定義的腳本會有時序問題,所以在此添加一個延時
            this.frameOnce(2, this, this.onFrame);
        }

        private onFrame(): void {
            //通過子元素的name值獲取該對象
            var userN: Laya.Label = this.getChildByName("userN") as Laya.Label;
            //設(shè)置文本內(nèi)容為屬性欄中給的值
            userN.text = this.userName;
            this.frameLoop(1, this, this.onLoop);
        }

        /**
         *設(shè)置幀循環(huán),實現(xiàn)左右移動 
         * 
         */
        private onLoop(): void {
            if (this.x <= 0) {
                this.boo = false;
                this.x += this.speed;
            }
            else if (this.x < Laya.stage.width - this.width && this.boo == false) {
                this.x += this.speed;
            }
            else if (this.x >= Laya.stage.width - this.width || this.boo == true) {
                this.x -= this.speed;
                this.boo = true;
            }
        }
    }
}

2.附加腳本MonkeyProp2.ts

namespace game {
    export class MonkeyProp2 {
        /**攻擊速度(也可以不用定義該變量,在這里定義是為了打開該類的時候能夠一目了然的看到對應(yīng)的腳本中添加了哪些屬性)**/
        public speed: number = 0;
        /**人物名稱(也可以不用定義該變量,在這里定義是為了打開該類的時候能夠一目了然的看到對應(yīng)的腳本中添加了哪些屬性)**/
        public userName: string = "";
        /**記錄狀態(tài)**/
        private boo: boolean = false;
        /**定義一個變量來接收Box組件實例**/        
        private monkeyBox:Laya.Sprite;

        /**
         *設(shè)置owner函數(shù),可以直接獲取到添加附加腳本的組件實例 
         * @param value
         * 
         */        
        public set owner(value:any){
            this.monkeyBox = value;
            //自定義的腳本會有時序問題,所以在此添加一個延時
            this.monkeyBox.frameOnce(2,this,this.onLoaded);
        }

        private onLoaded():void
        {
            //通過子元素的name值獲取該對象
            var userN:Laya.Label = this.monkeyBox.getChildByName("userN") as Laya.Label;
            //設(shè)置文本內(nèi)容為屬性欄中給的值
            userN.text = this.userName;
            this.monkeyBox.frameLoop(1,this,this.onLoop);
        }

        /**
         *設(shè)置幀循環(huán),實現(xiàn)左右移動 
         * 
         */
        private onLoop(): void {
            if (this.monkeyBox.x <= 0) {
                this.boo = false;
                this.monkeyBox.x += this.speed;
            }
            else if (this.monkeyBox.x < Laya.stage.width - this.monkeyBox.width && this.boo == false) {
                this.monkeyBox.x += this.speed;
            }
            else if (this.monkeyBox.x >= Laya.stage.width - this.monkeyBox.width || this.boo == true) {
                this.monkeyBox.x -= this.speed;
                this.boo = true;
            }
        }
    }
}
四、應(yīng)用場景

1.更改Laya組件的默認(rèn)行為,但是又不想直接改源代碼,畢竟那樣更新引擎時很麻煩。此時就可以用runtime繼承一下默認(rèn)的組件,然后override一下某些方法。如果是想添加一些額外屬性,并且在IDE中指定不同的值,就可以用擴展腳本了,它算是runtime的可視化增強版,與IDE配合得更緊密。
2.某些組件要實現(xiàn)相同的行為,最常見的例子就是一個Image支持點擊縮放效果的ScaleButton,用runtime就行了。參見官方示例中的:


image.png

3.附加腳本,目前沒有用到。個人理解,它和擴展腳本的區(qū)別,就像組合和繼承的區(qū)別一樣。
4.比較不爽的是擴展腳本和附加腳本都需要延時:

//自定義的腳本會有時序問題,所以在此添加一個延時
this.monkeyBox.frameOnce(2,this,this.onLoaded);

所以還是優(yōu)先考慮使用runTime吧

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,323評論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,650評論 4 61
  • 突然從睡夢中醒來 像往常一樣 翻手機 屏幕里那刺眼的話語 讓心冷卻無讓眼睛相信 看著看著入睡了… 夢里有你快樂的模...
    米夏小雨閱讀 199評論 0 1

友情鏈接更多精彩內(nèi)容