Örnek Olay - Stanisław Lem Google doodle'ını oluşturma

Marcin Wichary
Marcin Wichary

Merhaba (tuhaf) dünya

Google ana sayfası, içinde kodlamak için etkileyici bir ortamdır. Bu durum, birçok zor kısıtlamayı beraberinde getirir: özellikle hız ve gecikmeye odaklanmak, her tür tarayıcıya uyum sağlamak ve çeşitli durumlarda çalışmak ve evet, şaşırtmak ve memnun etmek.

Zaman zaman logomuzun yerini alan özel resimler olan Google doodle'larından bahsediyorum. Kalemlerle fırçalarla ilişkim uzun zamandır bir yasaklama kararının kendine özgü bir tadı olsa da, ben etkileşim halinde olanlarınkine genellikle katkıda bulunuyorum.

Kodladığım her etkileşimli doodle (Pac-Man, Jules Verne, World's Fair) ve yardımcı olduğum çoğu doodle, eşit oranda fütüristik ve zamana dayalı değildi; en yeni Web özelliklerinin gökyüzünde pasta uygulamaları için harika fırsatlar ve tarayıcılar arası uyumluluğun cesur pragmatizmi.

Etkileşimli doodle'ların her birinden çok şey öğrendik. Yeni Stanisław Lem mini oyunu, 17.000 satırlık JavaScript kodu sayesinde doodle tarihinde ilk kez birçok şey denedi. Bugün sizinle bu kodu paylaşmak istiyorum. Belki bu uygulamada ilginç bir şeyler bulur veya hatalarımı gösterirsiniz ve ondan biraz bahsederim.

Stanisław Lem doodle kodunu görüntüleyin »

Google ana sayfasının teknoloji demolarına uygun bir yer olmadığını unutmamak gerekir. Doodle'larımızla belirli kişileri ve olayları kutlamak, bunu da en iyi sanat eserlerini ve çağırabileceğimiz en iyi teknolojileri kullanarak yapmak istiyoruz. Ancak teknoloji olsun diye asla teknolojiyi övüyoruz. Bu, genel olarak bilinen HTML5'in kullanılabilir olan herhangi bir bölümünün dikkatli bir şekilde incelenmesi ve bu bölümün, dikkati dağıtmadan veya gölgede bırakmadan doodle'ı daha iyi hale getirmemize yardımcı olup olmadığına bakmak anlamına gelir.

Şimdi, yerini Stanisław Lem doodle'ında bulan ve bilmeyen modern Web teknolojilerinin üzerinden geçelim.

DOM ve tuval aracılığıyla grafikler

Canvas güçlü bir araçtır ve tam da bu doodle'da yapmak istediğimiz türden özelliklere uygun olarak üretilmiştir. Ancak, önemsediğimiz eski tarayıcıların bazıları bunu desteklemedi. Normalde mükemmel bir excanvas derleyen kişiyle aynı ofisi paylaşıyor olsam da, farklı bir yol seçmeye karar verdim.

"Rects" (rectler) adı verilen temel grafik öğeleri soyutlayan bir grafik motoru oluşturdum ve tuval yoksa bu öğeleri tuval (DOM) kullanarak oluşturuyorum.

Bu yaklaşım bazı ilginç zorlukları beraberinde getirir. Örneğin, DOM'deki bir nesneyi taşımak veya değiştirmek hemen sonuçlar getirirken tuval için her şeyin aynı anda çizildiği belirli bir an vardır. (Yalnızca bir tuval almaya karar verdim. Bunu temizleyip her karede çiziklerden çizmeye karar verdim. Bir tarafta çok fazla, çok sayıda hareketli parça var.

Ne yazık ki tuvale geçiş, CSS arka planlarını drawImage() ile yansıtmak kadar basit değildir: DOM aracılığıyla bir şeyleri bir araya getirirken ücretsiz sunulan birçok şeyi kaybedersiniz. En önemlisi, z-endeksleri ve fare etkinlikleriyle katman oluşturmaktır.

Z-endeksini "uçaklar" kavramıyla zaten soyutlamıştım. Doodle, gökyüzünden çok gerideki gökyüzünden her şeyin önündeki fare işaretçisine kadar bir dizi düzlem tanımlamıştı ve doodle'ın içindeki tüm aktörlerin hangisine ait olduğuna karar vermesi zorundaydı (planeCorrection kullanılarak, düzlemde küçük artı/eksi düzeltmeleri yapılabilirdi).

DOM aracılığıyla oluşturulan düzlemler, Z-endeksine dönüştürülür. Ancak tuval aracılığıyla görsel oluşturursak dikdörtgenleri çizmeden önce düzlemlerine göre sıralamamız gerekir. Bunu her defasında yapmak maliyetli olduğundan, sipariş yalnızca bir aktör eklendiğinde veya başka bir düzleme hareket ettiğinde yeniden hesaplanır.

Fare etkinlikleri için bunu da soyutladım... bir şekilde. Hem DOM hem de tuval için yüksek Z-endeksine sahip, tamamen şeffaf ek DOM öğeleri kullandım. Bunların işlevi yalnızca fare ile üzerine gelme, tıklamalar ve dokunmalara tepki vermekti.

Bu doodle ile denemek istediğimiz şeylerden biri dördüncü duvarı yıkmaktı. Yukarıdaki motor, tuval tabanlı aktörleri DOM tabanlı aktörlerle birleştirmemizi sağladı. Örneğin, sondaki patlamalar hem evrendeki nesneler için tuvalde, hem de Google ana sayfasının geri kalanında DOM'de gösteriliyor. Normalde etrafta uçan ve diğer oyuncular gibi pürüzlü maskemizle saplanan kuş, çekim aşamasında sorun yaşamamak için karar veriyor ve Kendimi Şanslı Hissediyorum düğmesine basıyor. Bu, kuşun zemini terk edip DOM öğesi haline getirmesi (veya bunun tersi) için yapılıyor. Bu durumun ziyaretçilerimize karşı tamamen şeffaf olmasını umuyorum.

Kare hızı

Geçerli kare hızını bilmek ve çok yavaş (ve çok hızlı!) olduğunda onlara tepki vermek motorumuzun önemli bir parçasıydı. Tarayıcılar kare hızını bildirmediğinden kare hızını kendimiz hesaplamamız gerekir.

requestAnimationFrame kullanarak başladım, kullanılabilir olmadığında eski moda setTimeout yöntemine geri dönüyorum. requestAnimationFrame, bazı durumlarda CPU'yu zekice kurtarıyor. Aşağıda açıklandığı gibi, bunların bir kısmını kendimiz de biz yapıyoruz. Ancak aynı zamanda setTimeout ile daha yüksek bir kare hızı elde edebiliyoruz.

Geçerli kare hızını hesaplamak basittir ancak önemli değişikliklere tabidir. Örneğin, başka bir uygulama bilgisayarı bir süre boyunca kullandığında bu hız hızla düşebilir. Bu nedenle, yalnızca her 100 fiziksel işaretlemede "kayan" (ortalama) bir kare hızı hesaplar ve kararlarımızı buna göre alırız.

Ne tür kararlar?

  • Kare hızı 60 fps'den yüksekse hızı kısıtlarız. Şu anda requestAnimationFrame ürününün bazı Firefox sürümlerinde kare hızı üzerinde herhangi bir üst sınır yoktur ve CPU'yu boşa harcamanın bir anlamı yoktur. Diğer tarayıcılarda kare hızını 60 fps'den biraz daha yüksek yapan yuvarlama hataları nedeniyle aslında 65 fps'ye sınırladığımızı unutmayın. Yanlışlıkla bunu kısıtlamaya başlamak istemeyiz.

  • Kare hızı 10 fps'nin altındaysa, kareleri bırakmak yerine sadece motoru yavaşlatırız. Bu bir kaybetmeme teklifi ama kareleri aşırı miktarda atlamanın daha yavaş (ama yine de tutarlı) bir oyuna sahip olmaktan daha kafa karıştırıcı olacağını hissettim. Bunun bir başka güzel yan etkisi de var: Sistem geçici olarak yavaşlarsa, motor çaresizce hızına yetişirken kullanıcı, tuhaf bir ilerlemeyle karşılaşmaz. (Pac-Man için bunu biraz farklı yaptım, ama minimum kare hızı daha iyi bir yaklaşım.)

  • Son olarak, kare hızı tehlikeli bir şekilde düştüğünde grafikleri basitleştirmeyi düşünebiliriz. Bunu Lem doodle'ı için yapmayız (fare işaretçisi hariç (aşağıda bununla ilgili daha fazla bilgi verilmiştir)), ancak varsayımsal olarak, yavaş bilgisayarlarda bile doodle'ın akıcı görünmesini sağlayacak şekilde bazı yabancı animasyonları kaybedebiliriz.

Ayrıca, fiziksel onay ve mantıksal onay seçenekleri de sunuyoruz. İlki requestAnimationFrame/setTimeout üzerinden geliyor. Normal oyundaki oran 1:1'dir, ancak ileri sarma için fiziksel onay işareti başına (1:5'e kadar) sadece daha fazla mantıksal onay işareti ekleriz. Bu, her mantıksal onay için gerekli tüm hesaplamaları yapmamızı sağlar, ancak ekrandaki şeyleri güncelleyen yalnızca sonuncuyu belirlememizi sağlar.

