Ergetソース分析(1):エントリファイル分析


egretのgithubアドレスはhttps://github.com/egret-labs...ああ、みんな自分でgit cloneで地元に行きます.
一.交差点htmlファイル
ergetWingで新しいプロジェクトを作成し、ルートディレクトリの下のindexを開きます.html、これがプロジェクトのエントリファイルです.ゲームの内容をロードしたDIVコンテナを見てみましょう.
   
/** * { * "renderMode":, // ,"canvas" "webgl" * "audioType": 0 // ,0: ,1:qq audio,2:web audio,3:audio * "antialias": //WebGL ,true: ,false: , false * "retina": // devicePixelRatio * } **/ egret.runEgret({renderMode:"webgl", audioType:0});

ここは公式の配置説明です.ソースコードを後で分析するので、ざっと見てみましょう.
Data-entry-class="Main"プロジェクトのエントリファイルを設定し、プロジェクトのエントリクラスを表し、デフォルトはMainであり、カスタマイズが必要な場合はプロジェクトにクラスを作成し、ここでクラスの名前を構成する必要があります.
data-orientation="auto"回転モードを設定します.
Data-scale-mode="showAll"スケールモードを設定します.
data-frame-rate="30"ここでは実行フレームレートです.
Data-content-width="480"とdata-content-height="800"は、舞台の設計幅と高さを設定するために使用されます.
Data-show-paint-rect="false"設定汚い長方形を表示する再描画領域.
Data-multi-fingered="2"マルチタッチ設定
data-show-fps="false"data-show-log="false"ここで表示フレームレートとlogを設定し、デバッグ時にのみ表示され、パブリッシュされたバージョンは削除されます.
Data-log-filter=」は正規表現のフィルタ条件を設定し、ログテキストがこの正規表現に一致したときにこのログを表示します.data-log-filter=「^egret」では、egretで始まるログのみが表示されます.
data-show-fps-style="x:0,y:0,size:30,textColor:0 x 00 c 200,bgAlpha:0.9"ここでfpsパネルのスタイルを設定します.パネルの位置を変更してxとyを設定したり、サイズを変更してsizeを設定したり、文字色textColorを変更したり、背景パネルの透明度bgAlphaを変更したりするなど、デフォルトの設定がサポートされています.
ページが開くとすぐにegretが実行されます.runEgret()、これらのパラメータは後で詳しく説明しますが、ergetの実行プロセスを理解しておきます.
EgretWeb.tsエントリスクリプト
ソースプロジェクトでrunEgretを検索すると、src/egret/native/EgretNativeにそれぞれ表示されます.tssrc/egret/player/EgretEntry.tssrc/egret/web/EgretWeb.tsで定義されます.これはegretの基本的な構造ですEgretEntry.TSはインタフェースを定義し、EgretNative.tsとEgretWeb.tsはそれぞれ原生プラットフォームとwebプラットフォームでの実現を定義する.まずweb部分の考え方に基づいて分析します.
1.環境パラメータの初期化
    let isRunning: boolean = false;

    /**
     * @private
     *       ,         Egret  
     */
    function runEgret(options?: runEgretOptions): void {
        if (isRunning) {
            return;
        }
        isRunning = true;
        if (!options) {
            options = {};
        }
        Html5Capatibility._audioType = options.audioType;
        Html5Capatibility.$init();
        //......
   }

まずrunEntry関数の前の行を見てみましょう.ここでは閉パッケージとisRunning、if文を利用してゲームの繰り返しを防ぐことができます.ここでのisRunningという変数は明らかにrunEntry関数でしか使用されないので、メンバーのプライベート属性として定義するのではなく、変数として定義されます.Html 5 Capatibilityは、html 5のサポート情報を初期化するために$init()メソッドを呼び出す静的クラスです.
public static $init(): void {
    let ua: string = navigator.userAgent.toLowerCase();
    Html5Capatibility.ua = ua;
    egret.Capabilities.$isMobile = (ua.indexOf('mobile') != -1 || ua.indexOf('android') != -1);
    //......
}

