使用白鹭引擎遇到的一些问题以及一些工具分享

用egret也有一段时间了,记录一下遇到的bug和流水账。

 

BUG类

1 Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. 

egret 2.5 里面将WebImageLoader的crossOrigin默认值设置为anonymous就可以了

 

心得:

1 关闭列表的滚动:比较hack的做法

var skin = this.list.skin;
var scroller:egret.gui.Scroller = skin._elementsContent[0];
if( scroller != null)
    scroller.verticalScrollPolicy = "off";

2 监听列表的滚动事件:

这个找了很久

this.list.dataGroup.addEventListener(egret.gui.PropertyChangeEvent.PROPERTY_CHANGE,this.onListTouchEnd, this);

private onListTouchEnd(evt:egret.gui.PropertyChangeEvent){

            var newPos:number = evt.newValue;
            var referPos:number = this.list.dataGroup.scrollRect.bottom-this.list.dataGroup.height;
            if( evt.property == "verticalScrollPosition" && referPos - newPos <= 10){
                //todo dosomething
            }
        }

 

 

工具:

1 抽屉效果

原理: Tween + mask实现

例如对显示对象d实现抽屉效果:

var tw:egret.Tween = egret.Tween.get(this.d,{onChange:this.updateMask,onChangeObj:this},null,true);
this.maskForD = new egret.Rectangle(0,0,0,60);
private updateMask(){
var showWidth:number; if( this.isLeft){ showWidth = 420-(this.itemGroup.x-20); }else{ showWidth = 420 - this.itemGroup.x; } this.maskForD.width = showWidth; this.d.mask = this.maskForItemGroup; }

 

2 帧事件的管理

沿用as的习惯,全局只有一个帧事件。

/**
 * Created by DukeCrushIt on 2015/8/5.
 */
module game {
    export class FrameMgr extends egret.HashObject {
        public constructor() {
            super();
            this.items = [];
            this.itemMap = {};
        }
        public itemMap:Object;
        private items:FrameItem[];
        private stage:egret.Stage;
        public referTime:number;
        public initStage(stage:egret.Stage){
            this.stage = stage;
            this.stage.addEventListener(egret.Event.ENTER_FRAME,this.update, this);
            this.referTime = egret.getTimer();
        }

        public update(evt:egret.Event){
            var temp:number = egret.getTimer();
            var delta:number = temp - this.referTime;
            var len:number = this.items.length;
            var item:FrameItem;
            for(var idx = len-1; idx >= 0; idx--){
                item = this.items[idx];
                item.callFun.call(item.callObj,delta);
            }
            this.referTime = temp;
            Model.SYSTIME += delta;
        }

        public addControll(item:FrameItem){
            if( this.items.indexOf(item) == -1){
                this.items.push(item);
                this.itemMap[item.callObj.name] = item;
            }
        }

        public delController(name:string){
            if( this.items.length == 0 ) return;
            var item:FrameItem = this.itemMap[name];
            if( item != null && item != undefined){
                var idx:number = this.items.indexOf(item);
                if(idx != -1){
                    this.items.splice(idx,1);
                }
            }
            delete this.itemMap[name];
        }

        public isUnderControl(name:string):boolean{
            return this.itemMap[name] != undefined && this.itemMap[name] != null;
        }

        public pause(){
            this.stage.removeEventListener(egret.Event.ENTER_FRAME,this.update, this);
        }

        public resume(){
            this.referTime = egret.getTimer();
            this.stage.addEventListener(egret.Event.ENTER_FRAME,this.update, this);
        }

        private static _instance:FrameMgr;
        public static getInstance():FrameMgr{
            if( FrameMgr._instance == null)
                FrameMgr._instance = new game.FrameMgr();
            return FrameMgr._instance;
        }
    }
}
FrameMgr

配合这个使用:

/**
 * Created by DukeCrushIt on 2015/8/5.
 */
module game {
    export class FrameItem extends egret.HashObject {
        public callObj:any;
        public callFun:Function;
        public constructor() {
            super();
        }
    }
}
FrameItem

3 简单的位移补间

用自带的Tween效率不是很好,于是自己实现了一个,如下:

/**
 * Created by DukeCrushIt on 2015/8/5.
 */
