Interpretation des CocosCreator-Quellcodes: Engine-Start und Hauptschleife

Interpretation des CocosCreator-Quellcodes: Engine-Start und Hauptschleife

Vorwort

Vorbereitung

Ich 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.

Text

Starten Sie den Prozess

Hauptseite

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 window.boot() aufgerufen.

💡 Für native Plattformen wird die Datei main.js in applicationDidFinishLaunching() {項目目錄}build\jsb-link\frameworks\runtime-src\Classes\AppDelegate.cpp geladen. (Danke an Please Allow Me to Sleep für die Ergänzung)

🧵 Code-Minimierung

Das Wort -min im Skriptdateinamen bedeutet im Allgemeinen, dass der Code in dieser Datei komprimiert ist.

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 window.boot() .

💡 Für Nicht-Web-Plattformen wird die Funktion window.boot() direkt nach der Definition aufgerufen, daher ist main.js ihr Ausgangspunkt.

window.boot() weist die folgenden wichtigen Verhaltensweisen auf:

  1. Definieren Sie die onStart Rückruffunktion: Wird hauptsächlich zum Laden der Startszene verwendet
  2. cc.assetManager.init(...) : AssetManager initialisieren
  3. cc.assetManager.loadScript(...) : lädt das Plugin-Skript in das src-Verzeichnis
  4. cc.assetManager.loadBundle(...) : lädt das Bundle im Projekt
  5. cc.game.run(...) : Starten Sie den Motor

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 cc.game Objekt ist eine Instanz cc.Game Klasse. cc.game enthält die wichtigsten Spielinformationen und ist für die Steuerung des Spiels verantwortlich.

Einfach ausgedrückt ist das cc.game -Objekt das Modul, das den Lebenszyklus der Engine verwaltet. Es wird für Vorgänge wie Starten, Anhalten und Neustarten benötigt.

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

laufen()

cc.game.run() gibt die Engine-Konfiguration und onStart -Rückruf an und löst cc.game.prepare() aus.

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()

cc.game.prepare() kompiliert hauptsächlich den Projektcode schnell und ruft _prepareFinished() auf, wenn eine Vorschau des Projekts angezeigt wird.

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“ __quick_compile_project__ suchen (Strg + P), um __quick_compile_project__.js zu finden.

_prepareFinished()

Die Hauptfunktionen cc.game._prepareFinished() bestehen darin, die Engine zu initialisieren, den Framerate-Timer einzustellen und integrierte Ressourcen (Effektressourcen und Materialressourcen) zu initialisieren.

Wenn die integrierten Ressourcen geladen sind, wird cc.game._runMainLoop() aufgerufen, um die Hauptschleife der Engine zu starten.

_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 _prepareFinished() aufgerufene Funktion _setAnimFrame() zu erwähnen.

_setAnimFrame()

cc.game._setAnimFrame() passt sich intern an unterschiedliche Bildraten von Spielen an.

Darüber hinaus ist window.requestAnimationFrame() gekapselt, um die Kompatibilität mit verschiedenen Browserumgebungen zu gewährleisten. Auf die Einzelheiten gehen wir weiter unten ein.

Ich werde den Code von _setAnimFrame() hier nicht veröffentlichen, aber Sie können ihn sich ansehen, wenn Sie ihn brauchen.

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

_runMainLoop()

Der Name cc.game._runMainLoop() ist sehr einfach und direkt. Er wird verwendet, um mainLoop() auszuführen.

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 _runMainLoop() hauptsächlich window.requestAnimFrame() verwendet, um den Loop-Aufruf mainLoop() zu implementieren.

Fenster.requestAnimFrame()

window.requestAnimFrame() ist die Kompatibilitätskapselung von window.requestAnimationFrame() () innerhalb des oben erwähnten _setAnimFrame() .

Freunde, die mit dem Front-End nicht vertraut sind, haben möglicherweise Fragen: Was ist window.requestAnimationFrame() , wofür wird es verwendet und wie funktioniert es?

window.requestAnimationFrame()

Einfach ausgedrückt wird window.requestAnimationFrame() verwendet, um eine Neuzeichnung vom Browser anzufordern und vor der Neuzeichnung die angegebene Rückruffunktion aufzurufen.

