1.動態添加的腳本,腳本事件不執行。
寫好了腳本XTimer,采用動態addComponent(Xtimer),但是腳本的start update都不執行。
代碼如下:
var node = new cc.Node('[XTimer]') //調用新建的node的addComponent函數,會返回一個sprite的對象 node.addComponent(XTimer);
檢查發現一切正常,就連輸出添加后的alert("BBBBBBBBBBBBB:" + node.active + " " + ttt.enabled); 這兩個值都是ture。而且發現將XTimer拖動到場景物體上就正常,只有動態添加的不正常。
后來發現是未給node設置父節點的問題。但我想把node就在場景跟節點中,所以在節點后添加如下代碼。
var scene = cc.director.getScene(); node.setParent(scene);
OK,正常運行了。
====================================
2.getChildByName獲取不到子物體。
今天發現getChildByName獲取不到層次2次以上的子物體。如
var life2 = this.obj.getChildByName("dao/boxlife2");
找了很多資料才知道:
export default class ui_page_battle extends UIBaseWindow { public numid: string = "-1"; public _AwakeImpl() { this.numid = GUtil.GetUUID(); GUtil.BindOnClick(this.txtBtn, this.node, "txtBtnClick", "222"); XObserverCore.RegisterNotification(ConstDefineNotifiStr.note_mainplayerfall,this.OnGameOver); } public txtBtnClick(event, customEventData): void { // 這里 event 是一個 Event 對象,你可以通過 event.target 取到事件的發送節點 var node = event.target; var button: cc.Button = node.getComponent(cc.Button); //// 這里的 customEventData 參數就等於你之前設置的 "foobar" ////alert("btn:" + customEventData); ////button.node.destroy(); //button.node.y += 50; this.CreateNewPlayerToSence(); this.txtBtn.node.active = false; } public OnGameOver(param: EventParam): void { this.Btn_Reset.active = true;//以這種方式注冊的訂閱者在這里Btn_Reset 始終為undifine,就是根本就未定義。就連此時打印numid都是undefine證明觀察者管理器調用的OnGameOver函數並非注冊時該函數所在的對象。這里猜測着是js的機制,因為之前綁定按鈕事件居然要指定函數所在的腳步名稱、節點、以及函數名稱。 } }
這里測試了很多總方法,如果是直接
ui_page_battle.Instance.OnGameOver();的話就一切正常,再次證明了上圖委托調用的猜想。這里將代碼修改為在匿名函數里調用居然正常了。
export default class ui_page_battle extends UIBaseWindow { public numid: string = "-1"; public _AwakeImpl() { this.numid = GUtil.GetUUID(); this.InitUIObject(); GUtil.BindOnClick(this.txtBtn, this.node, "txtBtnClick", "222"); XObserverCore.RegisterNotification(ConstDefineNotifiStr.note_mainplayerfall, (o) => { this.OnGameOver(o);//改成這樣就正常了 }); this.txtBtn.node.active = false; } public KeyDebug(o: EventParam): void { //alert("999999999999999999999999:" + this.numid); } public _StartOpenImpl() { //alert("5555555555:"); //this.Btn_Reset.active = false; } public _UpdateImpl(dt) { //alert("333333333333333333333333333333:" + this.node.name + " " + this.Btn_Reset.name + " " + this.numid); } public _DestroyImpl() { } public txtBtnClick(event, customEventData): void { // 這里 event 是一個 Event 對象,你可以通過 event.target 取到事件的發送節點 var node = event.target; var button: cc.Button = node.getComponent(cc.Button); //// 這里的 customEventData 參數就等於你之前設置的 "foobar" ////alert("btn:" + customEventData); ////button.node.destroy(); //button.node.y += 50; this.CreateNewPlayerToSence(); this.txtBtn.node.active = false; } public OnGameOver(param: EventParam): void { this.Btn_Reset.active = true; } }
這里這個得特別注意。
附錄:上面服的調用方法也可用下面這樣調用:
start() { let self = this;//用self的方式調用就可避免undifine的問題 cc.loader.downloader.loadSubpackage('subpackages', function (err) { if (err) { return console.error(err); } self.LoadInit(); }); } private LoadInit() { this.gameCore = new GameCore(); this.gameCore.Register(); }
3.操作符遠近的問題================================
var ui: UIBaseWindow = this.GetGameIngWindow(pageName);UI不為空 if (ui != null) {//為真 alert("2222222222222"); this.RemoveWindow(ui); ui.CloseWindow(() => { if (backcall != null) { backcall(); } }); } if (ui! = null) {!號和=號中建有了空格,此時條件為假 alert("2222222222222"); this.RemoveWindow(ui); ui.CloseWindow(() => { if (backcall != null) { backcall(); } }); }
4.設置局部坐標和世界坐標
item.setPosition(pos);
當item是世界根物體時 設置的坐標就是世界坐標,如果是子物體,就是設置它的局部坐標。
這里要特別注意多個子物體嵌套時,比如A。B。C。A是世界,B是A的自物體同時是C的父物體。且B如果局部坐標不為(0,0),這時如果將C的局部坐標轉換為世界坐標是無法正確的。必須一級一級向上層層轉換。
5.委托回調時調用this里的屬性是undefined的問題。
如:
public useWeaponCtrl: UseWeaponControl; private start(){ let self = this; item.RegisterCollisionCall(self.OnCollisioned); } private OnCollisioned(layer: string, otherCollider: cc.Node) { var other = <cc.Node>otherCollider; switch (layer) { case "monster": var otherCtrl: IPlayerControl = other.getComponent(IPlayerControl); console.log("7777777777777777:", this.strkey); console.log("6666666666666:", layer, " ", this.useWeaponCtrl.node.getComponent(IPlayerControl)); otherCtrl.player.useFight.AcceptAtk(this.useWeaponCtrl.node.getComponent(IPlayerControl)); XAudio.Play("data/audio/audio_hurt", 1, false); break; } }
如果是以item.RegisterCollisionCall(self.OnCollisioned);這種方式回調,受限於js的底層架構問題,回調后再OnCollisioned()函數里這個對象是未定義的。比如
this.useWeaponCtrl就是undefined
解決方法是在注冊委托時直接構建一個匿名函數,然后在匿名函數里調用本對象里的方法,就像下面這樣。
public useWeaponCtrl: UseWeaponControl; private start(){ let self = this; item.RegisterCollisionCall((layer: string, other: cc.Node) => { self.OnCollisioned(layer, other); }); } private OnCollisioned(layer: string, otherCollider: cc.Node) { var other = <cc.Node>otherCollider; switch (layer) { case "monster": var otherCtrl: IPlayerControl = other.getComponent(IPlayerControl); console.log("7777777777777777:", this.strkey); console.log("6666666666666:", layer, " ", this.useWeaponCtrl.node.getComponent(IPlayerControl)); otherCtrl.player.useFight.AcceptAtk(this.useWeaponCtrl.node.getComponent(IPlayerControl)); XAudio.Play("data/audio/audio_hurt", 1, false); break; } }
這樣調用就完全正確。
4.集合第二次判斷為空的問題。
private RefreshWeaponList(): void { this.playerslist.Clear(); this.playerslist = XTask.GetAllTaskList(); console.log("7777777777777777777777777:"+this.playerslist.Count.toString()); }
這里this.playerslist.Clear();第一次執行沒問題。但第二次執行時,由於playerlist已經等於了XTask.GetAllTaskList();且由於這里的playerlist是引用類型。所以第二次Clear會直接Clear掉
XTask.GetAllTaskList();這里可以去掉Clear。所以在第二行不要直接使用等於,使用AddRange就可以用Clear了。
----------