module game{
    export class MoveMgr extends egret.HashObject{
        public name:string;
        public frameItem:FrameItem;
        public constructor(){
            super();
            this.items = [];
            this.name = "movemgr";
            this.frameItem = new game.FrameItem();
            this.frameItem.callObj = this;
            this.frameItem.callFun = this.update;
            FrameMgr.getInstance().addControll(this.frameItem);
        }
        private items:MoveItem[];
        private spareTime:number = 10;
        public update(deltaTime:number){
            if( this.items.length == 0) return;
            var itemLen:number = this.items.length - 1;
            var item:MoveItem;
            var startTime = egret.getTimer();
            var gap:number;
            for(var i = itemLen; i >= 0 ; i--){
                item = this.items[i];
                item.update(deltaTime);
                gap = egret.getTimer() - startTime;
                if( gap >= this.spareTime)
                    break;
            }
        }

        public addItem(item:MoveItem){
            if( this.items.indexOf(item) == -1){
                this.items.push(item);
            }
        }

        public delItem(item:MoveItem){
            var idx:number = this.items.indexOf(item);
            if( idx != -1){
                this.items.splice(idx, 1);
            }
            MoveMgr.reclaim(item);
        }

        public removeAllHairItems(){
            var len:number = this.items.length;
            var item:MoveItem;
            var disObj:egret.DisplayObject;
            for( var idx = len - 1; idx >=0 ; idx--){
                item = this.items[idx];
                disObj = item.disObject;
                if( disObj instanceof Hair){
                    item.finish();
                }
            }
        }

        public finish(){
            var itemLen:number = this.items.length - 1;
            if( itemLen == -1 ) return;
            var item:MoveItem;
            for(var i = itemLen; i >= 0 ; i--){
                item = this.items[i];
                item.finish();
            }
        }

        private static _cache:MoveItem[]=[];
        public static reclaim(item:MoveItem){
            if( MoveMgr._cache.indexOf(item) == -1)
                MoveMgr._cache.push(item);
        }
        public static produce():MoveItem{
            if(MoveMgr._cache.length!=0)
                return MoveMgr._cache.pop();
            return new MoveItem();
        }

        private static _instance:MoveMgr;
        public static getInstance():MoveMgr{
            if( MoveMgr._instance == null)
                MoveMgr._instance = new game.MoveMgr();
            return MoveMgr._instance;
        }
    }
}
MoveMgr

需要配合这个使用:

/**
 * Created by DukeCrushIt on 2015/8/5.
 */
module game{
    export class MoveItem extends egret.HashObject{
        public disObject:egret.DisplayObject;
        private gapX:number;
        private gapY:number;
        public targetX:number;
        public targetY:number;
        public duration:number;
        public past:number;
        private roll:boolean=false;
        public callBackObj:any;
        public callBackFun:Function;
        public constructor(){
            super();
        }
        public init(disObject:egret.DisplayObject,targetX:number,targetY:number,duration:number,cbObj:any=null,cbFun:Function=null,roll:boolean=false){
            this.disObject = disObject;
            this.targetX = targetX;
            this.gapX = targetX - disObject.x;
            this.targetY = targetY;
            this.gapY = targetY - disObject.y;
            this.duration = duration;
            this.past = 0;
            this.callBackObj = cbObj;
            this.callBackFun = cbFun;
            this.roll = roll;
        }

        public update(deltaTime:number){
            this.past += deltaTime;
            if( this.past < this.duration){
                var refer:number = deltaTime/this.duration;
                this.disObject.x += this.gapX*refer;
                this.disObject.y += this.gapY*refer;
                if( this.roll){
                    this.disObject.rotation += this.gapX > 0 ? 3 : -3;
                }
            }else{
                this.disObject.x = this.targetX;
                this.disObject.y = this.targetY;
                if( this.callBackObj!= null && this.callBackObj != null)
                    this.callBackFun.call(this.callBackObj);
                MoveMgr.getInstance().delItem(this);
            }
            if( this.disObject.parent == null){
                MoveMgr.getInstance().delItem(this);
            }
        }

        public finish(){
            if(this.disObject != null){
                this.disObject.x = this.targetX;
                this.disObject.y = this.targetY;
            }
            this.roll = false;
            MoveMgr.getInstance().delItem(this);
        }
    }
}
MoveItem

4 做了一个简单的重力系统,如下:

/**
 * Created by DukeCrushIt on 2015/7/30.
 */
