序文準備皆さんは、こんなことを考えたことがあるでしょうか。ゲームの世界を車に例えると、この「車」はどうやって始動し、走り続けるのでしょうか。 タイトルの通り、この記事の内容は主にCocos Creatorエンジンの起動プロセスとメインループについてです。 メイン ループには、コンポーネントのライフ サイクルとタイマー、イージング システム、アニメーション システム、物理システムなども含まれます。 この記事では、メインループと各モジュールの関係をマクロレベルで説明します。また、各モジュールについても簡単に紹介しますが、モジュールの具体的な実装については説明しません。 すべてのモジュールに「触れる」と、この記事を終えることができなくなるのではないかと心配だからです。 行く!この記事を読んで、Cocos Creator エンジンについてより深く理解していただければ幸いです。 同時に、この記事が「あなたを導く師匠」の役割を果たすことを願っています。一緒に頑張って実践しましょう〜 また、「ソースコード解釈」シリーズは引き続き更新されます(はずです)。Pipiに解釈エンジンのモジュールを解釈してもらいたい場合は、メッセージを残して私に知らせてください。検討します(笑) この記事では、Cocos Creator 2.4.3 をリファレンスとして使用します。 文章プロセスを開始するインデックス.html Web プラットフォームの場合、index.html ファイルが絶対的な出発点となります。 デフォルトの index.html ファイルでは、ゲームの起動ページのレイアウトが定義され、main.js ファイルが読み込まれ、すぐに実行されるコードも含まれています。 以下はファイル内のキーコードの一部です。 // エンジンスクリプトをロードする loadScript(debug ? 'cocos2d-js.js' : 'cocos2d-js-min.ec334.js', function () { // 物理システムは有効になっていますか? (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) の場合 { // 物理システム スクリプトをロードし、エンジンを起動します。loadScript(debug ? 'physics.js' : 'physics-min.js', window.boot); } それ以外 { // エンジンを起動します window.boot(); } }); 上記のコードは主にエンジン スクリプトと物理システム スクリプトをロードするために使用されます。スクリプトがロードされた後、main.js で定義されている 💡 ネイティブ プラットフォームの場合、main.js ファイルは、 🧵 コードの縮小 スクリプト ファイル名の コードを圧縮すると、コード ファイルが占めるスペースを節約し、ファイルの読み込みを高速化し、トラフィックの消費を削減できますが、コードの可読性が低下し、デバッグに役立たなくなります。 したがって、デバッグ モードをオンにすると、圧縮されていないコード ファイルが直接使用されるため、開発のデバッグやエラーの配置に便利です。 メイン.js ウィンドウのブート() main.js の内容もプラットフォームによって多少異なります。ここでは違いを無視し、重要な共通動作のみに焦点を当てます。 main.js ファイルの内容は基本的に 💡 ウェブ以外のプラットフォームでは、
この部分のコードは掲載しません。プロジェクトをビルドした後、main.js ファイルを確認してください。 cc.ゲーム
簡単に言えば、 CCGame.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js 走る() 実行: 関数 (config, onStart) { //エンジン構成を指定します this._initConfig(config); onStart は、次のようになります。 これを準備します(game.onStart && game.onStart.bind(game)); } ポータル: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L491 準備する() 準備(cb) { // すでに準備されている場合はスキップします if (this._prepared) { cb() の場合; 戻る; } // プレビュープロジェクトコードを読み込む this._loadPreviewScript(() => { this._prepareFinished(cb); }); } ポータル: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L472 クイック コンパイルの詳細については、プロジェクトをプレビューするときにブラウザーの開発者ツールを開き、[ソース] 列で _準備完了() 組み込みリソースがロードされると、 _prepareFinished(cb) { // エンジンを初期化します this._initEngine(); // フレームレートタイマーを設定します this._setAnimFrame(); // 組み込みリソースを初期化します(組み込みエフェクトとマテリアルリソースをロードします) cc.assetManager.builtins.init(() => { // エンジンのバージョンをコンソールに出力します。 console.log('Cocos Creator v' + cc.ENGINE_VERSION); this._prepared = true; // メインループを開始 this._runMainLoop(); // 'game_inited' イベントを発行します (つまり、エンジンが初期化されました) this.emit(this.EVENT_GAME_INITED); // main.js で定義された onStart 関数を呼び出します。if (cb) cb(); }); } ポータル: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L387 💡 _setAnimFrame() さらに、 ポータル: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L564 _runMainLoop() コードを見てみましょう: _runMainLoop: 関数 () { (CC_EDITOR) の場合、戻り値: if (!this._prepared) 戻り値: // ローカル変数を定義する var self = this, callback, config = self.config, ディレクター = cc.director、 スキップ = true、フレームレート = config.frameRate; // パフォーマンス統計を表示または非表示にする debug.setDisplayStats(config.showFPS); // フレームコールバックを設定する callback = function (now) { (!self._paused)の場合{ // ループ呼び出しコールバック self._intervalId = window.requestAnimFrame(callback); if (!CC_JSB && !CC_RUNTIME && フレームレート === 30) { skip = !skipの場合、戻り値: } //mainLoopを呼び出す director.mainLoop(今); } }; // 次のフレームでループ コールバックを開始します。self._intervalId = window.requestAnimFrame(callback); self._paused = false; } ポータル: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L612 上記のコードから、 ウィンドウ.requestAnimFrame() フロントエンドに詳しくない友人は、 ウィンドウ.requestAnimationFrame() 簡単に言うと、 MDN ドキュメント: https://developer.mozilla.org/zh-CN/docs/Web/API/Performance/now コールバック関数の実行回数は通常、ブラウザ画面の更新回数と一致します。つまり、リフレッシュ レートが 60 Hz のディスプレイの場合、ブラウザは 1 秒間にコールバック関数を 60 回実行します。 MDN ドキュメント: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame まとめ エンジン始動のプロセスを絵で簡単にまとめてみました〜 メインループ紆余曲折を経て、ついにエンジンの最も期待されていたメイン ループに到達しました。さっそく、続けましょう。 cc.ディレクター
CCDirector.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCDirector.js メインループ() 🍖 それでは、 ここでは、関数内のコードの一部を選択的に削除し、コメントを追加しました。 メインループ: 関数(now) { // 「グローバル」デルタ時間 (DeltaTime) を計算します // つまり、mainLoop への最後の呼び出しからの時間間隔 this.calculateDeltaTime(now); // ゲームが一時停止されていない場合は更新します if (!this._paused) { // 'director_before_update' イベントを発行します。this.emit(cc.Director.EVENT_BEFORE_UPDATE); //新しく追加されたコンポーネント(有効)の開始関数を呼び出します。this._compScheduler.startPhase(); //すべてのコンポーネントの更新関数を呼び出します (有効) this._compScheduler.updatePhase(this._deltaTime); // スケジューラを更新する (cc.Scheduler) this._scheduler.update(this._deltaTime); //すべてのコンポーネントのlateUpdate関数を呼び出します(有効)this._compScheduler.lateUpdatePhase(this._deltaTime); // 'director_after_update' イベントを発行します。this.emit(cc.Director.EVENT_AFTER_UPDATE); // 最後に削除されたエンティティ(ノード)を破棄します オブジェクトを破棄します。 } // 'director_before_draw' イベントを発行します。this.emit(cc.Director.EVENT_BEFORE_DRAW); // ゲームをレンダリングします scenerenderer.render(this._scene, this._deltaTime); // 'director_after_draw' イベントを発行します。this.emit(cc.Director.EVENT_AFTER_DRAW); // イベント マネージャーのイベント リスナーを更新します (cc.eventManager は非推奨になりました) イベントマネージャのフレーム更新リスナー(); // ゲームの合計フレーム数を累積します this._totalFrames++; } ポータル: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCDirector.js#L843 次に、メインループの重要なポイントを1つずつ分解してみましょう。 コンポーネントスケジューラ
簡単に言えば、 テキストだけでは十分直感的ではありませんが、以下の画像を見ると理解できると思います。 コンポーネントスケジューラ.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/component-scheduler.js 開始フェーズ //新しく追加されたコンポーネント(有効)の開始関数を呼び出します。this._compScheduler.startPhase(); コンポーネントの 次のメイン ループ 🥁 ノードアクティベーター
次のようにします: ノードアクティベーター.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/node-activator.js 更新フェーズ //すべてのコンポーネントの更新関数を呼び出します (有効) this._compScheduler.updatePhase(deltaTime); コンポーネントの 遅い更新フェーズ //すべてのコンポーネントのlateUpdate関数を呼び出します(有効)this._compScheduler.lateUpdatePhase(deltaTime); パーティクルシステム ちなみに、パーティクル システム コンポーネント ( CCParticleSystem.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/particle/CCParticleSystem.js ヒント
📢 ただし、使用してはいけないというわけではありません。使用はしてもかまいませんが、乱用したり、すべてを入れたりしないでください。 スケジューラ
スケジューラ.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/Scheduler.js 💣次のコード行を実行した後に何が起こるかは、決して推測できません。 // スケジューラを更新します (cc.Scheduler クラスのインスタンス) this._scheduler.update(this._deltaTime); システムモジュール スケジューラの更新により、まず次のシステム モジュールの更新がトリガーされます。
上記のモジュールはすべてフレームごとに更新する必要があるため、 アクションマネージャー
CCActionManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/actions/CCActionManager.js アニメーションマネージャー
アニメーションマネージャ.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/animation/animation-manager.js 衝突マネージャ
CCCollisionManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/collider/CCCollisionManager.js 物理マネージャ
CCPhysicsManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/physics/CCPhysicsManager.js 物理3Dマネージャー
物理マネージャ.ts: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/3d/physics/framework/physics-manager.ts 入力マネージャー
CCInputManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d\core\platform\CCInputManager.js コンポーネントタイマー 皆さんの多くは、コンポーネントの 実際、 コンポーネントの CCComponent.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/components/CCComponent.js [ドキュメント] タイマーの使用: http://docs.cocos.com/creator/manual/zh/scripting/scheduler.html また、コンポーネントタイマーと setTimeout と setInterval 💡 もう一つのちょっとした知識: ブラウザでの 非アクティブ(バックグラウンド)タブの場合、最小遅延(間隔)は 1000 ミリ秒に延長されます。 🌰 例えば 現在のタブで 500 ミリ秒ごとにログを出力するタイマーを設定した場合、別のタブに切り替えると、タイマーは 1000 ミリ秒ごとにログを出力するようになります。 興味があれば、次のように自分で試してみることもできます。 間隔を設定する(() => { console.log(新しい日付().getTime()); }, 500); //アナログ出力//フォアグラウンドのタブ// 1604373521000 //1604373521500 // 1604373522000 // 別のタブページに切り替えた後 // 1604373523000 // 1604373524000 // 1604373525000 違いと使い方 コンポーネントのタイマーは、エンジンの コンポーネント内の関数の実行時間を計ったり、繰り返し実行したり、ノードを操作したりする必要がある場合は、コンポーネントのタイマーを使用できます。 💬 次のようなシナリオを想像してみましょう: 現在のシーンのスクリプトで タイマーがノードを移動するために再度コールバックを呼び出すと、タイマーの実行中にノードが前のシーンとともに破棄されているため、ターゲット ノードを見つけることができず、エラーが報告されます。 この場合、コンポーネントのタイマーを使用すると、コンポーネントが破棄されるとタイマーがクリアされるため、この問題は発生しません。 ゲームシーンに関係のない何かを実行する必要がある場合は、 🎃 もちろん、コンポーネントタイマーを使用できる場合は、コンポーネントタイマーを使用することをお勧めします〜 まとめ
要約するこれでエンジン起動プロセスとメインループの解釈は終了です。 最後に、総括として絵を描いてみましょう〜 上記は、CocosCreator ソースコードのエンジン起動とメインループの解釈の詳細内容です。CocosCreator ソースコードの解釈の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: mysql5.7.19 解凍版の詳細なインストール チュートリアル (純粋なクラックされた中国語版 SQLYog を使用)
>>: MySQL zip アーカイブ バージョン (5.7.19) の詳細なインストール チュートリアル
序文以前、MySQL 5.6 をインストールしました。3 か月後、開発者から MySQL で JSO...
最近、IM を実行するときに、これらの 3 つのキーワードを同時に使用したときに問題が発生しました。...
XML/HTML コードコンテンツをクリップボードにコピー< div style = &quo...
1. 仮想化 vcenter に入り、ブラウザでログインし (クライアントは設定する場所を見つけませ...
ページング クエリを使用するアプリケーションでは、LIMIT と OFFSET を含むクエリが非常に...
需要背景最近、Vue を使用してフロントエンド エンジニアリング システムと組み合わせ、以前のデモを...
CSS3 の 3D 効果を使用して立方体を作成する方法を学ぶと、3D シーンの回転と変位のプロパティ...
検索エンジン最適化 (SEO) では実行すべきタスクが多数ありますが、その中でもコードの最適化は重要...
序文実稼働環境で Docker を使用する場合、多くの場合、データを複数のコンテナ間で永続化または共...
HTML の一般的なコメント: <!--XXXXXXXX--> (XXXXXXXX はコ...
EXPLAIN は、MySQL がインデックスを使用して選択ステートメントを処理し、テーブルを結合す...
この記事では、グラフィック認証コードログインを実装するためのVueの具体的なコードを参考までに紹介し...
目次1 背景2 コンテナを作成する3 SAパスワードを変更する4 mssql のリンク5. コンテナ...
この記事では、Taobao商品詳細のカルーセルを実現するためのvideojs+swiperの具体的な...