Hallo, (seltsame) Welt
Die Google-Startseite ist eine faszinierende Umgebung zum Programmieren. Es gibt viele herausfordernde Einschränkungen: ein besonderer Fokus auf Geschwindigkeit und Latenz, die Anforderungen aller Arten von Browsern erfüllen und unter verschiedenen Umständen funktionieren und… ja, Nutzer überraschen und begeistern.
Ich meine Google-Doodles, die speziellen Illustrationen, die gelegentlich unser Logo ersetzen. Und obwohl meine Beziehung zu Stiften und Pinseln schon lange den unverwechselbaren Geschmack eines Gerichtsbeschlusses hat, trage ich oft zu den interaktiven Inhalten bei.
Jedes interaktive Doodle, das ich programmiert habe (Pac-Man, Jules Verne, World's Fair), und viele, bei denen ich mitgewirkt habe, waren in gleichem Maße futuristisch und anachronistisch: großartige Möglichkeiten für ambitionierte Anwendungen modernster Webfunktionen und der pragmatische Pragmatismus der plattformübergreifenden Kompatibilität.
Wir lernen viel von jedem interaktiven Doodle. Das jüngste Minispiel zu Stanisław Lem war dabei keine Ausnahme. Mit seinen 17.000 Zeilen JavaScript-Code wurden viele Dinge zum ersten Mal in der Doodle-Geschichte ausprobiert. Heute möchte ich diesen Code mit Ihnen teilen. Vielleicht finden Sie darin etwas Interessantes oder können mir auf Fehler hinweisen. Ich möchte auch ein wenig darüber sprechen.
Code des Stanisław-Lem-Doodles ansehen »
Denken Sie daran, dass die Startseite von Google kein Ort für Tech-Demos ist. Mit unseren Google-Logo-Artworks möchten wir bestimmte Personen und Ereignisse feiern. Dabei setzen wir auf die beste Kunst und die besten Technologien, die wir uns vorstellen können. Wir feiern aber nie die Technologie um ihrer selbst willen. Das bedeutet, dass wir uns genau ansehen, welche HTML5-Funktionen verfügbar sind und ob sie uns dabei helfen, das Doodle zu verbessern, ohne von ihm abzulenken oder es zu überschatten.
Sehen wir uns einige der modernen Webtechnologien an, die im Doodle zu Stanisław Lem einen Platz gefunden haben – und einige, die es nicht geschafft haben.
Grafiken über DOM und Canvas
Canvas ist leistungsstark und genau für die Art von Dingen konzipiert, die wir in diesem Doodle umsetzen wollten. Einige ältere Browser, die für uns wichtig waren, unterstützten es jedoch nicht. Und obwohl ich buchstäblich das Büro mit der Person teile, die eine ansonsten hervorragende excanvas-Lösung entwickelt hat, habe ich mich für eine andere Lösung entschieden.
Ich habe eine Grafik-Engine zusammengestellt, die grafische Primitivformen namens „rects“ abstrahiert und sie dann entweder mit Canvas oder dem DOM rendert, falls Canvas nicht verfügbar ist.
Dieser Ansatz bringt einige interessante Herausforderungen mit sich. So hat das Verschieben oder Ändern eines Objekts im DOM beispielsweise unmittelbare Auswirkungen, während bei Canvas alles gleichzeitig gezeichnet wird. (Ich habe mich dafür entschieden, nur einen Canvas zu verwenden, diesen zu löschen und bei jedem Frame von vorn anzufangen. Einerseits zu viele bewegliche Teile und andererseits nicht genug Komplexität, um sie in mehrere sich überschneidende Canvasse aufzuteilen und selektiv zu aktualisieren.)
Leider ist der Wechsel zu Canvas nicht so einfach, wie nur CSS-Hintergründe mit drawImage()
zu spiegeln: Sie verlieren eine Reihe von Funktionen, die beim Zusammenstellen von Elementen über das DOM kostenlos zur Verfügung stehen – vor allem die Schichtung mit Z-Indexen und Mausereignissen.
Ich habe den Z-Index bereits mit einem Konzept namens „Ebenen“ abstrahiert. Das Doodle definierte eine Reihe von Ebenen – vom Himmel weit hinten bis zum Mauszeiger vor allem – und jeder Akteur im Doodle musste entscheiden, zu welcher er gehörte. Kleine Plus-/Minuskorrekturen innerhalb einer Ebene waren mit planeCorrection
möglich.
Beim Rendern über das DOM werden die Ebenen einfach in den Z-Index übersetzt. Wenn wir jedoch über Canvas rendern, müssen wir die Rechtecke nach ihren Ebenen sortieren, bevor wir sie zeichnen. Da dies jedes Mal aufwendig ist, wird die Reihenfolge nur neu berechnet, wenn ein Akteur hinzugefügt oder in eine andere Ebene verschoben wird.
Auch Mausereignisse habe ich abstrahiert – sozusagen. Sowohl für das DOM als auch für das Canvas habe ich zusätzliche, vollständig transparente, schwebende DOM-Elemente mit hohem Z-Index verwendet, die nur auf Mausbewegungen, Klicks und Tippen reagieren.
Mit diesem Doodle wollten wir unter anderem die vierte Wand durchbrechen. Mit der oben genannten Engine konnten wir Canvas-basierte Akteure mit DOM-basierten Akteuren kombinieren. Die Explosionen im Finale befinden sich beispielsweise sowohl im Canvas für In-Universe-Objekte als auch im DOM für den Rest der Google-Startseite. Der Vogel, der normalerweise herumfliegt und wie jeder andere Darsteller von unserer unregelmäßigen Maske abgeschnitten wird, entscheidet sich, während der Aufnahmen nicht in Schwierigkeiten zu geraten, und setzt sich auf die Schaltfläche „Ich bin ein Glückspilz“. Dazu verlässt der Vogel das Canvas und wird zu einem DOM-Element (und später umgekehrt), was für unsere Besucher hoffentlich völlig transparent ist.
Die Framerate
Die aktuelle Framerate zu kennen und darauf zu reagieren, wenn sie zu langsam (oder zu schnell) ist, war ein wichtiger Bestandteil unserer Engine. Da die Browser die Framerate nicht zurückgeben, müssen wir sie selbst berechnen.
Ich habe mit requestAnimationFrame begonnen und bin auf die altmodische setTimeout
zurückgefallen, wenn die erste nicht verfügbar war.
requestAnimationFrame
spart in einigen Situationen clever die CPU – auch wenn wir das teilweise selbst tun, wie unten erläutert wird –, ermöglicht aber auch einfach eine höhere Framerate als setTimeout
.
Die Berechnung der aktuellen Framerate ist einfach, kann aber drastisch variieren. Sie kann beispielsweise schnell sinken, wenn eine andere Anwendung den Computer für eine Weile beansprucht. Daher berechnen wir nur alle 100 physischen Ticks eine „rolling“ (gemittelte) Framerate und treffen auf dieser Grundlage Entscheidungen.
Welche Art von Entscheidungen?
Wenn die Framerate über 60 fps liegt, wird sie gedrosselt. Derzeit gibt es in einigen Versionen von Firefox keine Obergrenze für die Framerate von
requestAnimationFrame
. Es hat also keinen Sinn, die CPU zu belasten. Hinweis: Wir begrenzen die Framerate auf 65 fps, da die Rundungsfehler die Framerate in anderen Browsern nur geringfügig über 60 fps anheben. Wir möchten nicht, dass die Framerate versehentlich gedrosselt wird.Wenn die Framerate unter 10 fps liegt, wird die Engine einfach verlangsamt, anstatt Frames zu entfernen. Es ist eine lose-lose-Situation, aber ich war der Meinung, dass das übermäßige Überspringen von Frames verwirrender wäre als ein langsameres (aber dennoch kohärentes) Spiel. Es gibt noch einen weiteren positiven Nebeneffekt: Wenn das System vorübergehend langsam wird, bemerkt der Nutzer keinen merkwürdigen Sprung nach vorne, während der Engine verzweifelt versucht, den Rückstand aufzuholen. (Bei Pac-Man habe ich es etwas anders gemacht, aber die Mindestframerate ist ein besserer Ansatz.)
Schließlich können wir die Grafiken vereinfachen, wenn die Framerate gefährlich niedrig wird. Beim Lem-Doodle ist das nicht der Fall, mit Ausnahme des Mauszeigers (mehr dazu weiter unten). Theoretisch könnten wir einige der überflüssigen Animationen entfernen, damit das Doodle auch auf langsameren Computern flüssig läuft.
Außerdem gibt es das Konzept eines physischen und eines logischen Tickens. Ersteres ergibt sich aus requestAnimationFrame
/setTimeout
. Das Verhältnis beim normalen Gameplay ist 1:1, aber beim Vorspulen fügen wir einfach mehr logische Takte pro physischem Takt hinzu (bis zu 1:5). So können wir alle erforderlichen Berechnungen für jeden logischen Tick ausführen, aber nur den letzten als Aktualisierer der Elemente auf dem Bildschirm festlegen.
Benchmarking
Es kann davon ausgegangen werden (und das wurde in der Anfangsphase auch getan), dass Canvas schneller als das DOM ist, wann immer es verfügbar ist. Das ist nicht immer der Fall. Bei den Tests haben wir festgestellt, dass Opera 10.0–10.1 auf einem Mac und Firefox unter Linux beim Verschieben von DOM-Elementen tatsächlich schneller sind.
Im Idealfall würde das Doodle verschiedene grafische Techniken vergleichen – DOM-Elemente, die mit style.left
und style.top
verschoben werden, Zeichnen auf dem Canvas und vielleicht sogar DOM-Elemente, die mit CSS3-Transformationen verschoben werden.
und dann zu derjenigen wechseln, die die höchste Framerate liefert. Ich habe damit begonnen, Code dafür zu schreiben, aber festgestellt, dass meine Art der Benchmarking ziemlich unzuverlässig war und viel Zeit in Anspruch nahm. Auf unserer Startseite ist das nicht möglich. Geschwindigkeit ist uns sehr wichtig und wir möchten, dass das Doodle sofort angezeigt wird und das Spiel beginnt, sobald Sie klicken oder tippen.
Letztendlich kommt es bei der Webentwicklung manchmal darauf an, das zu tun, was getan werden muss. Ich habe mich umgesehen, um sicherzugehen, dass niemand zusah, und dann Opera 10 und Firefox einfach aus dem Canvas herausgecodet. Im nächsten Leben werde ich als <marquee>
-Tag wiedergeboren.
CPU-Ressourcen schonen
Du kennst diesen Freund, der zu dir nach Hause kommt, sich das Staffelfinale von Breaking Bad ansieht, es dir verrät und es dann aus deinem DVR löscht? Sie möchten doch nicht zu diesen Leuten gehören, oder?
Ja, das ist die schlechteste Analogie überhaupt. Wir möchten aber auch nicht, dass unser Doodle so ein Typ ist. Die Tatsache, dass wir auf den Browsertab eines Nutzers zugreifen dürfen, ist ein Privileg. Wenn wir CPU-Zyklen belegen oder den Nutzer ablenken, wären wir ein unangenehmer Gast. Wenn also niemand mit dem Doodel spielt (keine Fingertippen, Mausklicks, Mausbewegungen oder Tastendrücke), soll es in den Ruhemodus versetzt werden.
Wann?
- nach 18 Sekunden auf der Startseite (in Arcade-Spielen Attract-Modus genannt)
- nach 180 Sekunden, wenn der Tab den Fokus hat
- nach 30 Sekunden, wenn der Tab nicht im Fokus ist (z.B. wenn der Nutzer zu einem anderen Fenster gewechselt ist, sich das Doodle aber möglicherweise noch in einem inaktiven Tab ansieht)
- sofort, wenn der Tab unsichtbar wird (z.B. wenn der Nutzer im selben Fenster zu einem anderen Tab gewechselt ist – es macht keinen Sinn, Zyklen zu verschwenden, wenn wir nicht sichtbar sind)
Woher wissen wir, dass der Tab derzeit den Fokus hat? Wir binden uns an window.focus
und window.blur
. Woher wissen wir, dass der Tab sichtbar ist? Wir verwenden die neue Page Visibility API und reagieren auf das entsprechende Ereignis.
Die oben genannten Zeitüberschreitungen sind großzügiger als üblich. Ich habe sie an dieses Doodle angepasst, das viele Umgebungsanimationen enthält (vor allem der Himmel und der Vogel). Idealerweise würden die Zeitüberschreitungen durch Interaktionen im Spiel gesteuert – z. B. könnte der Vogel direkt nach der Landung dem Doodel mitteilen, dass er jetzt schlafen kann. Das habe ich aber letztendlich nicht implementiert.
Da sich der Himmel immer in Bewegung befindet, wird das Doodel beim Einschlafen und Aufwachen nicht einfach an- oder ausgeschaltet. Es wird verlangsamt, bevor es pausiert, und umgekehrt, wenn es fortgesetzt wird. Die Anzahl der logischen Ticks pro physischem Tick wird bei Bedarf erhöht oder verringert.
Übergänge, Transformationen, Ereignisse
Eine der Stärken von HTML war schon immer, dass Sie es selbst verbessern können: Wenn etwas im regulären Portfolio von HTML und CSS nicht gut genug ist, können Sie JavaScript verwenden, um es zu erweitern. Leider bedeutet das oft, dass Sie ganz von vorn anfangen müssen. CSS3-Übergänge sind großartig, aber Sie können keinen neuen Übergangstyp hinzufügen oder Übergänge für andere Zwecke als das Stylen von Elementen verwenden. Ein weiteres Beispiel: CSS3-Transformationen sind ideal für das DOM, aber wenn Sie zu Canvas wechseln, sind Sie plötzlich auf sich allein gestellt.
Aus diesen und weiteren Gründen hat das Lem-Doodle eine eigene Übergangs- und Transformations-Engine. Ja, ich weiß, die 2000er-Jahre haben angerufen usw. Die von mir implementierten Funktionen sind bei weitem nicht so leistungsfähig wie CSS3, aber was die Engine tut, tut sie konsistent und bietet uns viel mehr Kontrolle.
Ich habe mit einem einfachen Aktionssystem (Ereignissystem) begonnen – einer Zeitachse, die Ereignisse in der Zukunft auslöst, ohne setTimeout
zu verwenden. Da die Zeit in Google Pixel Tablet zu einem bestimmten Zeitpunkt von der physischen Zeit abweichen kann, wenn sie schneller (Vorspulen), langsamer (niedrige Framerate oder Ruhemodus zur CPU-Einsparung) oder ganz anhält (Warten auf das Laden von Bildern),
Übergänge sind nur eine weitere Art von Aktionen. Neben einfachen Bewegungen und Drehungen unterstützen wir auch relative Bewegungen (z.B. etwas 10 Pixel nach rechts verschieben), benutzerdefinierte Elemente wie Zittern und Keyframe-Bildanimationen.
Ich habe bereits erwähnt, dass auch die Drehungen manuell erfolgen. Wir haben Sprites für verschiedene Winkel für die Objekte, die gedreht werden müssen. Der Hauptgrund ist, dass sowohl CSS3- als auch Canvas-Rotationen visuelle Artefakte verursachten, die wir für inakzeptabel halten. Außerdem variierten diese Artefakte je nach Plattform.
Da einige rotierende Objekte an anderen rotierenden Objekten befestigt sind, z. B. die Hand eines Roboters, die mit dem Unterarm verbunden ist, der wiederum mit einem rotierenden Oberarm verbunden ist, musste ich auch eine Art Ersatz für die Transformatorenachse in Form von Drehpunkten erstellen.
All das ist eine Menge Arbeit, die letztendlich den Bereich abdeckt, der bereits von HTML5 abgedeckt wird. Manchmal ist die native Unterstützung jedoch nicht gut genug und es ist an der Zeit, das Rad neu zu erfinden.
Bilder und Sprites
Eine Engine dient nicht nur dazu, das Doodle auszuführen, sondern auch, daran zu arbeiten. Ich habe oben einige Debug-Parameter geteilt. Den Rest finden Sie unter engine.readDebugParams
.
Spriting ist eine bekannte Technik, die wir auch für unsere eigenen Doodles verwenden. So können wir Byte einsparen und die Ladezeiten verkürzen. Außerdem wird das Vorladen erleichtert.
Allerdings erschwert es auch die Entwicklung: Jede Änderung an den Bildern würde ein erneutes Spriting erfordern (weitgehend automatisiert, aber dennoch mühsam). Daher unterstützt die Engine die Ausführung über engine.useSprites
sowohl mit Rohbildern für die Entwicklung als auch mit Sprites für die Produktion. Beide sind im Quellcode enthalten.

Außerdem können Bilder vorab geladen werden und das Doodle wird angehalten, wenn die Bilder nicht rechtzeitig geladen werden. Dazu gibt es eine gefälschte Fortschrittsanzeige. (Falsch, da leider nicht einmal HTML5 uns sagen kann, wie viel von einer Bilddatei bereits geladen wurde.)

Bei einigen Szenen verwenden wir nicht nur einen Sprite, um das Laden mit parallelen Verbindungen zu beschleunigen, sondern einfach aufgrund der 3/5-Millionen-Pixel-Begrenzung für Bilder unter iOS.
Wo passt HTML5 in all das? Oben ist nicht viel davon zu sehen, aber das Tool, das ich zum Erstellen von Sprites und Zuschneiden von Bildern geschrieben habe, basiert auf neuen Webtechnologien: Canvas, Blobs und a[download]. Eines der spannenden Dinge an HTML ist, dass es nach und nach Dinge umfasst, die zuvor außerhalb des Browsers erledigt werden mussten. Der einzige Teil, den wir dort erledigen mussten, war die Optimierung von PNG-Dateien.
Spielstatus zwischen den Spielen speichern
Lems Welten wirkten immer groß, lebendig und realistisch. Seine Geschichten begannen in der Regel ohne viel Erklärung, die erste Seite begann in medias res, wobei sich die Leser selbst zurechtfinden mussten.
„Cyberiad“ war keine Ausnahme und wir wollten dieses Gefühl auch im Doodle widerspiegeln. Wir versuchen, die Geschichte nicht zu sehr zu erklären. Ein weiterer wichtiger Aspekt ist die Zufallsgenerierung, die unserer Meinung nach zur mechanischen Natur des Buchuniversums passt. Wir haben eine Reihe von Hilfsfunktionen, die mit Zufälligkeit zu tun haben und die wir an vielen, vielen Stellen verwenden.
Außerdem wollten wir die Wiederspielbarkeit auf andere Weise erhöhen. Dazu mussten wir wissen, wie oft das Doodle schon fertiggestellt wurde. Die historisch korrekte technologische Lösung dafür ist ein Cookie. Das funktioniert jedoch nicht für die Google-Startseite. Jedes Cookie erhöht die Nutzlast jeder Seite. Wie bereits erwähnt, legen wir großen Wert auf Geschwindigkeit und Latenz.
Glücklicherweise bietet HTML5 Web Storage, das sich ganz einfach verwenden lässt. Damit können wir die Gesamtzahl der Wiedergaben und die letzte vom Nutzer abgespielte Szene speichern und abrufen – viel einfacher als mit Cookies.
Was machen wir mit diesen Informationen?
- Wir zeigen eine Schaltfläche zum Vorspulen, mit der die Nutzer die Zwischensequenzen, die sie bereits gesehen haben, überspringen können.
- Im Finale werden verschiedene N-Elemente gezeigt.
- haben wir den Schwierigkeitsgrad des Aufnahmelevels leicht erhöht.
- Beim dritten und den nachfolgenden Durchgängen wird ein kleiner Drache als Easter Egg aus einer anderen Geschichte angezeigt.
Es gibt eine Reihe von Debug-Parametern, mit denen sich dies steuern lässt:
?doodle-debug&doodle-first-run
– so tun, als wäre es der erste Durchlauf?doodle-debug&doodle-second-run
– so tun, als wäre es ein zweiter Durchlauf?doodle-debug&doodle-old-run
– so tun, als wäre es ein alter Lauf
Geräte mit Touchscreen
Wir wollten, dass das Doodle auf Touchbildschirmen gut funktioniert. Die meisten modernen Geräte sind leistungsstark genug, um das Doodle flüssig laufen zu lassen. Außerdem macht es viel mehr Spaß, das Spiel durch Tippen zu spielen als durch Klicken.
Es mussten einige Änderungen an der Nutzerfreundlichkeit vorgenommen werden. Ursprünglich war der Mauszeiger der einzige Hinweis darauf, dass eine Zwischensequenz oder ein nicht interaktiver Teil gerade abgespielt wird. Später haben wir rechts unten einen kleinen Indikator hinzugefügt, damit wir nicht nur auf den Mauszeiger angewiesen waren, da es diesen auf Touch-Geräten nicht gibt.
Normal | Beschäftigt | Anklickbar | Geklickt | |
---|---|---|---|---|
In Arbeit | ![]() |
![]() |
![]() |
![]() |
Finale | ![]() |
![]() |
![]() |
![]() |
Die meisten Funktionen funktionierten sofort. Schnelle, spontane Usability-Tests unserer Touchbedienung haben jedoch zwei Probleme aufgezeigt: Einige der Ziele waren zu schwer zu drücken und schnelle Antippen wurden ignoriert, da wir Mausklickereignisse einfach überschrieben haben.
Separate anklickbare transparente DOM-Elemente haben hier sehr geholfen, da ich sie unabhängig von den visuellen Elementen anpassen konnte. Ich habe für Touchgeräte ein zusätzliches Padding von 15 Pixeln eingeführt und es immer dann verwendet, wenn anklickbare Elemente erstellt wurden. (Ich habe auch für Mausumgebungen einen Abstand von 5 Pixeln hinzugefügt, nur um Herrn Fitts zufriedenzustellen.)
Was das andere Problem angeht, habe ich einfach dafür gesorgt, dass die richtigen Touch-Start- und -End-Handler angehängt und getestet wurden, anstatt mich auf Mausklicks zu verlassen.
Außerdem verwenden wir modernere Stileigenschaften, um einige Touch-Funktionen zu entfernen, die WebKit-Browser standardmäßig hinzufügen (z. B. „Highlight durch Tippen“ und „Hinweis durch Tippen“).
Und wie erkennen wir, ob ein bestimmtes Gerät, auf dem das Doodle ausgeführt wird, Touchbedienung unterstützt? Lazily. Anstatt das a priori herauszufinden, haben wir einfach mit unserem kombinierten IQ darauf geschlossen, dass das Gerät Touchbedienung unterstützt, nachdem wir das erste Touchstartereignis erhalten haben.
Mauszeiger anpassen
Aber nicht alles ist berührungsempfindlich. Eines unserer Leitprinzipien war es, so viele Dinge wie möglich in das Universum des Doodles einzubauen. Die kleine Seitenleiste (Vorspulen, Fragezeichen), die Kurzinfo und sogar der Mauszeiger.
Wie kann ich den Mauszeiger anpassen? In einigen Browsern können Sie den Mauszeiger ändern, indem Sie eine benutzerdefinierte Bilddatei verknüpfen. Diese Methode wird jedoch nicht gut unterstützt und ist auch etwas eingeschränkt.
Wenn nicht, was dann? Warum sollte der Mauszeiger nicht einfach ein weiterer Akteur im Doodle sein? Das funktioniert, hat aber einige Nachteile:
- Sie müssen den nativen Mauszeiger entfernen können.
- Sie müssen Ihren Mauszeiger ziemlich gut mit dem „echten“ Zeiger synchronisieren.
Ersteres ist schwierig. cursor: none
ist in CSS3 zulässig, wird aber in einigen Browsern nicht unterstützt. Wir mussten einige Tricks anwenden: Wir verwendeten eine leere .cur
-Datei als Fallback, bestimmten ein bestimmtes Verhalten für einige Browser und schlossen andere sogar komplett aus.
Das zweite Problem ist auf den ersten Blick relativ unwichtig, aber da der Mauszeiger nur ein weiterer Teil des Universums des Doodels ist, werden auch alle seine Probleme übernommen. Die größte? Wenn die Framerate des Doodels niedrig ist, ist auch die Framerate des Mauszeigers niedrig. Das hat schwerwiegende Folgen, da der Mauszeiger als natürliche Verlängerung Ihrer Hand auf jeden Fall reaktionsschnell sein muss. (Nutzer, die früher Commodore Amiga verwendet haben, nicken jetzt heftig.)
Eine etwas komplexe Lösung für dieses Problem besteht darin, den Mauszeiger von der regulären Updateschleife zu entkoppeln. Genau das haben wir getan – in einem alternativen Universum, in dem ich nicht schlafen muss. Gibt es eine einfachere Lösung für dieses Problem? Der native Mauszeiger wird nur dann wieder verwendet, wenn die Framerate unter 20 fps fällt. (Hier kommt die variable Framerate ins Spiel. Wenn wir auf die aktuelle Framerate reagieren würden und diese zufällig um 20 fps schwankt, würde der benutzerdefinierte Mauszeiger ständig ein- und ausgeblendet werden.) Das führt uns zu:
Frameratebereich | Verhalten |
---|---|
> 10 fps | Verlangsamen Sie das Spiel, damit nicht noch mehr Frames verloren gehen. |
10–20 fps | Verwenden Sie den nativen Mauszeiger anstelle eines benutzerdefinierten Mauszeigers. |
20–60 fps | Normaler Betrieb |
> 60 fps | Begrenzen Sie die Framerate so, dass sie diesen Wert nicht überschreitet. |
Ach ja, unser Mauszeiger ist auf einem Mac dunkel, aber auf einem PC weiß. Warum? Weil Plattformkriege auch in fiktiven Universen Nahrung brauchen.
Fazit
Dieser Algorithmus ist nicht perfekt, aber das ist auch nicht sein Ziel. Es wurde parallel zum Lem-Doodle entwickelt und ist sehr spezifisch für dieses. Das ist in Ordnung. „Zu frühe Optimierung ist die Wurzel allen Übels“, wie Don Knuth berühmt sagte. Ich glaube nicht, dass es sinnvoll ist, zuerst eine Engine in Isolation zu schreiben und sie erst später anzuwenden. Die Praxis beeinflusst die Theorie genauso wie die Theorie die Praxis. In meinem Fall wurde Code verworfen, mehrere Teile immer wieder neu geschrieben und viele gängige Elemente erst nach der Fertigstellung bemerkt. Aber letztendlich haben wir das erreicht, was wir wollten: die Karriere von Stanisław Lem und die Zeichnungen von Daniel Mróz auf die bestmögliche Weise zu feiern.
Ich hoffe, dass das oben Gesagte einige der Designentscheidungen und Kompromisse verdeutlicht hat, die wir treffen mussten, und wie wir HTML5 in einem bestimmten, realen Szenario verwendet haben. Probieren Sie den Quellcode aus und lassen Sie uns wissen, was Sie davon halten.
Das habe ich selbst gemacht. Das Bild unten war in den letzten Tagen zu sehen und zählte die Stunden bis zum 23. November 2011 in Russland herunter, der ersten Zeitzone, in der das Doodle zu sehen war. Vielleicht etwas albern, aber wie bei Scribble Art haben Dinge, die unbedeutend erscheinen, manchmal eine tiefere Bedeutung. Dieser Zähler war ein wirklich guter „Stresstest“ für die Engine.

Das ist eine Möglichkeit, das Leben eines Google-Doodles zu betrachten: Monatelange Arbeit, wochenlange Tests, 48 Stunden Einbrennen – und das alles für etwas, mit dem Nutzer fünf Minuten lang spielen. Hinter jeder dieser Tausenden von JavaScript-Zeilen steht die Hoffnung, dass diese fünf Minuten gut investiert sind. Viel Spaß.