module dukeutil{
    export class GravitySystem extends egret.HashObject {
        public gravity:number = 0.98;
        private items:GravityItem[] = [];
        private itemMap:Object = {};
        private frameItem:game.FrameItem;
        public name:string;
        public constructor(){
            super();
            this.name = "gravitysystem";
            this.frameItem = new game.FrameItem();
            this.frameItem.callFun = this.update;
            this.frameItem.callObj = this;
            game.FrameMgr.getInstance().addControll(this.frameItem);
        }

        public addItem(item:GravityItem){
            if( this.items.indexOf(item) == -1 ){
                this.items.push(item);
                this.itemMap[item.displayObject.name] = item;
            }
        }

        public contains(name:string):boolean{
            return this.itemMap[name] != undefined;
        }
        private spareTime:number = 10;
        private update(delata:number){
            var startTime = egret.getTimer();
            var gap:number;
            var len:number = this.items.length;
            var idx:number;
            var item:GravityItem;
            var displayObject:egret.DisplayObject;
            for(idx = len-1; idx >= 0; idx--){
                item = this.items[idx];
                displayObject = item.displayObject;
                if( item.phase == 0){
                    displayObject.x+=item.currentSpeedX;
                    item.currentSpeedY += this.gravity;
                    displayObject.y += item.currentSpeedY;
                    if( item.doublePhase && displayObject.y >= item.targetY){
                            item.phase = 1;
                            item.currentSpeedX = item.currentSpeedX*0.8;
                    }else if( !item.doublePhase && (item.currentSpeedY < 1 && item.currentSpeedY > -1)){
                        delete this.itemMap[item.displayObject.name];
                        this.items.splice(idx,1);
                        if( item.overCall != null && item.overCallObj != null)
                            item.overCall.call(item.overCallObj);
                        item.reset();
                        GravitySystem.reclaim(item);
                    }
                }else{
                    item.step++;
                    item.currentSpeedX = item.currentSpeedX*0.9;
                    displayObject.x+=item.currentSpeedX;

                    //if( item.currentSpeedX > 0){
                    //    displayObject.rotation+=2;
                    //}else{
                    //    displayObject.rotation-=2;
                    //}
                    if( item.step >= 30){
                        delete this.itemMap[item.displayObject.name];
                        this.items.splice(idx,1);
                        if( item.overCall != null && item.overCallObj != null)
                            item.overCall.call(item.overCallObj);
                        item.reset();
                        GravitySystem.reclaim(item);
                    }
                }
                if( displayObject.x <= 0 || displayObject.x >= game.GameConst.StageW){
                    item.currentSpeedX = -item.currentSpeedX;
                }
                gap = egret.getTimer() - startTime;
                if( gap >= this.spareTime)
                    break;
            }
        }

        private static _itemCache:GravityItem[] = [];
        public static produce():GravityItem{
            if( GravitySystem._itemCache.length != 0)
                return GravitySystem._itemCache.pop();
            return new GravityItem();
        }
        public static reclaim(item:GravityItem){
            if( GravitySystem._itemCache.indexOf(item) == -1)
                GravitySystem._itemCache.push(item);
        }

        private static _instance:GravitySystem;
        public static getInstance():GravitySystem{
            if( GravitySystem._instance == null )
                GravitySystem._instance = new dukeutil.GravitySystem();
            return GravitySystem._instance;
        }
    }
}
GravitySystem

配合使用的类:

/**
 * Created by DukeCrushIt on 2015/7/30.
 */
module dukeutil{
    export class GravityItem extends egret.HashObject{
        public phase:number=0;//0 gravity 1 roll to
        public doublePhase:boolean = true;
        public displayObject:egret.DisplayObject;
        public targetY:number;
        public currentSpeedX:number;
        public currentSpeedY:number;
        public step:number=0;
        public overCallObj:any;
        public overCall:Function;
        public constructor(){
            super();
        }
        public reset(){
            this.phase = 0;
            this.step = 0;
            this.doublePhase = true;
            this.overCall = null;
            this.overCallObj = null;
        }
    }
}
View Code

 

 2016-1-8:

egret.gui.BitmapLabel自定义font不能居中问题