$init()メソッドを少し見てみましょう.ここでは、src/egret/system/Capabilitiesにあるグローバル静的クラスCapabilitiesも呼び出します.tsでは、主に現在動作しているデバイス(PC/IOS/Android)情報、プラットフォーム情報(web/native)、レンダリングモード、エンジンバージョン、クライアントサイズが格納される.Webプラットフォームの実行環境に関する各情報はCapabilitiesから得られ,HTML 5のインタフェースはHtml 5 Capatibilityから得られることが分かる.
2.レンダリングの設定
 // WebGL        
function runEgret(options?: runEgretOptions): void {
        if (options.renderMode == "webgl") {
            // WebGL       ,  PC       
            let antialias = options.antialias;
            WebGLRenderContext.antialias = !!antialias;
            // WebGLRenderContext.antialias = (typeof antialias == undefined) ? true : antialias;
        }
    sys.CanvasRenderBuffer = web.CanvasRenderBuffer;
    setRenderMode(options.renderMode);
    ......
}

ここには2つのテクニックがあります!転換するためにantialiasはfalse、true、undefinedの1つかもしれませんが、falseかtrueなら2つ!!役に立たないに相当し,undefinedであればfalseに変換される.

    /**
     *       。"auto","webgl","canvas"
     * @param renderMode
     */
    function setRenderMode(renderMode: string): void {
        //......
        if (renderMode == "webgl" && WebGLUtils.checkCanUseWebGL()) {
            sys.RenderBuffer = web.WebGLRenderBuffer;
            sys.systemRenderer = new WebGLRenderer();
            sys.canvasRenderer = new CanvasRenderer();
            sys.customHitTestBuffer = new WebGLRenderBuffer(3, 3);
            sys.canvasHitTestBuffer = new CanvasRenderBuffer(3, 3);
            Capabilities.$renderMode = "webgl";
        }
        else {
            sys.RenderBuffer = web.CanvasRenderBuffer;
            sys.systemRenderer = new CanvasRenderer();
            sys.canvasRenderer = sys.systemRenderer;
            sys.customHitTestBuffer = new CanvasRenderBuffer(3, 3);
            sys.canvasHitTestBuffer = sys.customHitTestBuffer;
            Capabilities.$renderMode = "canvas";
        }
        //......
    }

簡単にsetRenderModeの方法を見てみましょう.ユーザーがrenderModeをwebGLに設定し、ブラウザがwebGLをサポートする場合はwebGLを使用します.そうでなければcanvas、WebGLUtilsを使用します.checkCanUseWebGL()この方法はみんな自分で見てもいいですし、同じように2つ使いました!!のテクニックは、webGLの使用について皆さんはここを見て初めてWebGLを知ることができます.
3.解像度構成
function runEgret(options?: runEgretOptions): void {
        //......
        let canvasScaleFactor;
        if (options.canvasScaleFactor) {
            canvasScaleFactor = options.canvasScaleFactor;
        }
        else if(options.calculateCanvasScaleFactor) {
            canvasScaleFactor = options.calculateCanvasScaleFactor(sys.canvasHitTestBuffer.context);
        }
        else {
            //based on : https://github.com/jondavidjohn/hidpi-canvas-polyfill
            let context = sys.canvasHitTestBuffer.context;
            let backingStore = context.backingStorePixelRatio ||
                context.webkitBackingStorePixelRatio ||
                context.mozBackingStorePixelRatio ||
                context.msBackingStorePixelRatio ||
                context.oBackingStorePixelRatio ||
                context.backingStorePixelRatio || 1;
            canvasScaleFactor = (window.devicePixelRatio || 1) / backingStore;
        }
        sys.DisplayList.$canvasScaleFactor = canvasScaleFactor;
        //......
}

ユーザーがスケールを構成して使用する場合は、スケールを計算する方法を構成して呼び出されます.そうしないと、現在のブラウザでサポートされている最大精度のスケールが計算されます.
4.システムタイマーの実行
function runEgret(options?: runEgretOptions): void {
    //......
    let ticker = egret.ticker;
    startTicker(ticker);
    //......
}
        