window.requestAnimationFrame() empfängt einen Rückruf als Parameter und gibt eine Ganzzahl als eindeutige Kennung zurück. Der Browser führt diesen Rückruf vor dem nächsten Neuzeichnen aus. Bei der Ausführung des Rückrufs wird ein Parameter übergeben, dessen Wert dem von performance.now() zurückgegebenen Wert entspricht.

Der Rückgabewert von performance.now() kann einfach als die Lauflänge des Browserfensters verstanden werden, also die Zeitdifferenz vom Öffnen des Fensters bis zum aktuellen Moment.

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 window.requestAnimationFrame() . Wenn Sie weitere Informationen wünschen, suchen Sie bitte selbst danach.

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 ~

Hauptschleife

Nach einigen Drehungen und Wendungen kamen wir endlich zur mit Spannung erwarteten Hauptschleife des Motors. Und nun ohne weitere Umschweife weiter!

cc.Direktor

cc.director -Objekt ist eine Instanz der Director-Klasse cc.Director . Die Engine verwaltet hauptsächlich den logischen Ablauf des Spiels über cc.director -Objekt.

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

Hauptschleife ()

🍖 cc.director.mainLoop() ist möglicherweise eine der kritischsten Logiken in der Engine und enthält eine Menge kritischen Inhalt.

Sehen wir uns nun mainLoop() an!

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

_compScheduler Attribut im cc.director Objekt ist eine Instanz ComponentScheduler Klasse.

Die meisten von Ihnen haben wahrscheinlich keine Vorstellung von ComponentScheduler Klasse, deshalb möchte ich sie kurz erklären.

Die wörtliche Übersetzung des Namens ComponentScheduler lautet „Komponentenplaner“. Wie der Name schon sagt, wird diese Klasse zum Planen von Komponenten verwendet.

Einfach ausgedrückt wird die Klasse ComponentScheduler verwendet, um den Lebenszyklus aller Komponenten ( cc.Component ) in der Spielszene zentral zu planen (verwalten).

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 start -Callback-Funktion der Komponente wird ausgelöst, bevor die Komponente zum ersten Mal aktiviert wird, d. h. bevor das erste update ausgeführt wird.

start Callback wird während der Lebensdauer der Komponente nur einmal ausgelöst, dasselbe gilt für onLoad und onEnable .

Es ist nur so, dass onLoad und onEnable von Instanzen NodeActivator Klasse verwaltet werden:

onLoad wird ausgelöst, wenn der Knoten aktiviert wird, onEnable wird ausgelöst, wenn die Komponente aktiviert wird.

start wird erst bei der nächsten Hauptschleife mainLoop() ausgelöst.

🥁 NodeActivator

NodeActivator wird hauptsächlich zum Aktivieren und Deaktivieren von Knoten und ihren Komponenten verwendet.

cc.director Objekt hat eine Instanz _nodeActivator , und das Aktivieren und Deaktivieren aller Knoten im Spiel muss darüber erfolgen.

So: cc.director._nodeActivator.activateNode(this, value);

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 update der Komponente wird einmal pro Frame ausgelöst.

späteUpdatePhase

//Rufen Sie die LateUpdate-Funktion aller Komponenten auf (aktiviert) this._compScheduler.lateUpdatePhase(deltaTime);

Die lateUpdate -Funktion der Komponente wird ausgelöst, nachdem update und der Scheduler cc.Scheduler aktualisiert wurden. Zu den Scheduler-Updates zählen Easing, Animation und Physik, die weiter unten näher erläutert werden.

Partikelsystem

Übrigens wird die Partikelsystemkomponente ( cc.ParticleSystem ) in der Rückruffunktion lateUpdate aktualisiert.

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

Tipps

Bitte verwenden Sie update und lateUpdate -Rückrufe mit Vorsicht, da sie für jeden Frame ausgelöst werden. Wenn update oder lateUpdate zu viel Logik enthalten, ist die Ausführungszeit jedes Frames (d. h. die Frame-Zeit) länger, was zu einer niedrigeren Framerate oder Instabilität im Spiel führt.

📢 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 Attribut cc.director Objekts ist eine Instanz cc.Scheduler Klasse.

cc.Scheduler ist die Klasse, die für das Auslösen der Rückruffunktion verantwortlich ist.

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);