在egret wing里面设置textAlign是通过setStyle去生效的,这个没有附加到BitmapLabel._bitmapText上去,因为BitmapLabel._bitmapText是通过_addToDisplayList()的方式去加上去的,这是官方比较hack的方式去将非UIComponent的元件加到gui显示列表里面去,所以这个style是无法生效的,我的解决方法很简单,直接给BitmapLabel加textAlign的setter和getter,然后在commiteProperties()里面判断textAlign是否有变更,有的话就赋值给BitmapLabel._bitmapText.textAlign,这个方法只能在程序里面手动去设置,egret wing里面的设置还是无效的,问题解决,修改后的BitmapLabel.ts如下:

  1 //////////////////////////////////////////////////////////////////////////////////////
  2 //
  3 //  Copyright (c) 2014-2015, Egret Technology Inc.
  4 //  All rights reserved.
  5 //  Redistribution and use in source and binary forms, with or without
  6 //  modification, are permitted provided that the following conditions are met:
  7 //
  8 //     * Redistributions of source code must retain the above copyright
  9 //       notice, this list of conditions and the following disclaimer.
 10 //     * Redistributions in binary form must reproduce the above copyright
 11 //       notice, this list of conditions and the following disclaimer in the
 12 //       documentation and/or other materials provided with the distribution.
 13 //     * Neither the name of the Egret nor the
 14 //       names of its contributors may be used to endorse or promote products
 15 //       derived from this software without specific prior written permission.
 16 //
 17 //  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 18 //  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 19 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20 //  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 21 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 22 //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
 23 //  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 24 //  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 25 //  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 26 //  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27 //
 28 //////////////////////////////////////////////////////////////////////////////////////
 29 
 30 
 31 module egret.gui {
 32 
 33     /**
 34      * @class egret.gui.BitmapLabel
 35      * @classdesc
 36      * 一行或多行不可编辑的位图文本控件
 37      * @extends egret.gui.UIComponent
 38      */
 39     export class BitmapLabel extends UIComponent implements IDisplayText {
 40 
 41         private _bitmapText:BitmapText = null;
 42 
 43         /**
 44          * @method egret.gui.Label#constructor
 45          */
 46         public constructor() {
 47             super();
 48             this.addEventListener(UIEvent.UPDATE_COMPLETE, this.updateCompleteHandler, this);
 49         }
 50 
 51         /**
 52          * 一个验证阶段完成
 53          */
 54         private updateCompleteHandler(event:UIEvent):void {
 55             this.lastUnscaledWidth = NaN;
 56         }
 57 
 58         private _textChanged:boolean = false;
 59         private _text:string = "";
 60         /**
 61          * @member egret.gui.BitmapLabel#text
 62          * 设置或获取显示文本
 63          */
 64         public set text(value:string) {
 65             if (this._text == value)
 66                 return;
 67             this._text = value;
 68             this._textChanged = true;
 69             this.invalidateProperties();
 70             this.invalidateSize();
 71             this.invalidateDisplayList();
 72         }
 73 
 74         public get text():string {
 75             return this._text;
 76         }
 77 
 78         private fontChanged:boolean = false;
 79 
 80         public _font:any;
 81         /**
 82          * 位图字体标识符,可以是BitmapFont对象或者在资源表中的key。
 83          * @member egret.gui.BitmapLabel#font
 84          */
 85         public get font():any {
 86             return this._font;
 87         }
 88 
 89         public set font(value:any) {
 90             if (this._font == value)
 91                 return;
 92             this._font = value;
 93             if (this.createChildrenCalled) {
 94                 this.parseFont();
 95             }
 96             else {
 97                 this.fontChanged = true;
 98             }
 99             this.invalidateProperties();
100             this.invalidateSize();
101             this.invalidateDisplayList();
102         }
103 
104         private _isLetterSpacingChanged:boolean = false;
105         public _letterSpacing:number = 0;
106         /**
107          * 字符之间的距离
108          * @default 0
109          * @param value
110          */
111         public set letterSpacing(value:number) {
112             this._setLetterSpacing(value);
113         }
114 
115         public _setLetterSpacing(value:number):void {
116             this._letterSpacing = value;
117 
118             this._isLetterSpacingChanged = true;
119             this.invalidateProperties();
120             this.invalidateSize();
121             this.invalidateDisplayList();
122         }
123 
124         public get letterSpacing():number {
125             return this._letterSpacing;
126         }
127         
128         private _isTextAlignChanged:boolean = false;
129         public _textAlign:string = "left";
130         /**
131          * 字符之间的距离
132          * @default 0
133          * @param value
134          */
135         public set textAlign(value:string) {
136             this._settextAlign(value);
137         }
138 
139         public _settextAlign(value:string):void {
140             this._textAlign = value;
141 
142             this._isTextAlignChanged = true;
143             this.invalidateProperties();
144             this.invalidateSize();
145             this.invalidateDisplayList();
146         }
147 
148         public get textAlign():string {
149             return this._textAlign;
150         }
151 
152         private _isLineSpacingChanged:boolean = false;
153         public _lineSpacing:number = 0;
154         /**
155          * 行与行之间的距离
156          * @default 0
157          * @param value
158          */
159         public set lineSpacing(value:number) {
160             this._setLineSpacing(value);
161         }
162 
163         public _setLineSpacing(value:number):void {
164             this._lineSpacing = value;
165 
166             this._isLineSpacingChanged = true;
167             this.invalidateProperties();
168             this.invalidateSize();
169             this.invalidateDisplayList();
170         }
171 
172         public get lineSpacing():number {
173             return this._lineSpacing;
174         }
175 
176         private createChildrenCalled:boolean = false;
177 
178         /**
179          * 创建子对象
180          */
181         public createChildren():void {
182             super.createChildren();
183             if (!this._bitmapText) {
184                 this.checkBitmapText();
185             }
186             if (this.fontChanged) {
187                 this.parseFont();
188             }
189             this.createChildrenCalled = true;
190         }
191 
192         /**
193          * 皮肤解析适配器
194          */
195         private static assetAdapter:IAssetAdapter;
196 
197         /**
198          * 解析source
199          */
200         private parseFont():void {
201             this.fontChanged = false;
202             var adapter:IAssetAdapter = BitmapLabel.assetAdapter;
203             if (!adapter) {
204                 adapter = this.getAdapter();
205             }
206             if (!this._font) {
207                 this.onFontChanged(null, null);
208             }
209             else {
210                 adapter.getAsset(this._font, this.onFontChanged, this, null);
211             }
212         }
213 
214         /**
215          * 获取资源适配器
216          */
217         private getAdapter():IAssetAdapter {
218             var adapter:IAssetAdapter;
219             try {
220                 adapter = $getAdapter("egret.gui.IAssetAdapter");
221             }
222             catch (e) {
223                 adapter = new DefaultAssetAdapter();
224             }
225             BitmapLabel.assetAdapter = adapter;
226             return adapter;
227         }
228 
229         /**
230          * 皮肤发生改变
231          */
232         private onFontChanged(bitmapFont:any, font:any):void {
233             if (font !== this._font)
234                 return;
235             this._bitmapText.font = bitmapFont;
236             this.invalidateSize();
237             this.invalidateDisplayList();
238         }
239 
240 
241         /**
242          * 上一次测量的宽度
243          */
244         private lastUnscaledWidth:number = NaN;
245 
246         private _padding:number = 0;
247         /**
248          * 四个边缘的共同内边距。若单独设置了任一边缘的内边距,则该边缘的内边距以单独设置的值为准。
249          * 此属性主要用于快速设置多个边缘的相同内边距。默认值:0。
250          * @member egret.gui.BitmapLabel#padding
251          */
252         public get padding():number {
253             return this._padding;
254         }
255 
256         public set padding(value:number) {
257             if (this._padding == value)
258                 return;
259             this._padding = value;
260             this.invalidateSize();
261             this.invalidateDisplayList();
262         }
263 
264         private _paddingLeft:number = NaN;
265         /**
266          * 文字距离左边缘的空白像素,若为NaN将使用padding的值,默认值:NaN。
267          * @member egret.gui.BitmapLabel#paddingLeft
268          */
269         public get paddingLeft():number {
270             return this._paddingLeft;
271         }
272 
273         public set paddingLeft(value:number) {
274             if (this._paddingLeft == value)
275                 return;
276 
277             this._paddingLeft = value;
278             this.invalidateSize();
279             this.invalidateDisplayList();
280         }
281 
282         /**
283          *
284          * @type {number}
285          * @private
286          */
287         private _paddingRight:number = NaN;
288         /**
289          * 文字距离右边缘的空白像素,若为NaN将使用padding的值,默认值:NaN。
290          * @member egret.gui.BitmapLabel#paddingRight
291          */
292         public get paddingRight():number {
293             return this._paddingRight;
294         }
295 
296         public set paddingRight(value:number) {
297             if (this._paddingRight == value)
298                 return;
299 
300             this._paddingRight = value;
301             this.invalidateSize();
302             this.invalidateDisplayList();
303         }
304 
305         /**
306          *
307          * @type {number}
308          * @private
309          */
310         private _paddingTop:number = NaN;
311         /**
312          * 文字距离顶部边缘的空白像素,若为NaN将使用padding的值,默认值:NaN。
313          * @member egret.gui.BitmapLabel#paddingTop
314          */
315         public get paddingTop():number {
316             return this._paddingTop;
317         }
318 
319         public set paddingTop(value:number) {
320             if (this._paddingTop == value)
321                 return;
322 
323             this._paddingTop = value;
324             this.invalidateSize();
325             this.invalidateDisplayList();
326         }
327 
328         /**
329          *
330          * @type {number}
331          * @private
332          */
333         private _paddingBottom:number = NaN;
334         /**
335          * 文字距离底部边缘的空白像素,若为NaN将使用padding的值,默认值:NaN。
336          * @member egret.gui.BitmapLabel#paddingBottom
337          */
338         public get paddingBottom():number {
339             return this._paddingBottom;
340         }
341 
342         public set paddingBottom(value:number) {
343             if (this._paddingBottom == value)
344                 return;
345 
346             this._paddingBottom = value;
347             this.invalidateSize();
348             this.invalidateDisplayList();
349         }
350 
351         /**
352          * 计算  容器默认大小的最小值和最大值
353          * @method egret.gui.BitmapLabel#measure
354          */
355         public measure():void {
356             //先提交属性,防止样式发生改变导致的测量不准确问题。
357             if (this._UIC_Props_._invalidatePropertiesFlag)
358                 this.validateProperties();
359             if (this.isSpecialCase()) {
360                 if (isNaN(this.lastUnscaledWidth)) {
361                     this._UIC_Props_._oldPreferWidth = NaN;
362                     this._UIC_Props_._oldPreferHeight = NaN;
363                 }
364                 else {
365                     this.measureUsingWidth(this.lastUnscaledWidth);
366                     return;
367                 }
368             }
369 
370             var availableWidth:number;
371 
372             if (!isNaN(this.$getExplicitWidth())) {
373                 availableWidth = this.$getExplicitWidth();
374             }
375             else if (this.maxWidth != 10000)
376                 availableWidth = this.maxWidth;
377 
378             this.measureUsingWidth(availableWidth);
379         }
380 
381         /**
382          * 特殊情况,组件尺寸由父级决定,要等到父级UpdateDisplayList的阶段才能测量
383          */
384         private isSpecialCase():boolean {
385             return (!isNaN(this.percentWidth) || (!isNaN(this.left) && !isNaN(this.right))) &&
386                 isNaN(this.$getExplicitWidth()) &&
387                 isNaN(this.percentHeight);
388         }
389 
390         /**
391          * 使用指定的宽度进行测量
392          */
393         private measureUsingWidth(w:number):void {
394             if (this._textChanged) {
395                 this._bitmapText.text = this._text;
396             }
397 
398             if (this._isLetterSpacingChanged) {
399                 this._bitmapText.letterSpacing = this._letterSpacing;
400             }
401             if (this._isLineSpacingChanged) {
402                 this._bitmapText.lineSpacing = this._lineSpacing;
403             }
404             if( this._isTextAlignChanged){
405                 this._bitmapText.textAlign = this._textAlign;
406             }
407 
408             var padding:number = isNaN(this._padding) ? 0 : this._padding;
409             var paddingL:number = isNaN(this._paddingLeft) ? padding : this._paddingLeft;
410             var paddingR:number = isNaN(this._paddingRight) ? padding : this._paddingRight;
411             var paddingT:number = isNaN(this._paddingTop) ? padding : this._paddingTop;
412             var paddingB:number = isNaN(this._paddingBottom) ? padding : this._paddingBottom;
413 
414             this._bitmapText.width = NaN;
415             this._bitmapText.height = NaN;
416             if (!isNaN(w)) {
417                 this._bitmapText.width = w - paddingL - paddingR;
418                 this.measuredWidth = Math.ceil(this._bitmapText.width);
419                 this.measuredHeight = Math.ceil(this._bitmapText.height);
420             }
421             else {
422                 this.measuredWidth = Math.ceil(this._bitmapText.width);
423                 this.measuredHeight = Math.ceil(this._bitmapText.height);
424             }
425             this.measuredWidth += paddingL + paddingR;
426             this.measuredHeight += paddingT + paddingB;
427 
428         }
429 
430         /**
431          * 通过设置此容器子项的位置和大小来响应大小更改
432          * @method egret.gui.BitmapLabel#updateDisplayList
433          * @param unscaledWidth {number}
434          * @param unscaledHeight {number}
435          */
436         public updateDisplayList(unscaledWidth:number, unscaledHeight:number):void {
437             super.updateDisplayList(unscaledWidth, unscaledHeight);
438             if (!this._bitmapText)
439                 return;
440             var padding:number = isNaN(this._padding) ? 0 : this._padding;
441             var paddingL:number = isNaN(this._paddingLeft) ? padding : this._paddingLeft;
442             var paddingR:number = isNaN(this._paddingRight) ? padding : this._paddingRight;
443             var paddingT:number = isNaN(this._paddingTop) ? padding : this._paddingTop;
444             var paddingB:number = isNaN(this._paddingBottom) ? padding : this._paddingBottom;
445 
446             this._bitmapText.x = paddingL;
447             this._bitmapText.y = paddingT;
448             if (this.isSpecialCase()) {
449                 var firstTime:boolean = isNaN(this.lastUnscaledWidth) ||
450                     this.lastUnscaledWidth != unscaledWidth;
451                 this.lastUnscaledWidth = unscaledWidth;
452                 if (firstTime) {
453                     this._UIC_Props_._oldPreferWidth = NaN;
454                     this._UIC_Props_._oldPreferHeight = NaN;
455                     this.invalidateSize();
456                     return;
457                 }
458             }
459             //防止在父级validateDisplayList()阶段改变的text属性值,
460             //接下来直接调用自身的updateDisplayList()而没有经过measure(),使用的测量尺寸是上一次的错误值。
461             if (this._UIC_Props_._invalidateSizeFlag)
462                 this.validateSize();
463 
464             if (!this._bitmapText.visible)//解决初始化时文本闪烁问题
465                 this._bitmapText.visible = true;
466 
467             this._bitmapText.width = unscaledWidth - paddingL - paddingR;
468             var unscaledTextHeight:number = unscaledHeight - paddingT - paddingB;
469             this._bitmapText.height = unscaledTextHeight;
470 
471         }
472 
473         private checkBitmapText() {
474             if (this._bitmapText)
475                 return;
476             this._bitmapText = new BitmapText();
477             this._bitmapText.text = this._text;
478             this._bitmapText.letterSpacing = this._letterSpacing;
479             this._bitmapText.lineSpacing = this._lineSpacing;
480             this._bitmapText.textAlign = this._textAlign;
481             this._textChanged = false;
482             this._isLetterSpacingChanged = false;
483             this._isLineSpacingChanged = false;
484             this._isTextAlignChanged = false;
485             this._addToDisplayList(this._bitmapText);
486         }
487 
488         /**
489          * 处理对组件设置的属性
490          */
491         public commitProperties():void {
492             super.commitProperties();
493 
494             if (!this._bitmapText) {
495                 this.checkBitmapText();
496             }
497             if (this._textChanged) {
498                 this._bitmapText.text = this._text;
499                 this._textChanged = false;
500             }
501             if (this._isLetterSpacingChanged) {
502                 this._bitmapText.letterSpacing = this._letterSpacing;
503                 this._isLetterSpacingChanged = false;
504             }
505             if (this._isLineSpacingChanged) {
506                 this._bitmapText.lineSpacing = this._lineSpacing;
507                 this._isLineSpacingChanged = false;
508             }
509             if (this._isTextAlignChanged) {
510                 this._bitmapText.textAlign = this._textAlign;
511                 this._isTextAlignChanged = false;
512             }
513         }
514 
515     }
516 }
BitmapLabel.ts

