Roll It, klasik bir sahil oyunu olan "topu yuvarla"yı yalnızca telefonunuzdaki ve bilgisayarınızdaki tarayıcıda oynayabileceğiniz bir Chrome denemesidir. Telefonunuzdaki tarayıcı, bileğinizi bir hareketle topu nişan almanıza ve atmanıza olanak tanır. Bilgisayarınızdaki tarayıcı ise WebGL ve Canvas ile Roll It salonunun gerçek zamanlı grafiklerini oluşturur. İki cihaz, Websocket'ler aracılığıyla iletişim kurar. Uygulama yok. İndirmeye gerek yok. Jeton yok. Tek ihtiyacınız olan modern bir tarayıcıdır.
Google Creative Lab'in yönlendirmesiyle Legwork, kullanıcı deneyimini, arayüzleri ve oyun ortamını geliştirdi. Ardından, Roll It'i oluşturmak için geliştirme iş ortağı Mode Set ile birlikte çalıştı. Projenin süresi boyunca birçok benzersiz zorlukla karşılaştık. Bu makalede, Roll It'i hayata geçirirken kullandığımız tekniklerden, keşfettiğimiz püf noktalarından ve aldığımız derslerden bazıları ele alınmaktadır.
3D iş akışı
Başlangıçta karşılaştığımız zorluklardan biri, yazılımımızdaki 3D modelleri web'e hazır bir dosya biçimine dönüştürmenin en iyi yolunu bulmaktı. Öğeler Cinema 4D'de oluşturulduktan sonra modeller basitleştirildi ve düşük poligonlu ağlara dönüştürüldü. Her bir ağa, boyama ve doku oluşturma için nesnenin bölümlerini birbirinden ayırt etmek üzere belirli poligon seçim etiketleri verildi. Ardından, three.js ile uyumlu dosyalar oluşturmak için Collada 1.5 (.dae) dosyası olarak dışa aktarıp açık kaynak bir 3D program olan Blender'a aktarabildik. Modellerimizin doğru şekilde içe aktarıldığından emin olduktan sonra örgüyü JSON dosyası olarak dışa aktardık ve ışıklandırma kod kullanılarak uygulandı. Attığımız adımlara daha ayrıntılı bir göz atalım:
Kodu yazma
Roll It, açık kaynak kitaplıklarıyla geliştirildi ve modern tarayıcılarda yerel olarak çalışır. WebGL ve WebSocket gibi teknolojiler sayesinde web, konsol kalitesinde oyun ve multimedya deneyimlerine yaklaşıyor. HTML geliştirme için daha modern araçlar kullanıma sunulduğundan, geliştiricilerin bu deneyimleri oluşturma konusundaki kolaylık ve rahatlık büyük ölçüde arttı.
Geliştirme ortamı
Roll It'in orijinal kodunun çoğu, iyi biçimlendirilmiş ve lintlenmiş JavaScript'e aktarılan temiz ve kısa bir dil olan CoffeeScript ile yazılmıştır. CoffeeScript, mükemmel kalıtım modeli ve daha net kapsam yönetimiyle OOP geliştirmede öne çıkar. CSS, geliştiricinin projenin stil sayfalarını geliştirmek ve yönetmek için kullanabileceği birçok harika araç sunan SASS çerçevesiyle yazılmıştır. Bu sistemleri derleme sürecine eklemek biraz zaman alır ancak özellikle Roll It gibi daha büyük bir proje için bu çabaya kesinlikle değer. Geliştirme sırasında öğelerimizi otomatik olarak derlemek için bir Ruby on Rails sunucusu oluşturduk. Böylece tüm bu derleme adımları şeffaf hale geldi.
Kolay ve rahat bir kodlama ortamı oluşturmanın yanı sıra, sitenin daha hızlı yüklenmesini sağlamak için istekleri en aza indirmek amacıyla öğeleri manuel olarak optimize ettik. Her resmi ImageOptim ve ImageAlpha adlı iki sıkıştırma programından geçirdik. Her program, resimleri sırasıyla kayıpsız ve kayıplı olarak kendi yöntemiyle optimize eder. Doğru ayar kombinasyonuyla, bir resmin dosya boyutunu önemli ölçüde azaltabilirler. Bu, harici resimler yüklenirken bant genişliğinden tasarruf etmenizi sağlamaz. Ayrıca, optimize edilen resimleriniz HTML, CSS ve JavaScript'e satır içi olarak yerleştirilmek üzere çok daha küçük base64 kodlu dizelere dönüştürülür. Base64 kodlama konusunda, Open Sans WOFF ve SVG yazı tipi dosyalarımızı da bu tekniği kullanarak doğrudan CSS'ye yerleştirdik. Bu da toplam istek sayısını daha da azalttı.
Fizik destekli 3D sahne
THREE.js, web için her yerde bulunan 3D JavaScript kitaplığıdır. Basit kullanıcıların özel gölgelendirici yazmak veya manuel matris dönüşümleri gerçekleştirmek zorunda kalmadan iyi aydınlatılmış ve güzel etkileşimli 3D sahneler oluşturmasını sağlayan düşük düzey 3D matematik ve donanım tabanlı WebGL optimizasyonlarını bir araya getirir. Physijs, JavaScript'e çevrilmiş popüler bir C++ fizik kitaplığı için THREE.js'ye özel bir sarmalayıcıdır. Topun hedefe doğru yuvarlanmasını, zıplamasını ve sıçramasını 3D olarak simüle etmek için bu kitaplıktan yararlandık.
Başından itibaren, yalnızca topu yuvarlama deneyimini gerçekçi hale getirmekle kalmayıp oyundaki nesnelerin de gerçekçi olmasını sağlamaya çalıştık. Bu, Physijs sahnesinin genel yerçekimini, oyuncunun attığı top yuvarlanırken topun hızını, koridorun zıplamasının eğimini ve topun ve koridor malzemelerinin sürtünme ve geri tepme (sıçrama) özelliklerini ayarlamak için birçok iterasyon gerektiriyordu. Daha fazla yerçekimi ve daha fazla hız, daha gerçekçi bir oyun deneyimi sağladı.
Düzleştirme
Modern tarayıcı ve video kartı kombinasyonlarının çoğu, WebGL ortamında doğal donanım tabanlı kenar yumuşatma özelliğinden yararlanır ancak bazı kombinasyonlar bu özelliği desteklemez. Kenar yumuşatma doğal olarak çalışmıyorsa THREE.js sahnesindeki sert ve kontrastlı kenarlar sivri ve çirkin görünür (en azından bizim hassas gözlerimiz için).
Neyse ki bu sorunu düzeltmek için bir yöntemimiz var: Platformun doğal olarak kenar yumuşatmayı destekleyip desteklemediğini bir kod snippet'i aracılığıyla algılayabiliriz. Bu durumda, işe başlayabiliriz. Aksi takdirde, THREE.js ile birlikte gelen ve bize yardımcı olabilecek bir dizi son işleme gölgelendiricisi vardır. FXAA anti-aliasing filtresi. Oluşturulan sahneyi her karede bu gölgelendiriciyle yeniden çizerek genellikle çizgilerimiz ve kenarlarımız çok daha pürüzsüz bir görünüme kavuşur. Aşağıdaki demoya bakın:
// Check for native platform antialias support via the THREE renderer
// from: http://codeflow.org/entries/2013/feb/22/how-to-write-portable-webgl/#antialiasing
var nativeAntialiasSupport = (renderer.context.getParameter(renderer.context.SAMPLES) == 0) ? false : true;
İvmeölçer tabanlı oyun kontrolleri
Roll It'in büyüsünün çoğu, oyuncunun telefonla yaptığı top yuvarlama hareketinden gelir. Mobil cihazlar bir süredir tarayıcıdaki ivme ölçere erişebiliyor ancak sektör olarak web'de harekete dayalı hareket tanıma özelliğini yeni yeni keşfetmeye başladık. Telefonun ivmeölçerinin sağladığı verilerle biraz sınırlıyız ancak biraz yaratıcılıkla harika yeni deneyimler sunabiliriz.
Roll It'in ana "yuvarlama" hareketini algılama işlemi, pencerenin deviceorientation
etkinliğinden gelen en son 10 ivmeölçer güncellemesini izlemeyle başlar. Önceki eğim değerini mevcut eğim değerinden çıkararak etkinlikler arasındaki açı farkını depolarız. Ardından, son on açı farkı değerini sürekli olarak toplayarak telefon uzayda hareket ederken sürekli dönmeyi algılayabiliriz. Telefon, tarama açısı değişikliği eşiğini geçtiğinde bir yuvarlanma tetikliyoruz. Ardından, bu taramada en büyük tek eğim deltasını bularak topun hızını tahmin edebiliriz. Roll It'te bu hız, her bir hızlandırıcı güncellemesine eklediğimiz zaman damgalarını kullanarak normalleştirilir. Bu, farklı cihazlarda ivmeölçer güncellemelerinin tarayıcıya aktarıldığı değişken hızı düzeltmeye yardımcı olur.
WebSocket iletişimi
Oyuncu topu telefonla yuvarladıktan sonra telefondan dizüstü bilgisayara topu fırlatmasını söyleyen bir mesaj gönderilir. Bu "roll" mesajı, iki makine arasındaki WebSocket bağlantısı üzerinden bir JSON veri nesnesi aracılığıyla gönderilir. JSON verileri küçüktür ve temel olarak mesaj türü, atış hızı ve nişan alma yönünden oluşur.
{
"type": "device:ball-thrown",
"speed": 0.5,
"aim": 0.1
}
Dizüstü bilgisayar ile telefon arasındaki tüm iletişim, bu gibi küçük JSON mesajları aracılığıyla gerçekleşir. Oyun masaüstünde durumunu her güncellediğinde veya kullanıcı telefonda bir düğmeyi eğiştiğinde ya da düğmeye dokunduğunda makineler arasında bir WebSocket mesajı iletilir. Bu iletişimin basit ve kolay yönetilebilir kalması için WebSocket mesajları, her iki tarayıcıdan da tek bir çıkış noktası kullanılarak yayınlanır. Buna karşılık, alıcı tarayıcıda tek bir giriş noktası vardır ve her iki uçtaki tüm gelen ve giden mesajlar tek bir WebSocket nesnesi tarafından işlenir. Bir WebSocket mesajı alındığında JSON verileri, jQuery'nin trigger()
yöntemi kullanılarak JavaScript uygulamasında yeniden yayınlanır. Bu noktada, gelen veriler diğer tüm özel DOM etkinlikleri gibi davranır ve uygulamadaki diğer nesneler tarafından alınıp işlenebilir.
var websocket = new WebSocket(serverIPAddress);
// rebroadcast incoming WebSocket messages with a global event via jQuery
websocket.onmessage = function(e) {
if (e.data) {
var obj = JSON.parse(e.data);
$(document).trigger(data.type, obj);
}
};
// broadcast outgoing WebSocket messages by passing in a native .js object
var broadcast = function(obj) {
websocket.send(JSON.stringify(obj));
};
Roll It'in WebSocket sunucuları, iki cihaz bir oyun koduyla senkronize edildiğinde anında oluşturulur. Roll It'in arka ucu, Go kullanılarak Google Compute Engine ve App Engine platformunda oluşturuldu.
Ekranı eğme menüsü
Oyun sırasında kullanılan olaya dayalı WebSocket mesajlarının yanı sıra Roll It'teki menüler, telefonu yatırarak ve bir düğmeye dokunarak seçim yapmak için kontrol edilir. Bunun için telefondan dizüstü bilgisayara daha tutarlı bir eğim verisi akışı aktarılması gerekir. Bant genişliğini azaltmak ve gereksiz güncelleme göndermekten kaçınmak için bu mesajlar yalnızca cihazın eğimi birkaç dereceden fazla değişirse gönderilir. Telefon masanın üzerinde düz bir şekilde duruyorsa eğim verisi akışı göndermenin bir anlamı yoktur. Aktarım hızı da sınırlandırılır. Cihaz aktif olarak eğiliyorsa bile Roll It'te saniyede en fazla 15 WebSockets mesajı gönderilir.
Eğim değerleri bilgisayarda alındıktan sonra, pürüzsüz bir deneyim sunmak için requestAnimationFrame
kullanılarak zaman içinde ara değerlerle doldurulur. Sonuç olarak, dönen bir menü ve kullanıcının seçimini belirtmeye yardımcı olmak için yuvarlanan bir top elde edersiniz. Telefon eğim verilerini gönderirken bu DOM öğeleri, requestAnimationFrame
döngüsü içinde bir CSS dönüşümü yeniden hesaplanarak gerçek zamanlı olarak güncellenir. Menünün kapsayıcısı dönüyor ancak top zeminde yuvarlanıyor. Bu efekti elde etmek için topların x koordinatını rotasyonuyla ilişkilendirmek üzere bazı temel trigonometri işlemleri uygularız. Basit denklem: rotasyon sayısı = x / (çap * π)
Son adım
Roll It, zamanın bir göstergesidir. Geliştirilmesini destekleyen açık kaynak projeleri, masalarımızdaki ve ceplerimizdeki cihazların işlem gücü ve web'in platform olarak durumu göz önüne alındığında, açık web'e bağlı olmak gerçekten heyecan verici ve dönüştürücü bir deneyim. Bu teknolojinin büyük bir kısmı, sadece tescilli sistemlerde mevcuttu ve özgürce kullanılamıyor, dağıtılamıyordu. Her gün bulmacanın yeni parçalarını oluşturup paylaştığımız için günümüzde karmaşık deneyimler daha az çalışma ve daha fazla hayal gücüyle hayata geçirilebiliyor. Neyi bekliyorsunuz? Harika bir şey oluşturun ve bunu dünyayla paylaşın.