CocosCreator ソースコードの解釈: エンジンの起動とメインループ

CocosCreator ソースコードの解釈: エンジンの起動とメインループ

序文

準備

皆さんは、こんなことを考えたことがあるでしょうか。ゲームの世界を車に例えると、この「車」はどうやって始動し、走り続けるのでしょうか。

タイトルの通り、この記事の内容は主に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 で定義されているwindow.boot()関数が呼び出されます。

💡 ネイティブ プラットフォームの場合、main.js ファイルは、 {項目目錄}build\jsb-link\frameworks\runtime-src\Classes\AppDelegate.cppファイルのapplicationDidFinishLaunching()関数で読み込まれます。 (補足を提供してくれたPlease Allow Me to Sleepに感謝します)

🧵 コードの縮小

スクリプト ファイル名の-min単語は、通常、このファイル内のコードが圧縮されていることを意味します。

コードを圧縮すると、コード ファイルが占めるスペースを節約し、ファイルの読み込みを高速化し、トラフィックの消費を削減できますが、コードの可読性が低下し、デバッグに役立たなくなります。

したがって、デバッグ モードをオンにすると、圧縮されていないコード ファイルが直接使用されるため、開発のデバッグやエラーの配置に便利です。

メイン.js

ウィンドウのブート()

main.js の内容もプラットフォームによって多少異なります。ここでは違いを無視し、重要な共通動作のみに焦点を当てます。

main.js ファイルの内容は基本的にwindow.boot()関数を定義します。

💡 ウェブ以外のプラットフォームでは、 window.boot()関数は定義の直後に呼び出されるため、main.js が開始点になります。

window.boot()関数には、次の主要な動作があります。

  1. onStartコールバック関数を定義します。主に起動シーンをロードするために使用されます。
  2. cc.assetManager.init(...) : AssetManager を初期化する
  3. cc.assetManager.loadScript(...) : srcディレクトリ内のプラグインスクリプトをロードします
  4. cc.assetManager.loadBundle(...) : プロジェクトにバンドルをロードします
  5. cc.game.run(...) : エンジンを始動する

この部分のコードは掲載しません。プロジェクトをビルドした後、main.js ファイルを確認してください。

cc.ゲーム

cc.gameオブジェクトは、 cc.Gameクラスのインスタンスですcc.gameにはメインのゲーム情報が含まれており、ゲームの実行を担当します。

簡単に言えば、 cc.gameオブジェクトはエンジンのライフサイクルを管理するモジュールです。起動、一時停止、再起動などの操作に必要です。

CCGame.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js

走る()

cc.game.run()関数は、エンジン構成とonStartコールバックを指定し、 cc.game.prepare()関数をトリガーします。