Sound.play()循环播放导致声音重复加载的问题

产生的原因是HtmlSoundChannel.ts在播放完成的时候,判断到loops的时候,直接重新this.audio.load(),然后浏览器去进行了加载,至于浏览器为什么不是从缓存里面去加载而是去服务器上加载,我就不知道了,我只知道,判断一下然后去确定是否要去加载,治愈官方说的有的手机会播放不了,对于大型游戏,例如我们项目来说,其实声音在大部分机型上能播放就可以了,最起码我是这么认为的:

  1 //////////////////////////////////////////////////////////////////////////////////////
  2 //
  3 //  Copyright (c) 2014-2015, Egret Technology Inc.
  4 //  All rights reserved.
  5 //  Redistribution and use in source and binary forms, with or without
  6 //  modification, are permitted provided that the following conditions are met:
  7 //
  8 //     * Redistributions of source code must retain the above copyright
  9 //       notice, this list of conditions and the following disclaimer.
 10 //     * Redistributions in binary form must reproduce the above copyright
 11 //       notice, this list of conditions and the following disclaimer in the
 12 //       documentation and/or other materials provided with the distribution.
 13 //     * Neither the name of the Egret nor the
 14 //       names of its contributors may be used to endorse or promote products
 15 //       derived from this software without specific prior written permission.
 16 //
 17 //  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 18 //  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 19 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20 //  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 21 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 22 //  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
 23 //  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 24 //  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 25 //  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 26 //  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27 //
 28 //////////////////////////////////////////////////////////////////////////////////////
 29 
 30 module egret.web {
 31 
 32     /**
 33      * @private
 34      * @inheritDoc
 35      */
 36     export class HtmlSoundChannel extends egret.EventDispatcher implements egret.SoundChannel {
 37 
 38 
 39         /**
 40          * @private
 41          */
 42         $url:string;
 43         /**
 44          * @private
 45          */
 46         $loops:number;
 47         /**
 48          * @private
 49          */
 50         $startTime:number = 0;
 51         /**
 52          * @private
 53          */
 54         private audio:HTMLAudioElement = null;
 55 
 56         //声音是否已经播放完成
 57         private isStopped:boolean = false;
 58 
 59         /**
 60          * @private
 61          */
 62         constructor(audio:HTMLAudioElement) {
 63             super();
 64             audio.addEventListener("ended", this.onPlayEnd);
 65             this.audio = audio;
 66         }
 67 
 68         $play():void {
 69             if (this.isStopped) {
 70                 egret.$error(1036);
 71                 return;
 72             }
 73 
 74             try {
 75                 this.audio.currentTime = this.$startTime;
 76             }
 77             catch (e) {
 78 
 79             }
 80             finally {
 81                 this.audio.play();
 82             }
 83         }
 84 
 85         /**
 86          * @private
 87          */
 88         private onPlayEnd = () => {
 89             if (this.$loops == 1) {
 90                 this.stop();
 91 
 92                 this.dispatchEventWith(egret.Event.SOUND_COMPLETE);
 93                 return;
 94             }
 95 
 96             if (this.$loops > 0) {
 97                 this.$loops--;
 98             }
 99 
100             /////////////
101             if( !this.audio.ended)
102                 this.audio.load();
103             this.$play();
104         };
105 
106         /**
107          * @private
108          * @inheritDoc
109          */
110         public stop() {
111             if (!this.audio)
112                 return;
113             var audio = this.audio;
114             audio.pause();
115             audio.removeEventListener("ended", this.onPlayEnd);
116             this.audio = null;
117 
118             HtmlSound.$recycle(this.$url, audio);
119         }
120 
121         /**
122          * @private
123          * @inheritDoc
124          */
125         public get volume():number {
126             if (!this.audio)
127                 return 1;
128             return this.audio.volume;
129         }
130 
131         /**
132          * @inheritDoc
133          */
134         public set volume(value:number) {
135             if (this.isStopped) {
136                 egret.$error(1036);
137                 return;
138             }
139 
140             if (!this.audio)
141                 return;
142             this.audio.volume = value;
143         }
144 
145         /**
146          * @private
147          * @inheritDoc
148          */
149         public get position():number {
150             if (!this.audio)
151                 return 0;
152             return this.audio.currentTime;
153         }
154     }
155 }
HtmlSoundChannel.ts

 QQ玩吧声音加载和播放问题:

Android QQ玩吧的页面如果有嵌入jsbridge.js的话,egret会判断是否是玩吧,时候有jsbridge里面的接口,有的话会强制使用相对路径,详见HtmlCapbility搜索"wanba"就可以看到了,此时玩吧会使用他们的audio播放程序去加载和播放audio,cdn以及绝对路径都会没有用,resource一定要存放在代码的相对根目录下才能用。

所有细节可以参考:HtmlCapability以及QQSound中参考

解决方法很简单,去掉页面里面的jsbridge.js的嵌入,其实这个js文件没有什么用,去掉后android上QQ玩吧会默认使用egret.HtmlSound去播放声音

 



你可能感兴趣的:(使用白鹭引擎遇到的一些问题以及一些工具分享)