Karşılaştırma

Tuvalin, kullanılabilir olduğunda DOM'den daha hızlı olacağı varsayımında bulunulabilir (ve başlangıçta, bu kabul edilmiştir). Bu her zaman geçerli değildir. Test sırasında, DOM öğelerini taşırken Mac'te Opera 10.0–10.1 ve Linux'ta Firefox'un daha hızlı olduğunu tespit ettik.

Kusursuz dünyada doodle sessizce farklı grafik tekniklerini karşılaştırır: DOM öğeleri style.left ve style.top kullanılarak hareket etti, tuval üzerine çizim yaptı ve hatta CSS3 dönüşümleri kullanılarak DOM öğeleri hareket ettirildi

ve ardından en yüksek kare hızını sağlayan seçeneğe geçiş yapın. Bunun için kod yazmaya başladım, ama en azından kullandığım karşılaştırma yönteminin pek güvenilmez olduğunu ve çok fazla zaman gerektirdiğini öğrendim. Ana sayfamızda bulunmayan bir zaman. Hıza çok önem veriyoruz ve doodle'ın anında görünmesini ve oyunun bir düğmeye bastığınızda veya dokunduğunuzda başlamasını istiyoruz.

Sonunda, web geliştirme bazen yapmanız gerekeni yapma zorunluluğu olarak ortaya çıkar. Kimsenin bakmadığından emin olmak için omzumun arkasına baktım ve ardından Opera 10'u ve Firefox'u tuval dışına sabit olarak kodladım. Gelecekte <marquee> etiketi olarak döneceğim.