_scheduler.update() wird in cc.director.mainLoop() verwendet, um Updates zu verteilen. Innerhalb des Schedulers ( cc.director._scheduler ) werden die Updates verschiedener Systemmodule und Komponenten-Timer nacheinander entsprechend ihrer Priorität ausgelöst.

Systemmodul

Die Aktualisierung des Schedulers löst zunächst die Aktualisierung der folgenden Systemmodule aus:

  • AktionsManager
  • AnimationManager
  • KollisionsManager
  • PhysikManager
  • Physik3DManager
  • EingabeManager

Alle oben genannten Module werden mit cc.director._scheduler.scheduleUpdate() beim Scheduler registriert, da diese Module bei jedem Frame aktualisiert werden müssen.

Die Priorität aller Module außer InputManager ist cc.Scheduler.PRIORITY_SYSTEM . Dies ist die Systempriorität und wird zuerst ausgelöst.

AktionsManager

ActionManager ist der Aktionsmanager, der zum Verwalten aller Aktionen im Spiel verwendet wird, also des Easing-Systems Action und Tween (tatsächlich sind sie im Wesentlichen dasselbe).

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

AnimationManager

AnimationManager ist ein Animationsmanager, der alle Animationen im Spiel verwaltet und Animation auf den Knoten ansteuert, um Animationen abzuspielen.

animation-manager.js: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/animation/animation-manager.js

KollisionsManager

CollisionManager ist der Kollisionskomponenten-Manager, der verwendet wird, um zu verarbeiten, ob die Kollisionskomponenten zwischen Knoten kollidiert sind, und um die entsprechende Rückruffunktion aufzurufen.

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

PhysikManager

PhysicsManager ist der physikalische Systemmanager, der Box2D intern als 2D-Physik-Engine verwendet, kapselt und einige häufig verwendete Schnittstellen öffnet. Gleichzeitig ist PhysicsManager auch für die Verwaltung der Verteilung von Kollisionsinformationen verantwortlich.

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

Physik3DManager

Physics3DManager ist der 3D-Physiksystemmanager. Die 3D-Physik-Engines in Cocos Creator umfassen Cannon.js und Builtin . Physics3DManager kapselt eine einheitliche gemeinsame Schnittstelle für sie.

physics-manager.ts: https://github.com/cocos-creator/engine/blob/2.4.3/cocos2d/core/3d/physics/framework/physics-manager.ts

EingabeManager

InputManager ist der Eingabeereignis-Manager, der zum Verwalten aller Eingabeereignisse verwendet wird. Nachdem der Entwickler den Beschleunigungsmesser aktiv aktiviert hat, sendet die Engine regelmäßig cc.SystemEvent.EventType.DEVICEMOTION -Ereignisse über InputManager (das Standardintervall beträgt 0,2 Sekunden).

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 schedule() und scheduleOnce() von Komponenten verwendet, die hauptsächlich zum wiederholten Ausführen oder Planen von Funktionen dienen.

Tatsächlich basiert schedule() -Schnittstelle von cc.Component auch auf cc.Scheduler Klasse und verwendet insbesondere die _scheduler Instanz im cc.director Objekt.

schedule() -Schnittstelle der Komponente fügt eine Kapselungsebene außerhalb cc.director._scheduler.schedule() Schnittstelle hinzu, wobei die Komponente selbst target ist. Auf diese Weise sind die geplanten Aufgaben in der Komponente an den Lebenszyklus der Komponente gebunden und die geplanten Aufgaben werden auch entfernt, wenn die Komponente zerstört wird.

scheduleOnce() fügt eine weitere Kapselungsebene außerhalb der Schnittstelle schedule() der Komponente hinzu und ist so festgelegt, dass sie nach der angegebenen Zeit nur einmal ausgeführt wird.

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 setInterval() immer noch nicht ganz klar sind. Lassen Sie mich daher die Gelegenheit nutzen, es kurz zu erklären ~

setTimeout und setIntervall

Sowohl setTimeout() als auch setInterval() sind Schnittstellen, die von Browsern oder Laufzeiten wie Node.js bereitgestellt werden.

