VorwortVorbereitungIch frage mich, ob Sie schon einmal darüber nachgedacht haben: Wenn man die Spielwelt mit einem Auto vergleicht, wie startet dieses „Auto“ dann und wie bleibt es am Laufen? Wie der Titel schon sagt, geht es in diesem Artikel hauptsächlich um den Startvorgang und die Hauptschleife der Cocos Creator-Engine. Die Hauptschleife umfasst außerdem: Komponentenlebenszyklus und Timer, Easing-System, Animationssystem und Physiksystem usw. In diesem Artikel wird die Beziehung zwischen der Hauptschleife und jedem Modul auf Makroebene erläutert. Außerdem werden die einzelnen Module kurz vorgestellt, auf die spezifische Implementierung des Moduls wird jedoch nicht eingegangen. Denn ich fürchte, wenn ich jedes Modul „anfasse“, werde ich diesen Artikel nicht fertigstellen können. Gehen!Ich hoffe, dass Sie nach dem Lesen dieses Artikels ein besseres Verständnis der Cocos Creator-Engine haben. Gleichzeitig hoffe ich auch, dass dieser Artikel die Rolle eines „Meisters spielen kann, der Sie durch die Tür führt“. Lassen Sie uns gemeinsam hart daran arbeiten, zu üben ~ Darüber hinaus sollte die Reihe „Source Code Interpretation“ weiterhin aktualisiert werden. Wenn Sie möchten, dass Pipi ein Modul der Interpretations-Engine interpretiert, können Sie mir auch gerne eine Nachricht hinterlassen, ich werde es mir überlegen, hahaha~ Dieser Artikel verwendet Cocos Creator 2.4.3 als Referenz. TextStarten Sie den ProzessHauptseite Für die Webplattform ist die Datei index.html der absolute Ausgangspunkt. In der Standarddatei index.html wird das Layout der Startseite des Spiels definiert, die Datei main.js wird geladen und es gibt auch einen Codeabschnitt, der sofort ausgeführt wird. Hier ist ein Teil des Schlüsselcodes in der Datei: // Laden Sie das Engine-Skript loadScript(debug ? 'cocos2d-js.js' : 'cocos2d-js-min.ec334.js', function () { // Ist das Physiksystem aktiviert? wenn (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) { // Laden Sie das Physiksystemskript und starten Sie die Engine loadScript(debug ? 'physics.js' : 'physics-min.js', window.boot); } anders { // Starten Sie die Engine window.boot(); } }); Der obige Code wird hauptsächlich zum Laden des Engine-Skripts und des physischen Systemskripts verwendet. Nachdem das Skript geladen wurde, wird die in main.js definierte Funktion 💡 Für native Plattformen wird die Datei main.js in 🧵 Code-Minimierung Das Wort Durch das Komprimieren von Code können Sie den von Codedateien belegten Speicherplatz einsparen, das Laden von Dateien beschleunigen und den Datenverkehr reduzieren. Allerdings wird der Code dadurch auch schlechter lesbar und ist für die Fehlerbehebung nicht förderlich. Daher wird nach dem Aktivieren des Debug-Modus die unkomprimierte Codedatei direkt verwendet, was für das Debuggen während der Entwicklung und die Fehlerlokalisierung praktisch ist. Haupt-JS window.boot() Es gibt auch einige Unterschiede im Inhalt von main.js für verschiedene Plattformen. Hier ignorieren wir die Unterschiede und konzentrieren uns nur auf die wichtigsten gemeinsamen Verhaltensweisen. Der Inhalt der Datei main.js definiert im Wesentlichen 💡 Für Nicht-Web-Plattformen wird die Funktion
Ich werde den Code für diesen Teil nicht veröffentlichen. Sie können sich die Datei main.js ansehen, nachdem Sie Ihr Projekt erstellt haben. cc.spiel Das Einfach ausgedrückt ist das CCGame.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js laufen() ausführen: Funktion (Konfiguration, beim Start) { //Engine-Konfiguration angeben this._initConfig(config); dies.onStart = beimStart; dies.vorbereiten(spiel.onStart && spiel.onStart.binden(spiel)); } Portal: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L491 vorbereiten() vorbereiten(cb) { // Überspringen, wenn bereits vorbereitet if (this._prepared) { wenn (cb) cb(); zurückkehren; } // Vorschau des Projektcodes laden this._loadPreviewScript(() => { dies._prepareFinished(cb); }); } Portal: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L472 Ausführliche Informationen zur Schnellkompilierung erhalten Sie, wenn Sie bei der Projektvorschau die Entwicklertools des Browsers öffnen und in der Spalte „Quellen“ _prepareFinished() Die Hauptfunktionen Wenn die integrierten Ressourcen geladen sind, wird _prepareFinished(cb) { // Initialisiere die Engine this._initEngine(); // Stellen Sie den Framerate-Timer ein this._setAnimFrame(); // Integrierte Ressourcen initialisieren (integrierte Effekt- und Materialressourcen laden) cc.assetManager.builtins.init(() => { // Drucke die Engine-Version auf der Konsole aus console.log('Cocos Creator v' + cc.ENGINE_VERSION); dies._vorbereitet = wahr; // MainLoop starten dies._runMainLoop(); // Das Ereignis „game_inited“ ausgeben (d. h. die Engine wurde initialisiert) dies.emit(dieses.EVENT_GAME_INITED); // Rufen Sie die in main.js definierte Funktion onStart auf, wenn (cb) cb(); }); } Portal: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L387 💡 Es ist wichtig, die in _setAnimFrame() Darüber hinaus ist Ich werde den Code von Portal: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L564 _runMainLoop() Der Name Schauen wir uns den Code an: _runMainLoop: Funktion () { wenn (CC_EDITOR) zurückgeben; wenn (!this._prepared) zurückgeben; // Lokale Variablen definieren var self = this, callback, config = self.config, Direktor = cc.Direktor, überspringen = wahr, FrameRate = config.frameRate; // Leistungsstatistiken anzeigen oder ausblenden debug.setDisplayStats(config.showFPS); // Frame-Callback setzen callback = function (now) { wenn (!self._paused) { // Schleifenaufruf-Rückruf self._intervalId = window.requestAnimFrame(callback); wenn (!CC_JSB && !CC_RUNTIME && frameRate === 30) { wenn (überspringen = !überspringen) return; } //mainLoop aufrufen director.mainLoop(jetzt); } }; // Startet die Rückrufschleife im nächsten Frame self._intervalId = window.requestAnimFrame(callback); self._paused = falsch; } Portal: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCGame.js#L612 Aus dem obigen Code können wir erkennen, dass Fenster.requestAnimFrame() Freunde, die mit dem Front-End nicht vertraut sind, haben möglicherweise Fragen: Was ist window.requestAnimationFrame() Einfach ausgedrückt wird Der Rückgabewert von MDN-Dokumentation: https://developer.mozilla.org/zh-CN/docs/Web/API/Performance/now Die Anzahl der Ausführungen der Rückruffunktion entspricht normalerweise der Anzahl der Bildschirmaktualisierungen des Browsers. Dies bedeutet, dass der Browser bei einer Anzeige mit einer Aktualisierungsrate von 60 Hz die Rückruffunktion 60 Mal pro Sekunde ausführt. Dies ist das Ende der Beschreibung von MDN-Dokumentation: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame Zusammenfassung Zeichnen Sie ein Bild, um eine kurze Zusammenfassung des Motorstartvorgangs zu erstellen ~ HauptschleifeNach einigen Drehungen und Wendungen kamen wir endlich zur mit Spannung erwarteten Hauptschleife des Motors. Und nun ohne weitere Umschweife weiter! cc.Direktor CCDirector.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCDirector.js Hauptschleife () 🍖 Sehen wir uns nun Hier habe ich selektiv einen Teil des Codes in der Funktion entfernt und einige Kommentare hinzugefügt: Hauptschleife: Funktion (jetzt) { //Berechnen Sie die „globale“ Deltazeit (DeltaTime) // Das heißt, das Zeitintervall seit dem letzten Aufruf von mainLoop this.calculateDeltaTime(now); // Aktualisieren, wenn das Spiel nicht pausiert ist if (!this._paused) { //Ereignis „director_before_update“ ausgeben this.emit(cc.Director.EVENT_BEFORE_UPDATE); //Rufen Sie die Startfunktion der neu hinzugefügten Komponente auf (aktiviert) this._compScheduler.startPhase(); //Rufen Sie die Update-Funktion aller Komponenten auf (aktiviert) this._compScheduler.updatePhase(this._deltaTime); // Aktualisiere den Scheduler (cc.Scheduler) dies._scheduler.update(diese._deltaTime); //Rufen Sie die LateUpdate-Funktion aller Komponenten auf (aktiviert) this._compScheduler.lateUpdatePhase(this._deltaTime); //Ereignis „director_after_update“ ausgeben this.emit(cc.Director.EVENT_AFTER_UPDATE); // Zerstöre die zuletzt entfernte Entität (Knoten) Obj._deferredDestroy(); } //Ereignis „director_before_draw“ ausgeben this.emit(cc.Director.EVENT_BEFORE_DRAW); // Rendere die Spielszenerenderer.render(this._scene, this._deltaTime); //Ereignis „director_after_draw“ ausgeben this.emit(cc.Director.EVENT_AFTER_DRAW); // Aktualisiere den Ereignis-Listener des Ereignis-Managers (cc.eventManager ist veraltet) eventManager.frameUpdateListeners(); // Akkumuliere die Gesamtzahl der Frames des Spiels this._totalFrames++; } Portal: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/CCDirector.js#L843 Als Nächstes wollen wir die wichtigsten Punkte in der Hauptschleife nacheinander aufschlüsseln. Komponentenplaner Die meisten von Ihnen haben wahrscheinlich keine Vorstellung von Die wörtliche Übersetzung des Namens Einfach ausgedrückt wird die Klasse Der Text ist nicht intuitiv genug. Sie werden ihn wahrscheinlich verstehen, wenn Sie sich das folgende Bild ansehen: component-scheduler.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/component-scheduler.js startPhase //Rufen Sie die Startfunktion der neu hinzugefügten Komponente auf (aktiviert) this._compScheduler.startPhase(); Die Es ist nur so, dass 🥁 NodeActivator So: node-activator.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/node-activator.js updatePhase //Rufen Sie die Update-Funktion aller Komponenten auf (aktiviert) this._compScheduler.updatePhase(deltaTime); Die späteUpdatePhase //Rufen Sie die LateUpdate-Funktion aller Komponenten auf (aktiviert) this._compScheduler.lateUpdatePhase(deltaTime); Die Partikelsystem Übrigens wird die Partikelsystemkomponente ( CCParticleSystem.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/particle/CCParticleSystem.js Tipps Bitte verwenden Sie 📢 Bitte beachten Sie, dass dies nicht bedeutet, dass Sie es nicht verwenden dürfen. Sie können es trotzdem verwenden, aber missbrauchen Sie es nicht und stecken Sie nicht alles hinein~ Terminplaner Das Scheduler.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/Scheduler.js 💣Sie werden nie erraten, was passiert, nachdem die folgende Codezeile ausgeführt wurde. // Aktualisieren Sie den Scheduler (Instanz der Klasse cc.Scheduler) dies._scheduler.update(diese._deltaTime); Systemmodul Die Aktualisierung des Schedulers löst zunächst die Aktualisierung der folgenden Systemmodule aus:
Alle oben genannten Module werden mit Die Priorität aller Module außer AktionsManager CCActionManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/actions/CCActionManager.js AnimationManager animation-manager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/animation/animation-manager.js KollisionsManager CCCollisionManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/collider/CCCollisionManager.js PhysikManager CCPhysicsManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/physics/CCPhysicsManager.js Physik3DManager physics-manager.ts: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/3d/physics/framework/physics-manager.ts EingabeManager CCInputManager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d\core\platform\CCInputManager.js Komponenten-Timer Ich glaube, die meisten von Ihnen haben Tatsächlich basiert CCComponent.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/components/CCComponent.js [Dokumentation] Verwenden des Timers: http://docs.cocos.com/creator/manual/zh/scripting/scheduler.html Mir ist auch aufgefallen, dass vielen von Ihnen der Unterschied und die Verwendung zwischen Komponenten-Timern und setTimeout und setIntervall Sowohl Mit der Schnittstelle 💡 Noch eine kleine Erkenntnis: Die minimale Verzögerung (Intervall) für Handelt es sich um einen inaktiven (Hintergrund-)Tab, wird die Mindestverzögerung (Intervall) auf 1000ms verlängert. 🌰 Zum Beispiel Wenn ich einen Timer so einstelle, dass alle 500 ms auf der aktuellen Registerkarte ein Protokoll ausgegeben wird, wird beim Wechsel zu einer anderen Registerkarte der Timer so eingestellt, dass alle 1000 ms ein Protokoll ausgegeben wird. Wenn Sie interessiert sind, können Sie es hier selbst ausprobieren: setzeIntervall(() => { Konsole.log(neues Datum().getTime()); }, 500); //Analogausgang//Tab im Vordergrund// 1604373521000 //1604373521500 // 1604373522000 // Nach dem Wechsel auf eine andere Registerkarte // 1604373523000 // 1604373524000 // 1604373525000 Unterschiede und Verwendung Der Timer der Komponente hängt von der Sowohl Wenn Sie eine Funktion zeitlich festlegen oder wiederholt ausführen oder einen Knoten innerhalb einer Komponente bedienen müssen, können Sie den Timer der Komponente verwenden. 💬 Stellen wir uns ein Szenario vor: Verwenden Sie Wenn der Timer den Rückruf erneut aufruft, um zu versuchen, den Knoten zu verschieben, kann er den Zielknoten nicht finden und einen Fehler melden, da der Knoten zusammen mit der vorherigen Szene zerstört wurde, während der Timer noch ausgeführt wird. In diesem Fall tritt dieses Problem bei Verwendung des Timers der Komponente nicht auf, da der Timer gelöscht wird, wenn die Komponente zerstört wird. Wenn wir etwas ausführen müssen, das nicht mit der Spielszene zusammenhängt, können wir die Verwendung von 🎃 Wenn Sie einen Komponenten-Timer verwenden können, ist es natürlich besser, den Komponenten-Timer zu verwenden ~ Zusammenfassung Zeichnen wir dennoch ein Bild, um ZusammenfassenDamit ist die Interpretation des Motorstartvorgangs und der Hauptschleife beendet. Lassen Sie uns zum Schluss ein Bild zeichnen, um eine abschließende Zusammenfassung zu erhalten ~ Oben finden Sie ausführliche Informationen zur Interpretation des Engine-Starts und der Hauptschleife des CocosCreator-Quellcodes. Weitere Informationen zur Interpretation des CocosCreator-Quellcodes finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
>>: Detailliertes Installationstutorial für die MySQL-Zip-Archivversion (5.7.19)
Bei unserer täglichen Arbeit führen wir manchmal ...
So installieren und konfigurieren Sie mysql-5.7.5...
Redis verwendet das Apline-Image (Alps) von Redis...
Sowohl die Optionen „Nur lesen“ als auch „Deaktivi...
Verwenden Sie einfach CSS, um alle Effekte von Ec...
Vue $http - domänenübergreifendes Abrufen und Sen...
Inhaltsverzeichnis 1. Deinstallieren Sie den Orig...
Wenn wir eine neue CSS-Funktion verwenden möchten...
Inhaltsverzeichnis So funktioniert es Betriebsabl...
Ein einfacher Rechner, der als Referenz in das We...
Dieser Artikel bezieht sich auf die Arbeit des 51...
Einführung Das Modul, das die Anzahl gleichzeitig...
BFC BFC: Blockformatierungskontext BFC-Layoutrege...
Inhaltsverzeichnis Schreiben Sie vor Geschäftscod...
Inhaltsverzeichnis 1. Beispiel: Hiermit können Da...