CPU korunuyor

Evine gelen bir arkadaşınız Breaking Bad'in sezon finalini izliyor, oyunu sizin için bozuyor ve sonra DVR'dan siliyor mu? Öyle biri olmak istemezsin, değil mi?

Yani evet, gelmiş geçmiş en kötü benzetme. Ancak doodle'ımızın da böyle bir kişi olmasını istemiyoruz. Birinin tarayıcı sekmesine erişim iznimiz bir ayrıcalıktır ve CPU döngülerini biriktirmek veya kullanıcının dikkatini dağıtmak bizi rahatsız eder. Bu nedenle, doodle'la oynayan kimse olmazsa (dokunma, tıklama, fare hareketi veya tuşa basma olmadan) doodle'ın en sonunda uyku moduna geçmesini isteriz.

Ne zaman?

  • Ana sayfada 18 saniye geçtikten sonra (arcade oyunlarında buna ilgi çekme modu denir)
  • sekmeye odaklanılmışsa 180 saniye sonra
  • Sekmede odak yoksa (ör. kullanıcı başka bir pencereye geçmiş olsa da doodle'ı şu anda etkin olmayan bir sekmede izlemeye devam ediyor olabilir) 30 saniye sonra
  • Sekme görünmez olursa (ör. kullanıcı aynı pencerede başka bir sekmeye geçerse) hemen

Sekmenin şu anda odaklandığını nasıl anlarız? Kendimizi window.focus ve window.blur öğelerine bağlıyoruz. Sekmenin görünür olduğunu nereden bilebiliriz? Yeni Page Görünürlük API'sını kullanıyor ve uygun etkinliğe tepki veriyoruz.

Yukarıda belirtilen zaman aşımları, bizim için her zamankinden daha affedici olabilir. Bu doodle'ı, ortam animasyonu (esas olarak gökyüzü ve kuş) içeren bu özel doodle'a uyarladım. İdeal olan, molaların oyun içi etkileşime bağlı olmasıdır. Örneğin, inişin hemen ardından kuş doodle'a şimdi uykuya dalabileceğini bildirebiliyordu, ama sonunda bunu uygulamadım.

Gökyüzü her zaman hareket halinde olduğundan, uykuya dalarken veya uyanırken doodle yalnızca durmadan veya başlamaz. Durmadan önce yavaşlar. Gerektiğinde fiziksel bir işaret başına mantıksal tıklama sayısını devam etmek, artırmak veya azaltmak için de tam tersi olur.

Geçişler, dönüşümler, olaylar

HTML'nin güçlü yönlerinden biri her zaman, onu daha iyi hale getirebilmenizdir: HTML ve CSS'nin normal portföyünde yeterince iyi olmayan bir şey olursa, onu genişletmek için JavaScript'le hazırlayabilirsiniz. Ne yazık ki bu çoğu zaman sıfırdan başlamak anlamına geliyor. CSS3 geçişleri harikadır, ancak yeni bir geçiş türü ekleyemez veya stil öğeleri dışında başka bir şey yapmak için geçişler kullanamazsınız. Başka bir örnek: CSS3 dönüşümleri DOM için idealdir ancak tuvale geçtiğinizde aniden kendiniz olursunuz.

Bu sorunlar ve daha fazlası, Lem doodle'ın kendi geçiş ve dönüşüm motorunun olmasının nedenidir. Evet, 2000'lerin adı gibi. Geliştirdiğim özellikler CSS3 kadar güçlü olmasa da motor ne olursa olsun tutarlı bir şekilde çalışıyor ve bize çok daha fazla kontrol sağlıyor.

Basit bir işlem (etkinlik) sistemi ile başladım. Herhangi bir noktada doodle zamanı daha hızlı hale geldikçe (hızlı ileri sarma), yavaşladıkça (daha düşük kare hızı veya CPU'dan tasarruf etmek için uykuya dalma) ya da tamamen durduğunda (resimlerin yüklenmesinin bitmesini beklerken) durduğundan, gelecekte setTimeout kullanmadan etkinlikleri tetikleyecek bir zaman çizelgesi kullanmaya başladım.

Geçişler de bir başka işlem türüdür. Temel hareketlere ve döndürmeye ek olarak, göreli hareketleri (ör. bir şeyi 10 piksel sağa taşıma), titreme gibi özel şeyleri ve ayrıca animasyon karesi resim animasyonlarını da destekleriz.

Döndürmelerden bahsettim, bunlar da manuel olarak yapılıyor: Döndürülmesi gereken nesneler için çeşitli açılar için imgelerimiz var. Bunun başlıca nedeni, hem CSS3 hem de tuval rotasyonlarının kabul edilemez bulduğumuz görsel yapılar sağlamasıydı. Ayrıca, bu eserler platforma göre değişiyordu.

Dönen bazı nesnelerin diğer dönen nesnelere bağlı olduğundan (örneğin, dönen bir üst kola bağlı olan alt kola bağlı bir robot eli olabilir) bu durum, fakir bir adamın dönme başlangıç noktasını da dönme şeklinde oluşturmamız gerektiği anlamına geliyordu.

Tüm bunlar, nihayetinde HTML5'in ele aldığı zemini kapatan sağlam bir çalışma. Ancak bazen yerel destek yeterince iyi olmayabilir ve tekerleği yeniden keşfetmenin zamanı geldi.

Resimler ve sprite görsellerle başa çıkma

Motor yalnızca doodle'ı çalıştırmak için değil, aynı zamanda doodle üzerinde çalışmak için de kullanılabilir. Bazı hata ayıklama parametrelerini yukarıda paylaştım: Diğerlerini engine.readDebugParams bağlantısında bulabilirsiniz.

Birleştirme, doodle'lar için de kullandığımız iyi bilinen bir tekniktir. Bayt tasarruf etmemizi ve yükleme sürelerini kısaltmamızı sağlıyor. Ayrıca, önceden yüklemeyi daha kolay hale getiriyor. Ancak bu, geliştirmeyi de zorlaştırır. Görüntülerde yapılan her değişiklik, yeniden birleştirmeyi gerektirir (büyük ölçüde otomatikleştirilmiş ancak yine de kullanışsızdır). Bu nedenle motor, geliştirme için ham görüntülerde ve engine.useSprites aracılığıyla üretim için sprite görsellerde çalışmayı destekler. Her ikisi de kaynak koduna dahil edilir.

Pac-Man doodle&#39;ı
Pac-Man doodle'ının kullandığı spriler.

Devam ederken resimlerin önceden yüklenmesini ve zamanında yüklenmezse doodle'ı durdurmayı da destekliyoruz. Bir sahte ilerleme çubuğuyla tamamlandı! (Faks çünkü maalesef HTML5 bile bir resim dosyasının ne kadarının yüklendiğini bize bildiremez.)

Düzenlenmiş ilerleme çubuğunun yer aldığı bir grafik yükleme ekran görüntüsü.
Düzenlenmiş ilerleme çubuğunun yer aldığı bir grafik yükleme ekran görüntüsü.

Bazı sahnelerde, paralel bağlantılar kullanarak yüklemeyi hızlandırmak için birden fazla imge kullanırız. Bunun nedeni sadece iOS'ta resimler için 3/5 milyon piksel sınırlaması olmasıdır.

Tüm bunlarda HTML5 nasıl bir rol oynar? Yukarıda bununla ilgili pek fazla söz yok ama birleştirme/kırpma işlemi için yazdığım araç tümüyle yeni Web teknolojisiydi: tuval, blob'lar, a[indirin]. HTML ile ilgili heyecan verici noktalardan biri, daha önce tarayıcının dışında yapılması gerekenleri yavaş yavaş dahil etmesidir. İhtiyacımız olan tek şey PNG dosyalarını optimize etmekti.

Maçlar arasında durum kaydediliyor

Lem'in dünyaları her zaman büyük, canlı ve gerçekçiydi. Hikayeleri genelde açıklama açısından fazla uzun sürmez, ilk sayfa medya çözünürlüğünde başlıyor ve okuyucunun aradığı yolu bulması gerekiyor.

Cyberiad için de durum farklı değildi ve bu duyguyu doodle'da da yansıtmak istedik. İlk olarak hikayeyi çok fazla açıklamamaya çalışırız. Bir diğer büyük bölüm de rastgeleleştirmedir. Kitap evreninin mekanik doğasına uygun olduğunu düşündüğümüz rastgeleleştirmedir; pek çok yerde kullandığımız ve rastgelelikle çalışan bir dizi yardımcı fonksiyona sahibiz.

Tekrar oynanabilirliği başka şekillerde de artırmak istiyorduk. Bunun için, doodle'ın daha önce kaç defa bittiğini bilmemiz gerekiyordu. Buna tarihsel açıdan doğru olan teknolojik çözüm çerezdir ancak bu, Google ana sayfasında işe yaramaz. Her çerez, her sayfanın yükünü artırır. Hız ve gecikmeyi de çok önemsiyoruz.

Neyse ki HTML5 bize, önemsiz olan Web Depolama olanağı sunuyor. Bu sayede, genel oynatma sayısını ve kullanıcının oynadığı son sahneyi kaydedip hatırlıyoruz. Böylece, çerezlerin hiç olmadığı kadar incelikli bir şekilde kullanılmış oluyor.

Bu bilgileri nasıl kullanırız?

  • Kullanıcının daha önce gördüğü ara sahneleri sıkıştırmayı sağlayan ileri sarma düğmesini gösteriyoruz.
  • final sırasında farklı N öğe gösteririz
  • atış seviyesinin zorluğunu biraz artırırız
  • üçüncü ve sonraki oyunlarınızda farklı bir hikayede anlatılan, küçük bir paskalya yumurtası olası ejderha gösteriyoruz

Bunu kontrol eden birkaç hata ayıklama parametresi vardır:

  • ?doodle-debug&doodle-first-run – İlk koşunuzmuş gibi davranın
  • ?doodle-debug&doodle-second-run – ikinci koşuyu yapmış gibi düşünün
  • ?doodle-debug&doodle-old-run – Eski bir koşumuş gibi düşünün

Dokunmatik cihazlar

Doodle'ın dokunmatik cihazlarda kendini rahat hissetmesini istedik. En modern olanlar, doodle'ın gerçekten iyi çalışması için yeterince güçlüdür. Oyunu dokunarak deneyimlemek, tıklamadan çok daha eğlencelidir.

Kullanıcı deneyiminde önceden bazı değişikliklerin yapılması gerekiyordu. Başlangıçta, fare işaretçimiz bir ara sahneyle/etkileşimsiz bir bölümle ilgili bilgi veren tek yerdi. Daha sonra sağ alt köşeye küçük bir gösterge ekledik, böylece sadece fare işaretçisine güvenmek zorunda kalmadık (dokunmatik cihazlarda mevcut olmadıklarından dolayı).

Normal Meşgul Tıklanabilir Tıklandı
Devam eden işler
Devam eden işler normal işaretçi
Devam eden işler meşgul işaretçisi
Devam eden iş tıklanabilir işaretçi
Devam eden çalışma tıklama işaretçisi
Son
Normal son işaretçiv
Son meşgul işaretçisi
Son tıklanabilir işaretçi
Son tıklanan işaretçi
Geliştirme sırasında fare işaretçileri ve son eşdeğerleri.

Çoğu şey alışılmışın dışındaydı. Ancak, dokunma deneyimimizin önceden tasarlanmamış hızlı kullanılabilirlik testleri iki sorun gösterdi: Hedeflerden bazılarına basmak çok zordu ve fare tıklaması etkinliklerini yalnızca geçersiz kıldığımız için hızlı dokunmalar yok sayıldı.

Tıklanabilir şeffaf DOM öğelerinin ayrı olması, bunları görsellerden bağımsız olarak yeniden boyutlandırabildiğim için çok yardımcı oldu. Dokunmatik cihazlar için ekstra 15 piksellik dolgu kullandım ve tıklanabilir öğeler oluşturulduğunda bunu kullandım. (Mr. Fitts'i mutlu etmek amacıyla, fare ortamları için de 5 piksellik dolgu ekledim.)

Diğer sorunda da, fare tıklamasına güvenmek yerine, uygun dokunma başlangıç ve bitiş işleyicilerini ekleyip test etmeyi başardım.

Ayrıca, WebKit tarayıcılarının varsayılan olarak eklediği bazı dokunma özelliklerini (vurgulama, açıklama metnine dokunma) kaldırmak için daha modern stil özellikleri de kullanıyoruz.

Doodle çalıştıran belirli bir cihazın dokunmayı destekleyip desteklemediğini nasıl saptarız? Tembel bir şekilde. İlk temas başlatma etkinliğini ele almamızdan sonra, cihazın dokunmayı desteklediğinden çıkarım yapmak için, bunu bir öncelik olarak belirlemek yerine birleşik IQ'larımızı kullandık.

Fare işaretçisini özelleştirme

Ancak her şey dokunmatik değildir. Yol gösterici ilkelerimizden biri, doodle'ın evrenine olabildiğince çok şey yerleştirmekti. Küçük kenar çubuğu kullanıcı arayüzü (hızlı ileri sarma, soru işareti), ipucu ve hatta evet, fare işaretçisi.

Fare işaretçisi nasıl özelleştirilir? Bazı tarayıcılar, ısmarlama bir resim dosyasına bağlantı vererek fare imlecinin değiştirilmesine izin verir. Ancak bu, iyi bir şekilde desteklenmez ve biraz kısıtlayıcıdır.

Bu değilse ne olacak? Neden bir fare işaretçisini doodle'daki başka bir aktör oluşturmaya ne dersiniz? Bu yöntem işe yarıyor, ancak dikkat edilmesi gereken bazı noktalar var:

  • yerel fare işaretçisini kaldırabilmeniz gerekir
  • fare işaretçinizi "gerçek" fareyle senkronize etme konusunda epey başarılı olmanız gerekir.

İlki karmaşıktır. CSS3, cursor: none öğesine izin verir, ancak bazı tarayıcılarda desteklenmez. Bazı jimnastik programlarına başvurmamız gerekiyordu: Yedek olarak boş .cur dosyası kullanmak, bazı tarayıcılar için somut bir davranış belirtmek, hatta diğerlerini de deneyimin dışında tutmak.

Diğeri ise göreceli olarak önemsizdir. Ancak fare işaretçisi, doodle evreninin yalnızca başka bir parçası olduğundan, tüm sorunlarını da devralır. Hangisi en büyük? Doodle'ın kare hızı düşükse fare işaretçisinin kare hızı da düşük olur. Bu da elinizin doğal bir uzantısı olan fare işaretçisinin ne olursa olsun yanıt verdiğini hissetmesi gerektiğinden bunun ciddi sonuçları olacaktır. (Önceden Commodore Amiga'yı kullanmış olanlar, artık güçlü bir şekilde başını sallıyor.)

Bu sorunun biraz karmaşık çözümlerinden biri, fare işaretçisini normal güncelleme döngüsünden ayırmaktır. Tam da bunu uyumak zorunda olmadığım alternatif bir evrende yaptık. Bunun için daha basit bir çözüm mü var? Yuvarlanan kare hızı 20 fps'nin altına düşerse yerel fare işaretçisine geri dönebiliriz. (Yani kayan kare hızı tam da bu noktada fayda sağlar. Mevcut kare hızına tepki gösterseydik ve bu hareket 20 fps civarında titreşirse kullanıcı özel fare işaretçisinin sürekli gizlenip gösterildiğini görür.) Bu da bizi şu konuma getirir:

Kare hızı aralığı Davranış
>10fps Daha fazla karenin düşmemesi için oyunu yavaşlatın.
10-20 fps Özel fare işaretçisi yerine yerel fare işaretçisi kullanın.
20-60 fps Normal çalışma.
>60fps Kare hızının bu değeri aşmaması için hızlandırın.
Kare hızına bağlı davranışın özeti.

Ayrıca, fare işaretçimiz Mac'te koyu, PC'de beyazdır. Bunun sebebi nedir? Çünkü platform savaşları kurgusal evrenlerde bile yakıta ihtiyaç duyar.

Sonuç

Bu mükemmel bir motor değil ama mükemmel bir motor gibi durmuyor. Lem doodle'ıyla birlikte geliştirildi ve doodle'a özel. Tamam, tamam. Don Knuth'un söylediği gibi, "erken optimizasyon tüm kötülüklerin köküdür," diyor ve ben öncelikle bir motoru tek başına yazmanın değil, daha sonra uygulanmasının mantıklı olduğuna inanıyorum. Uygulama, teoriyi en az teorik bilgiler sağladığı kadar bilgilendirir. Benim durumumda kod atıldı, birkaç parça tekrar tekrar yazıldı ve birçok yaygın parça yanlışlıkla değil de yayımlandı. Ama nihayetinde burada olan şey, istediğimiz şeyi yapmamızı sağladı: Stanisław Lem'in kariyerini ve Daniel Mróz'un çizimlerini aklımıza gelen en iyi şekilde kutladık.

Umarım yukarıdakiler, yapmamız gereken bazı tasarım seçimleri ile ödünleşimlere ve HTML5'i belirli bir gerçek hayat senaryosunda nasıl kullandığımıza ışık tutar. Şimdi kaynak koduyla oynayın, deneyin ve düşüncelerinizi bizimle paylaşın.

Bunu ben de yaptım. Aşağıdaki reklam, son birkaç gün içinde canlı yayındaydı, Lem doodle'ının görüldüğü ilk saat dilimi olan Rusya'da 23 Kasım 2011'in erken saatlerine kadar geri sayım yapıyorum. Belki şapşal bir şey ama tıpkı doodle'larda olduğu gibi, önemsiz görünen şeylerin bazen daha derin bir anlamı vardır. Bu sayaç, motor için gerçekten güzel bir "stres testi"ydi.

Lem doodle&#39;ının evrende geri sayım saatinin ekran görüntüsü.
Lem doodle'ının evrende geri sayım saatinin ekran görüntüsü.

Bu, bir Google doodle'ının yaşamına bakmanın bir yolu. Aylarca süren çalışma, haftalarca test etme, 48 saat boyunca hazırlama süresi ve bunların hepsi insanların beş dakika oynadığı bir şey için. Bu binlerce JavaScript satırının her biri, bu 5 dakikanın geçirilen zamanı geçirmesini umuyor. Afiyet olsun.