実行: 関数 (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

準備する()

cc.game.prepare()関数は主にプロジェクト コードをすばやくコンパイルし、プロジェクトがプレビューされるときに_prepareFinished()関数を呼び出します。

準備(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

クイック コンパイルの詳細については、プロジェクトをプレビューするときにブラウザーの開発者ツールを開き、[ソース] 列で__quick_compile_project__検索 (Ctrl + P) して__quick_compile_project__.jsファイルを見つけます。

_準備完了()

cc.game._prepareFinished()関数の主な機能は、エンジンの初期化、フレーム レート タイマーの設定、組み込みリソース (エフェクト リソースとマテリアル リソース) の初期化です。

組み込みリソースがロードされると、 cc.game._runMainLoop()が呼び出され、エンジンのメイン ループが開始されます。

_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

💡 _prepareFinished()で呼び出される_setAnimFrame()関数について言及することが重要です。

_setAnimFrame()

cc.game._setAnimFrame()さまざまなゲーム フレーム レートに内部的に適応します。

さらに、 window.requestAnimationFrame()インターフェイスは、さまざまなブラウザ環境との互換性のためにカプセル化されています。詳細については以下で説明します。

_setAnimFrame()のコードはここでは掲載しませんが、必要な場合は確認してください。

ポータル: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L564

_runMainLoop()

cc.game._runMainLoop()関数の名前は非常にシンプルで直接的です。これはmainLoop()関数を実行するために使用されます。

コードを見てみましょう:

_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

上記のコードから、 _runMainLoop()は主にwindow.requestAnimFrame()インターフェースを使用してmainLoop()関数のループ呼び出しを実装していることがわかります。

ウィンドウ.requestAnimFrame()

window.requestAnimFrame()は、前述の_setAnimFrame()内のwindow.requestAnimationFrame() () の互換性カプセル化です。

フロントエンドに詳しくない友人は、 window.requestAnimationFrame()とは何なのか、何に使われるのか、どのように動作するのか、といった疑問を持つかもしれません。

ウィンドウ.requestAnimationFrame()

簡単に言うと、 window.requestAnimationFrame()ブラウザから再描画を要求し、再描画の前に指定されたコールバック関数を呼び出すために使用されます。

window.requestAnimationFrame() 、コールバックをパラメータとして受け取り、一意の識別子として整数を返します。ブラウザは、次の再描画の前にこのコールバックを実行します。コールバックの実行時にパラメータが渡され、パラメータの値はperformance.now()によって返される値と等しくなります。

performance.now()の戻り値は、ブラウザ ウィンドウの実行時間、つまりウィンドウを開いてから現在の瞬間までの時間差として簡単に理解できます。

MDN ドキュメント: https://developer.mozilla.org/zh-CN/docs/Web/API/Performance/now

コールバック関数の実行回数は通常、ブラウザ画面の更新回数と一致します。つまり、リフレッシュ レートが 60 Hz のディスプレイの場合、ブラウザは 1 秒間にコールバック関数を 60 回実行します。

window.requestAnimationFrame()の説明はこれで終わりです。さらに詳しい情報を知りたい場合は、ご自身で検索してください。

MDN ドキュメント: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame

まとめ

エンジン始動のプロセスを絵で簡単にまとめてみました〜

メインループ

紆余曲折を経て、ついにエンジンの最も期待されていたメイン ループに到達しました。さっそく、続けましょう。

cc.ディレクター

cc.directorオブジェクトは、ディレクター クラスcc.Directorのインスタンスです。エンジンは主に、 cc.directorオブジェクトを通じてゲームの論理フローを管理します。

CCDirector.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCDirector.js

メインループ()

🍖 cc.director.mainLoop()関数は、エンジン内で最も重要なロジックの 1 つであり、多くの重要なコンテンツが含まれています。

それでは、 mainLoop()関数の内部を見てみましょう。

ここでは、関数内のコードの一部を選択的に削除し、コメントを追加しました。

メインループ: 関数(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つずつ分解してみましょう。

コンポーネントスケジューラ

cc.directorオブジェクトの_compScheduler属性は、 ComponentSchedulerクラスのインスタンスです。

ComponentSchedulerクラスについてあまり印象がない方も多いと思いますので、簡単に説明させていただきます。

ComponentSchedulerという名前を文字通り翻訳すると、「コンポーネント スケジューラ」になります。名前が示すように、このクラスはコンポーネントをスケジュールするために使用されます。

簡単に言えば、 ComponentSchedulerクラスは、ゲーム シーン内のすべてのコンポーネント ( cc.Component ) のライフ サイクルを集中的にスケジュール (管理) するために使用されます。

テキストだけでは十分直感的ではありませんが、以下の画像を見ると理解できると思います。

コンポーネントスケジューラ.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/component-scheduler.js

開始フェーズ

//新しく追加されたコンポーネント(有効)の開始関数を呼び出します。this._compScheduler.startPhase();

コンポーネントのstartコールバック関数は、コンポーネントが初めてアクティブ化される前、つまり最初のupdateが実行される前にトリガーされます。

startコールバックはコンポーネントの有効期間中に 1 回だけトリガーされますonLoadonEnableについても同様です。

onLoadonEnable NodeActivatorクラスのインスタンスによって管理されるだけです。

onLoadノードがアクティブ化されたときにトリガーされonEnableコンポーネントが有効化されたときにトリガーされます。

次のメイン ループmainLoop()までstartトリガーされません。

🥁 ノードアクティベーター

NodeActivatorクラスは主に、ノードとそのコンポーネントを有効化または無効化するために使用されます。

cc.directorオブジェクトにはインスタンス_nodeActivatorがあり、ゲーム内のすべてのノードの有効化と無効化はこれを介して操作する必要があります。

次のようにします: cc.director._nodeActivator.activateNode(this, value);

ノードアクティベーター.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/node-activator.js

更新フェーズ

//すべてのコンポーネントの更新関数を呼び出します (有効) this._compScheduler.updatePhase(deltaTime);

コンポーネントのupdate関数はフレームごとに 1 回トリガーされます。

遅い更新フェーズ

//すべてのコンポーネントのlateUpdate関数を呼び出します(有効)this._compScheduler.lateUpdatePhase(deltaTime);

updateとスケジューラcc.Schedulerが更新された後、コンポーネントのlateUpdate関数がトリガーされます。スケジューラの更新には、イージング、アニメーション、物理演算が含まれており、これについては以下で詳しく説明します。

パーティクルシステム

ちなみに、パーティクル システム コンポーネント ( cc.ParticleSystem ) は、 lateUpdateコールバック関数で更新されます。

CCParticleSystem.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/particle/CCParticleSystem.js

ヒント

updateおよびlateUpdateコールバックはフレームごとにトリガーされるため、注意して使用してください。 updateまたはlateUpdateにロジックが多すぎると、各フレームの実行時間 (つまりフレーム時間) が長くなり、フレーム レートが低下したり、ゲームが不安定になったりします。

📢 ただし、使用してはいけないというわけではありません。使用はしてもかまいませんが、乱用したり、すべてを入れたりしないでください。

スケジューラ

cc.directorオブジェクトの_scheduler属性は、 cc.Schedulerクラスのインスタンスです。

cc.Schedulerは、コールバック関数をトリガーするクラスです。

スケジューラ.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/Scheduler.js

💣次のコード行を実行した後に何が起こるかは、決して推測できません。

// スケジューラを更新します (cc.Scheduler クラスのインスタンス)
this._scheduler.update(this._deltaTime);

_scheduler.update()関数は、 cc.director.mainLoop()で更新を配布するために使用されます。スケジューラ ( cc.director._scheduler ) 内では、さまざまなシステム モジュールとコンポーネント タイマーの更新が、優先度に従って順番にトリガーされます。

システムモジュール

スケジューラの更新により、まず次のシステム モジュールの更新がトリガーされます。

  • アクションマネージャー
  • アニメーションマネージャー
  • 衝突マネージャ
  • 物理マネージャ
  • 物理3Dマネージャー
  • 入力マネージャー

上記のモジュールはすべてフレームごとに更新する必要があるため、 cc.director._scheduler.scheduleUpdate()を使用してスケジューラに登録されます。

InputManager除くすべてのモジュールの優先度はcc.Scheduler.PRIORITY_SYSTEMです。これはシステム優先度であり、最初にトリガーされます。

アクションマネージャー

ActionManagerはアクション マネージャーであり、ゲーム内のすべてのアクション、つまりイージング システムActionTween管理するために使用されます (実際、これらは本質的に同じものです)。

CCActionManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/actions/CCActionManager.js

アニメーションマネージャー

AnimationManagerは、ゲーム内のすべてのアニメーションを管理し、ノード上のAnimationコンポーネントを駆動してアニメーションを再生するアニメーション マネージャーです。

アニメーションマネージャ.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/animation/animation-manager.js

衝突マネージャ

CollisionManagerは衝突コンポーネント マネージャーであり、ノード間の衝突コンポーネントが衝突したかどうかを処理し、対応するコールバック関数を呼び出すために使用されます。

CCCollisionManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/collider/CCCollisionManager.js

物理マネージャ

PhysicsManagerは物理システム マネージャーであり、内部でBox2D 2D 物理エンジンとして使用し、それをカプセル化して、いくつかのよく使用されるインターフェイスを開きます。同時に、 PhysicsManagerは衝突情報の配布の管理も担当します。

CCPhysicsManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/physics/CCPhysicsManager.js

物理3Dマネージャー

Physics3DManagerは 3D 物理システム マネージャーです。Cocos Creator の 3D 物理エンジンにはCannon.jsBuiltinが含まれます。Physics3DManager Physics3DManagerそれらの統一された共通インターフェイスをカプセル化します。

物理マネージャ.ts: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/3d/physics/framework/physics-manager.ts

入力マネージャー

InputManager 、すべての入力イベントを管理するために使用される入力イベント マネージャーです。開発者が加速度計をアクティブに有効にすると、エンジンはInputManagerを介してcc.SystemEvent.EventType.DEVICEMOTIONイベントを定期的に送信します (デフォルトの間隔は 0.2 秒です)。

CCInputManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d\core\platform\CCInputManager.js

コンポーネントタイマー

皆さんの多くは、コンポーネントのschedule()およびscheduleOnce()インターフェースを使用したことがあると思います。これらは主に、関数を繰り返し実行したりスケジュールしたりするために使用されます。

実際、 cc.Componentschedule()インターフェースもcc.Schedulerクラスに依存しており、具体的にはcc.directorオブジェクト内の_schedulerインスタンスを使用します。

コンポーネントのschedule()インターフェースは、 cc.director._scheduler.schedule()インターフェースの外側に、コンポーネント自体をtargetとしてカプセル化レイヤーを追加します。このようにして、コンポーネント内のスケジュールされたタスクはコンポーネントのライフサイクルにバインドされ、スケジュールされたタスクもコンポーネントが破棄されると削除されます。

scheduleOnce()インターフェースは、コンポーネントのschedule()インターフェースの外側に別のカプセル化レイヤーを追加し、指定された時間後に 1 回だけ実行されるように固定されています。

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()の違いと使用方法についてまだよくわかっていない方が多いことに気づいたので、この機会に簡単に説明させてください。

setTimeout と setInterval

setTimeout()setInterval()どちらも、ブラウザーまたは Node.js などのランタイムによって提供されるインターフェースです。

setTimeout()インターフェイスは、タイマーの期限が切れた後に関数または指定されたコードを実行するタイマーを設定するために使用されます。 setInterval()インターフェイスは、各呼び出しの間に一定の時間遅延を設けて関数を呼び出したり、コード セグメントを繰り返し実行したりするために使用されます。

💡 もう一つのちょっとした知識:

ブラウザでのsetTimeout()およびsetInterval()の最小遅延 (間隔) は 4 ミリ秒です。

非アクティブ(バックグラウンド)タブの場合、最小遅延(間隔)は 1000 ミリ秒に延長されます。

🌰 例えば

現在のタブで 500 ミリ秒ごとにログを出力するタイマーを設定した場合、別のタブに切り替えると、タイマーは 1000 ミリ秒ごとにログを出力するようになります。

興味があれば、次のように自分で試してみることもできます。

間隔を設定する(() => {
    console.log(新しい日付().getTime());
}, 500);
//アナログ出力//フォアグラウンドのタブ// 1604373521000
//1604373521500
// 1604373522000
// 別のタブページに切り替えた後 // 1604373523000
// 1604373524000
// 1604373525000

違いと使い方

コンポーネントのタイマーは、エンジンのmainLoop()とコンポーネント自体に依存します。エンジンが一時停止されると、コンポーネントのタイマーも一時停止されます。コンポーネントまたはコンポーネントが配置されているノードが破棄されると、タイマーも無効になります。

setTimeout()setInterval()はどちらも現在のwindowオブジェクトに依存します。つまり、現在のブラウザ タブが閉じられない限り、 setTimeout()setInterval()引き続き実行されます。

コンポーネント内の関数の実行時間を計ったり、繰り返し実行したり、ノードを操作したりする必要がある場合は、コンポーネントのタイマーを使用できます。

💬 次のようなシナリオを想像してみましょう:

現在のシーンのスクリプトでsetInterval()を使用して、シーン内のノードを繰り返し移動します。シーンを切り替えると何が起こりますか?

タイマーがノードを移動するために再度コールバックを呼び出すと、タイマーの実行中にノードが前のシーンとともに破棄されているため、ターゲット ノードを見つけることができず、エラーが報告されます。

この場合、コンポーネントのタイマーを使用すると、コンポーネントが破棄されるとタイマーがクリアされるため、この問題は発生しません。

ゲームシーンに関係のない何かを実行する必要がある場合は、 setTimeout()またはsetInterval()の使用を検討できます。

🎃 もちろん、コンポーネントタイマーを使用できる場合は、コンポーネントタイマーを使用することをお勧めします〜

まとめ

Scheduler簡単にまとめた図を描いてみましょう。

要約する

これでエンジン起動プロセスとメインループの解釈は終了です。

最後に、総括として絵を描いてみましょう〜

上記は、CocosCreator ソースコードのエンジン起動とメインループの解釈の詳細内容です。CocosCreator ソースコードの解釈の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Unity3Dはカメラレンズの動きを実現し、角度を制限する
  • CocosCreatorで複数のタイマーを使用する方法の詳細な説明
  • CocosCreator 学習モジュールスクリプト
  • CocosCreator で物理エンジン ジョイントを使用する方法
  • CocosCreatorでJSZip圧縮を使用する方法
  • CocosCreator 入門チュートリアル: TS で初めてのゲームを作る
  • CocosCreator 一般的なフレームワーク設計リソース管理
  • CocosCreatorでリストを作成する方法
  • CocosCreator で http と WebSocket を使用する方法
  • CocosCreator の新しいリソース管理システムの分析
  • CocosCreator でカメラトラッキングに cc.follow を使用する方法

<<:  mysql5.7.19 解凍版の詳細なインストール チュートリアル (純粋なクラックされた中国語版 SQLYog を使用)

>>:  MySQL zip アーカイブ バージョン (5.7.19) の詳細なインストール チュートリアル

推薦する

Linux (Ubuntu) での MySQL 5.7.17 のインストールと設定のチュートリアル

序文以前、MySQL 5.6 をインストールしました。3 か月後、開発者から MySQL で JSO...

MySQL の count()、group by、order by の詳細な説明

最近、IM を実行するときに、これらの 3 つのキーワードを同時に使用したときに問題が発生しました。...

クリック範囲を拡大する入力チェックボックスを実装する方法

XML/HTML コードコンテンツをクリップボードにコピー< div style = &quo...

Zabbix による VMware Exsi ホストの監視のグラフィカルな手順

1. 仮想化 vcenter に入り、ブラウザでログインし (クライアントは設定する場所を見つけませ...

MySQL ページングクエリ最適化テクニック

ページング クエリを使用するアプリケーションでは、LIMIT と OFFSET を含むクエリが非常に...

vue-cli 3 で vue-bootstrap-datetimepicker 日付プラグインを使用する方法

需要背景最近、Vue を使用してフロントエンド エンジニアリング システムと組み合わせ、以前のデモを...

CSS3の3D効果を使って立方体を作成する

CSS3 の 3D 効果を使用して立方体を作成する方法を学ぶと、3D シーンの回転と変位のプロパティ...

...

Div CSS 命名標準 CSS クラスの命名規則 (SEO 標準に準拠)

検索エンジン最適化 (SEO) では実行すべきタスクが多数ありますが、その中でもコードの最適化は重要...

Dockerコンテナとホスト間のデータ相互作用の概要

序文実稼働環境で Docker を使用する場合、多くの場合、データを複数のコンテナ間で永続化または共...

HTML におけるブロックコメントの使用に関する詳細な紹介

HTML の一般的なコメント: <!--XXXXXXXX--> (XXXXXXXX はコ...

Explainキーワードに基づいてMySQLインデックス機能を最適化する方法

EXPLAIN は、MySQL がインデックスを使用して選択ステートメントを処理し、テーブルを結合す...

Vue はグラフィック検証コードログインを実装します

この記事では、グラフィック認証コードログインを実装するためのVueの具体的なコードを参考までに紹介し...

Docker を使用して Microsoft Sql Server を展開するための詳細な手順

目次1 背景2 コンテナを作成する3 SAパスワードを変更する4 mssql のリンク5. コンテナ...

Videojs+swiper が Taobao の商品詳細カルーセルを実現

この記事では、Taobao商品詳細のカルーセルを実現するためのvideojs+swiperの具体的な...