Mit der Schnittstelle setTimeout() wird ein Timer eingestellt, der nach Ablauf des Timers eine Funktion oder einen angegebenen Code ausführt. Die Schnittstelle setInterval() wird verwendet, um eine Funktion aufzurufen oder ein Codesegment wiederholt mit einer festen Zeitverzögerung zwischen jedem Aufruf auszuführen.

💡 Noch eine kleine Erkenntnis:

Die minimale Verzögerung (Intervall) für setTimeout() und setInterval() im Browser beträgt 4 ms.

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 mainLoop() der Engine und der Komponente selbst ab. Wenn die Engine angehalten wird, wird auch der Timer der Komponente angehalten. Wenn die Komponente oder der Knoten, in dem sich die Komponente befindet, zerstört wird, wird der Timer ebenfalls ungültig.

Sowohl setTimeout() als auch setInterval() hängen vom aktuellen window ab. Dies bedeutet, dass setTimeout() und setInterval() weiterhin ausgeführt werden, solange die aktuelle Browserregisterkarte nicht geschlossen wird.

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 setInterval() in einem Skript in der aktuellen Szene, um einen Knoten in der Szene wiederholt zu verschieben. Was passiert, wenn wir die Szene wechseln?

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 setTimeout() oder setInterval() in Betracht ziehen.

🎃 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 Scheduler kurz zusammenzufassen.

Zusammenfassen

Damit 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:
  • Unity3D realisiert die Bewegung des Kameraobjektivs und begrenzt den Winkel
  • Detaillierte Erklärung zur Verwendung mehrerer Timer in CocosCreator
  • CocosCreator - modulares Lernskript
  • So verwenden Sie Verbindungen der Physik-Engine in CocosCreator
  • So verwenden Sie die JSZip-Komprimierung in CocosCreator
  • CocosCreator-Tutorial für den Einstieg: Erstellen Sie Ihr erstes Spiel mit TS
  • CocosCreator allgemeines Framework-Design Ressourcenmanagement
  • So erstellen Sie eine Liste in CocosCreator
  • So verwenden Sie http und WebSocket in CocosCreator
  • Analyse des neuen Ressourcenmanagementsystems von CocosCreator
  • So verwenden Sie cc.follow zur Kameraverfolgung in CocosCreator

<<:  Detailliertes Installationstutorial zur dekomprimierten Version von mysql5.7.19 (mit rein geknackter chinesischer Version von SQLYog)

>>:  Detailliertes Installationstutorial für die MySQL-Zip-Archivversion (5.7.19)

Artikel empfehlen

So verwenden Sie den EXPLAIN-Befehl in SQL

Bei unserer täglichen Arbeit führen wir manchmal ...

mysql 5.7.5 m15 winx64.zip Installations-Tutorial

So installieren und konfigurieren Sie mysql-5.7.5...

Docker startet Redis und legt das Passwort fest

Redis verwendet das Apline-Image (Alps) von Redis...

Eine detaillierte Erklärung der subtilen Unterschiede zwischen Readonly und Disabled

Sowohl die Optionen „Nur lesen“ als auch „Deaktivi...

Ubuntu-Installations-Grafiktreiber und CUDA-Tutorial

Inhaltsverzeichnis 1. Deinstallieren Sie den Orig...

MySQL partitioniert vorhandene Tabellen in der Datentabelle

Inhaltsverzeichnis So funktioniert es Betriebsabl...

Das WeChat-Applet implementiert einen einfachen Rechner

Ein einfacher Rechner, der als Referenz in das We...

So installieren Sie MySQL 5.7.29 mit einem Klick mithilfe eines Shell-Skripts

Dieser Artikel bezieht sich auf die Arbeit des 51...

So begrenzen Sie die Anzahl gleichzeitiger Verbindungsanforderungen in Nginx

Einführung Das Modul, das die Anzahl gleichzeitig...

CSS-Methode zum Löschen von Float und BFC

BFC BFC: Blockformatierungskontext BFC-Layoutrege...

Verschiedene korrekte Haltungen zur Verwendung von Umgebungsvariablen in Webpack

Inhaltsverzeichnis Schreiben Sie vor Geschäftscod...

Der Quellcode zeigt, warum Vue2 Daten und Methoden direkt abrufen kann

Inhaltsverzeichnis 1. Beispiel: Hiermit können Da...