egret.sys.$tickerはegret.SystemTickerクラスのオブジェクトの一例です.まずstartTickerメソッドを呼び出します.
function startTicker(ticker:egret.sys.SystemTicker):void {
    var requestAnimationFrame =
        window["requestAnimationFrame"] ||
        window["webkitRequestAnimationFrame"] ||
        window["mozRequestAnimationFrame"] ||
        window["oRequestAnimationFrame"] ||
        window["msRequestAnimationFrame"];
    if (!requestAnimationFrame) {
        requestAnimationFrame = function (callback) {
            return window.setTimeout(callback, 1000 / 60);
        };
    }
    requestAnimationFrame.call(window, onTick);
    function onTick():void {
        ticker.update();
        requestAnimationFrame.call(window, onTick)
    }
}

ここでは同様にブラウザにrequestAnimationFrameのAPIが存在するか否かを判読し、存在する場合はsettimoutメソッドを用いる、ここでonTickerは遅延再帰呼び出しを用い、一定時間毎にtickerを呼び出すことを実現する.update()メソッド.ここでcallメソッドを使用して、jsのthisのピットを避けるために呼び出されたメソッドオブジェクトがグローバルwindowオブジェクトであることを確認します.
5.スクリーンアダプタとプレーヤーの作成
function runEgret(options?: runEgretOptions): void {
    //......
    if (options.screenAdapter) {
            egret.sys.screenAdapter = options.screenAdapter;
        }
        else if (!egret.sys.screenAdapter) {
            egret.sys.screenAdapter = new egret.sys.DefaultScreenAdapter();
        }

        let list = document.querySelectorAll(".egret-player");
        let length = list.length;
        for (let i = 0; i < length; i++) {
            let container = list[i];
            let player = new WebPlayer(container, options);
            container["egret-player"] = player;
            //webgl       
            if (Capabilities.$renderMode == "webgl") {
                player.stage.dirtyRegionPolicy = DirtyRegionPolicy.OFF;
            }
        }
        if (Capabilities.$renderMode == "webgl") {
            egret.sys.DisplayList.prototype.setDirtyRegionPolicy = function () { };
        }

        window.addEventListener("resize", function () {
            if (isNaN(resizeTimer)) {
                resizeTimer = window.setTimeout(doResize, 300);
            }
        });
    //......
   
}
//......
    let resizeTimer: number = NaN;

    function doResize() {
        resizeTimer = NaN;

        egret.updateAllScreens();

        if (customContext) {
            customContext.onResize(context);
        }
    }

次にdocumentを使用します.QuerySelectorAll()メソッドは、「egret-player」を持つCSS classのDOMオブジェクトをすべて取得します.最初はindexでhtmlのbodyに見えるdivタグ.これらのDOMオブジェクトを巡回し、それぞれにegretを作成する.WebPlayerオブジェクトは、DOMの「egret-player」プロパティに割り当てられます(これはカスタムプロパティです).
ここでもう1つ注目すべき相手はresizeTimerであり,ブラウザサイズが変化するたびにまず1つの判断を行い,再描画タイマ(すなわちresizeTimerはNaN)が存在しない場合はタイマを起動し,300ミリ秒後にブラウザサイズを再描画し,resizeTimerをNaNに割り当ててこのタイマが閉じたことを示す.このようにするのは、PC側でブラウザサイズを変更するのは継続的な動作であり、つまりマウスが移動し続けてウィンドウサイズを変更し、300ミリ秒のタイマ遅延再描画を定義することは、過剰な再描画要求がリソースを占有することを防止するためであるからです.
小結
runEgretはHtml 5 CapatibilityとCapatibilitiesの2つの静的クラスを通じてプロジェクト実行の環境パラメータを初期化し、スクリーンアダプタegretを作成した.sys.screenAdapterは、異なる適合ポリシーに基づいて調整されます.次にwinodwオブジェクトのresizeイベントを傍受することによってクライアントサイズの変化(回転装置、ブラウザウィンドウサイズの変更などを含む)を傍受する.最も主要なことは、呼び出しがタイマーを無限に呼び出すegret.を作成することである.sys.$tickerのupdate()メソッドは、グローバルなデータ更新とビューレンダリングを行います.では、ゲームエンジン全体の大体の有効化プロセスはここで終わります.
上一篇:ergetソース分析(2):グローバルハッシュベースクラスとグローバル非同期関数オブジェクトインタフェース