Chrome Dino Oyununun Kaynak Kodunda Gizli Oyun Tasarımı Sırları
Chrome Dino Oyununun Kaynak Kodunda Chrome Dino Oyununun Kaynak Kodunda kapsamında, Bunu yüzlerce kez gördünüz: Wi-Fi bağlantısı kesiliyor, Chrome omuz silkiyor ve boşluk tuşuna bastığınız anda çölde koşmaya hazır küçük pikselli bir T-Rex beliriyor. 2014'ten bu…

Chrome Dino Oyununun Kaynak Kodunda
Chrome Dino Oyununun Kaynak Kodunda kapsamında, Bunu yüzlerce kez gördünüz: Wi-Fi bağlantısı kesiliyor, Chrome omuz silkiyor ve boşluk tuşuna bastığınız anda çölde koşmaya hazır küçük pikselli bir T-Rex beliriyor. 2014’ten bu yana “İnternet Yok” hatasının arkasına gizlenen bu küçük oyun, her ay yaklaşık 270 milyon kez oynanıyor. Google’daki dahili kod adı, rock grubu T. Rex’in solisti Marc Bolan’a gönderme yapan “Project Bolan”dı.
Chrome Dino Oyununun Kaynak Kodunda kapsamında, Chrome, açık kaynaklı Chromium projesi üzerine kurulduğundan, oyunun tamamı (her sabit, tasarım kararı ve hack) herkesin okuyabileceği şekilde herkesin önünde duruyor. Ben de okudum. Hepsi.
Chrome Dino Oyununun Kaynak Kodunda kapsamında, Ve bu “basit” oyunun, oyun tasarımında küçük bir ustalık sınıfı olduğu ortaya çıktı: Sizi sessizce oyuna dahil ediyor, sizi haksız yere öldürmeyi reddediyor, ayı yedi aşamada canlandırıyor ve on yıldır milyarlarca cihaza bir yazım hatası gönderiyor. Bu makalede gerçek kaynak kodunu inceleyeceğiz ve dino oyununun gerçekte nasıl çalıştığını açıklayacağız.
Tasarım ve teknik ayrıntılar
Chrome Dino Oyununun Kaynak Kodunda kapsamında, Okurken oyunun bir sekmede açılmasını istiyorsanız Wi-Fi’nizi kapatmanıza gerek yok. Dinozor Oyununu çevrimiçi olarak oynayabilirsiniz ve freeCodeCamp’te oyunu çevrimiçi ve çevrimdışı olarak başlatmaya yönelik bir kılavuz da bulunur. Kodun kendisi de source.chromium.org adresinde göz atılabilen Chromium ağacında bulunuyor.
Chrome Dino Oyununun Kaynak Kodunda kapsamında, Bu, tarihsel olarak düz bir üzerine çizilen, yaklaşık 3.000 satırlık bağımlılık içermeyen vanilya JavaScript’inden oluşan tek bir dosyadır. Motor yok. Çerçeve yok. JQuery bile değil. Bu arada, işte oyunun tamamı ikir.

Chrome Dino Oyununun Kaynak Kodunda kapsamında, Bu küçük bir PNG’dir ve kodun koordinatlarla atıfta bulunduğu her bir karakter vardır: İçindekiler Saat: Oyun Neden Her Yerde Aynı Hızda Çalışır T-Rex: Dört Sabit ve Bir Yazım Hatası Adillik Motoru: Oyun Sizi Aldatmayı Nasıl Reddeder Çarpışma Algılama: Dino Altı Dikdörtgendir Gece Modu ve Yedi Aşamalı Ay Açık Görüşte Saklanan Küçük Zevkler Kendi Projeleriniz İçin Neleri Çalabilirsiniz Saat: Neden Oyun Her Yerde Aynı Hızda Çalışır Her oyunun çözmesi gereken ilk sorun: tarayıcılar sabit bir hızda yeniden boyama yapmaz.
Bugünden bakınca ne kadar güvenilir?
144 Hz’lik bir oyun monitörü, requestAnimationFrame’i saniyede 144 kez başlatır. Ancak zor durumdaki bir dizüstü bilgisayar 40 pikseli idare edebilir. Eğer nesneleri kare başına sabit sayıda piksel hareket ettirirseniz, oyununuz daha iyi donanımda kelimenin tam anlamıyla 3 kat daha hızlı çalışır. Dino’nun çözümü, temiz bir şekilde uygulanan standart çözümdür.
Oyun, varsayılan 60 FPS’de hızlarını kare başına piksel cinsinden tanımlar ve ardından her hareketi gerçekte geçen süreye göre ölçeklendirir: this.msPerFrame = 1000 / FPS; // …her güncellemede: this.xPos -= Math.floor((currentSpeed FPS / 1000) deltaTime); Dinozorun atlamasından kaktüslere, bulutlara ve hatta aya kadar oyundaki her hareketli şey deltaTime ile çarpılır.
Bu nedenle, ikiniz de hangi makineyi kullanıyor olursanız olun, yüksek puanınız arkadaşınızınkiyle karşılaştırılabilir. Bu makaleden bir mühendislik alışkanlığını çıkarırsanız, şunu alın: hiçbir şeyi “kare başına” hareket ettirmeyin ” tutarlar. Her zaman geçen zamana göre ölçeklendirin.
Okuyucu için pratik anlamı
T-Rex: Dört Sabit ve Bir Yazım Hatası Dinozorun tüm fiziksel varlığı, Trex.config ve Runner.config’teki bir avuç sayıyla tanımlanır: GRAVITY: 0,6, INIITAL_JUMP_VELOCITY: -10, HIZ: 6, HIZLANMA: 0,001, MAX_SPEED: 13, Evet, doğru okudunuz: INIITAL_JUMP_VELOCITY, üç I’li.
Bu yazım hatası Chrome’da milyarlarca cihaza gönderildi ve yaklaşık on yıl boyunca hayatta kaldı çünkü yeniden adlandırmak hiçbir zaman riske girmeye değmezdi. Bir dahaki sefere kendi üretim kodunuzda bir yazım hatası bulduğunuzda bu sizi rahatlatsın. Birimler 60 FPS’de kare başına pikseldir. Bunları dönüştürdüğünüzde fizik sezgisel hale gelir: yerçekimi 0,6 piksel/kare², atlama hızı −10 piksel/karedir.
Matematiği çalıştırın ve atlama arkı zirvelerini kalkıştan yaklaşık 0,28 saniye sonra yaklaşık 83 pikselde yapın. 150 piksel yüksekliğindeki bir oyun alanında bu, ekranın yarısından fazlasıdır. Dünya 6 piksel/kare (360 piksel/s) hızında kaydırmaya başlar ve başlangıç hızının iki katından biraz daha fazla olan 13 sınırına ulaşana kadar her karede 0,001 piksel/kare kazanır.
Bu sınır önemlidir: Bu, oyunun zorlaşacağının ancak hiçbir zaman imkansız olmayacağının garantisidir. Ancak çoğu klonun gözden kaçırdığı ayrıntı şu: atlama yüksekliği değişkendir.
Boşluk çubuğunu bıraktığınızda çalışan kodu izleyin: endJump: function () { if (this.MinHeight’a ulaştı && this.jumpVelocity < this.config.DROP_VELOCITY) { this.jumpVelocity = this.config.DROP_VELOCITY; } }, Boşluk çubuğuna dokunun ve t Dinozor kısa bir atlama yapar, ancak onu tutarsanız dino tam yay boyunca ilerler.
Anahtarın erken bırakılması yukarı doğru hızı kıstırır, sıçramayı kısaltır (minimum yüksekliğe ulaşıldığı sürece, böylece kendinizi bir kaktüse kapamazsınız). Ve havadayken Aşağı oka basarsanız, setSpeedDrop düşme hızını 3 ile çarparak hızlı bir iyileşme için dinoyu tekrar yere çarpar. İki küçük mekanik ve birdenbire tek tuşlu oyunda etkileyici bir beceri tavanı beliriyor: kısa atlama, tam atlama, hızlı çarpma.
Bu yüzden en iyi oyuncuların koşuları sizinkine hiç benzemiyor. Adillik Motoru: Oyun Sizi Aldatmayı Nasıl Reddediyor Bu kod tabanının en sevdiğim kısmı çünkü hiçbiri görünmüyor. Bunu yalnızca hissedebilirsin. Oyundaki her engel küçük bir yapılandırmayla bildirilir ve yapılandırmalar bir dizi adalet kuralını kodlar.
İşte küçük kaktüs: { şunu yazın: ‘CACTUS_SMALL’, genişlik: 17, yükseklik: 35, çokluHız: 4, minGap: 120, dkHız: 0, // … } Ortaya çıkan kodun orada ve başka yerlerinde saklanan kuralları açalım: Kural 1: İlk üç saniye boştur. CLEAR_TIME: 3000, koşunun ilk üç saniyesinde hiçbir engelin ortaya çıkmayacağını garanti eder.
Bu sessiz bir başlangıçtır: oyun sizden herhangi bir şey istemeden önce kontrolleri hissetmek için biraz zamanınız olur. Kural 2: Kümeler hıza göre kontrol edilir. Bir kaktüs, MAX_OBSTACLE_LENGTH: 3’e kadar grup halinde ortaya çıkabilir, ancak yalnızca mevcut hız çoklu hız değerini aştığında ortaya çıkabilir ed (küçük kaktüsler için 4, büyük kaktüsler için 7). Neden?
Çünkü dünya hızıyla birlikte atlama mesafeniz de artıyor. Yay sabit bir süre sürer, dolayısıyla zemin ne kadar hızlı hareket ederse atlama başına o kadar fazla zemin temizlersiniz. Geniş engeller yalnızca atlayışınız fiziksel olarak onları aşacak kadar uzun olduğunda ortaya çıkar. Oyun asla geçemeyeceğinizi bildiği bir duvar oluşturmaz. Kural 3: Boşluklar da hıza göre artar.
Her engelden sonraki boşluk, kabaca engel Genişliği × hız + minimum Boşluk × 0,6 artı rastgelelik olarak hesaplanır. Yani oyun ne kadar hızlı olursa, tepki vermeniz için size o kadar fazla alan verilir. Zorluk hızın kendisinden gelir, asla adil olmayan aralıktan kaynaklanmaz. Kural 4: Arka arkaya üç kez hiçbir engel görünmüyor.
Tüm işi çeşitlilik olan bir fonksiyon var: doubleObstacleCheck: function (nextObstacleType) { var kopyaSayısı = 0; for (var i = 0; i < this.obstacleHistory.length; i++) { kopyaSayısı = this.obstacleHistory[i] == nextObstacleType ?
kopyaSayısı + 1 : 0; } return doubleCount >= Runner.config.MAX_OBSTACLE_DUPLICATION; }, MAX_OBSTACLE_DUPLICATION: 2 ile, yumurtlayan kişi bir geçmiş tutar ve aynı engel türünün art arda üçüncü kez ortaya çıkması durumunda yeniden yuvarlanır. Bu kuralı hiç fark etmediniz, asıl mesele de bu. Yokluğunu fark etmişsinizdir. Kural 5: Pterodaktil oyunun sonlarındaki bir boss’tur.
Yapılandırmasında minSpeed: 8.5 yazıyor, bu da maksimum hıza giden yolun üçte ikisine ulaşana kadar görünemeyeceği anlamına geliyor.
T’lerden birinde uçuyor üç yükseklikte (yani bazen atlarsınız, bazen eğilirsiniz ve bazen 50 pikselde karar vermeniz gerekir), asla gruplar halinde ortaya çıkmaz (multipleSpeed: 999) ve kendi speedOffset’i vardır: 0,8, yani her pterodaktil dünyanın hareketinden biraz daha hızlı veya daha yavaş uçar. Bu son ayrıntı, tam rahatladığınız anda ritim temelli kas hafızanızı kırar.
Bu kuralların tümü her oyun tasarımcısının karşılaştığı bir sorunun cevabını oluşturur: Bir oyunu haksız hale getirmeden nasıl zorlaştırırsınız? Oyuncular “Yavaş olduğum için kaybettim” ile “Oyun hile yaptığı için kaybettim” arasındaki farkı hissedebilirler. Ve dino, on yıl ve trilyonlarca koşu boyunca hiç kimseyi aldatmadı.
Çarpışma Algılama: Dino Altı Dikdörtgendir Deneyimsiz çarpışma algılama, dinoyu tek bir sınırlayıcı kutuya sarar ve örtüşmeyi kontrol eder. Ama dinoya bakın: Dışarı çıkmış bir burnu, kuyruğu ve çenesinin altında bir boşluk var. Tek bir kutuyla çenesinin altındaki boş havayı otlayan bir kaktüs sizi öldürür ve bu çok kötü hissettirirdi.
Yani gerçek dino altı kutudan oluşuyor: Trex.collisionBoxes = { KOŞUYOR: [ new CollisionBox(22, 0, 17, 16), // kafa new CollisionBox(1, 18, 30, 9), // gövde new CollisionBox(10, 35, 14, 8), // bacaklar yeni CollisionBox(1, 24, 29, 5), yeni CollisionBox(5, 30, 21, 4), yeni CollisionBox(9, 34, 15, 4) ], ÖLDÜRMEK: [ new CollisionBox(1, 18, 55, 25) // bir uzun düşük kutu ] }; Diyi izleyen altı küçük dikdörtgen Hayır’ın gerçek silueti: baş, gövde ve karın ile bacaklardan aşağıya doğru uzanan kutulardan oluşan bir merdiven.
Dino eğildiğinde tüm set uzun, alçak bir kutuyla değiştirilir. Engeller aynı muameleyi görüyor: Küçük bir kaktüs, gövdesini ve kollarını takip eden üç kutudan oluşuyor ve pterodaktil, kanatlarını ve gagasını takip eden beş kutudan oluşuyor.
İşte gerçek sprite üzerine çizilmiş bu kutular gerçekte neye benziyor: Algoritma klasik iki aşamalı bir kontroldür: ilk önce ucuz bir dış kutu testi (genel dikdörtgenler birbirine değiyor mu?) ve ancak bu başarılı olursa, her dino kutusunu her engel kutusuyla karşılaştıran ayrıntılı döngü. Genel durumda hızlı, önemli olan anda hassas.
Eğer bir kaktüs iğnesi görsel olarak dino’nun çenesinin altındaki çentikten geçerse, yaşarsınız ve kod gözlerinizle aynı fikirde olur. Bu, dövüş oyunu isabet kutularına ve zarar kutularına kadar ölçeklenen bir tekniğin mümkün olan en ucuz versiyonudur. Ders genelleştirir: Çarpışma, matematik açısından uygun olanla değil, oyuncunun gördüğüyle eşleşmelidir.
Gece Modu ve Yedi Aşamalı Ay 700 puana ulaşır (INVERT_DISTANCE: 700) ve dünya tersine döner: karanlık gökyüzü, soluk zemin, yıldızlar. On iki saniye sonra (INVERT_FADE_DURATION: 12000) gün geri dönüyor. Sayısal olarak bu sadece bir sınıf geçişi artı paletin CSS tarzı ters çevrilmesidir. Ama işin büyüleyici kısmı gökyüzünde olup bitenler. Ay statik bir hayalet değildir.
Sprite sayfası onu yedi versiyonda içeriyor ve kod bunlar arasında geçiş yapar: NightMode.phases = [140, 120, 100, 60, 40, 20, 0]; Bunlar, ince bir hilalden yarım aylara ve tam bir diske kadar hareketli grafik sayfasındaki x sapmalarıdır: Her gece düştüğünde, ay bir aşama ilerler. Yıldızlar yerden daha yavaş olan kendi hızlarında (STAR_SPEED: 0,3) sürükleniyor ve geceye paralaks derinliğinin fısıltısını veriyor.
Tarayıcı hata sayfasında kimsenin ay takvimine ihtiyacı yoktu. Zaten birileri bir tane inşa etti ve birileri bunun gibi detayların bir özellik ile sevilen bir şey arasındaki fark olduğunu anladı. Açık Görüşte Saklanan Küçük Zevkler Kaynaktan dikkatli olanı ödüllendiren birkaç bulgu daha: Dinozor göz kırpıyor. Oyun başlamanızı beklerken boştaki dino rastgele aralıklarla yanıp söner.
Ve bunu kaç kez yapacağını sınırlayan MAX_BLINK_COUNT: 3 sabiti var. Göz kırpma gecikmesinin kendisi Math.ceil(Math.random() * Trex.BLINK_TIMING) şeklindedir. Google’dan birisi bir dinozorun göz kapağının rastgeleliğini ayarladı. Puanınız piksel değil. Mesafe ölçer kat edilen gerçek piksel sayısını KATSAYIS ile çarpar: 0,025. Yani 100 puan, 4.000 piksel çalıştırdığınız anlamına gelir.
Her 100 puanda bir (ACHIEVEMENT_DISTANCE: 100), skor saniyede dört vuruşla yanıp söner; yuvarlak sayıları olaymış gibi hissettiren küçük bir dopamin metronomu. Tezgah taşma konusunda teatraldir. Ekranda MAX_DISTANCE_UNITS gösteriliyor: 5 hane. 99.999’u geçtik ve puan görsel olarak sıfırlanır. Dahili sayaç çalışmaya devam ediyor, ancak kilometre sayacı etkisi kalıyor, atari salonlarına kasıtlı bir saygı duruşu.
Mobil oyuncular bir dezavantaja sahiptir. MOBILE_SPEED_COEFFICIENT: 1.2: oyun daha hızlı çalışır… bekleyin, hayır: daha küçük ekranlara ve dokunma gecikmesine göre ayarlanır, böylece deneyim eşdeğer hissettirir. Mesele şu ki, birisi cam üzerindeki başparmak ile boşluk çubuğu üzerindeki parmak arasındaki farkı ölçtü ve cevabı bir sabit olarak kodladı. Yeniden başlatma korumalı.
Bir çarpışmanın ardından GAMEOVER_CLEAR_TIME: 750 olur. Saniyenin dörtte üçü boyunca atlama tuşu oyunu yeniden başlatmaz. Bu orada çünkü öldüğünüzde boşluk tuşuna basacaksınız ve anında yeniden başlatmak sizi puanınızı görme şansınızdan mahrum bırakacaktır. 750 milisaniyelik bir merhamet eylemi.
Kendi Projeleriniz İçin Neleri Çalabilirsiniz Dino oyunu tam da kısıtlamaları acımasız olduğu için bir ustalık sınıfıdır: küçük olması, anında yüklenmesi, oyun donanımlarından 50 dolarlık telefonlara kadar her şeyde çalıştırılması ve herkes tarafından bir saniyede anlaşılması gerekiyordu. Bu kısıtlamalar altında kullandığı teknikler herhangi bir projeye aktarılır: Çerçevelere göre değil zamana göre ölçeklenir.
Delta zamanlı hareket, oyunun donanım açısından adil olmasının nedenidir. Yeteneğin arkasında kapı zorluğu. Geniş kümeler yalnızca atlama onları temizleyebildiğinde ortaya çıkar. Oyuncunun ne yapabileceğini sorun ve buna göre ortaya çıkın. Oyuncuya boş bir pist verin. Üç sessiz saniye kontrol bahislerini öğretir bir eğitim ekranından daha iyi. Çeşitliliği güçlendirin.
Üç satırlık bir geçmiş kontrolü, oyuncunun yalnızca belli belirsiz bir can sıkıntısı olarak fark edeceği monotonluğu önler. Hitbox’ları dürüst hale getirin. Siluetle eşleşen altı dikdörtgen, oyuncunun gözlerini ele veren bir dikdörtgeni yendi. Görünmeyen ayrıntılara çaba harcayın. Yanıp sönme, ayın evreleri, yeniden başlatma yetkisiz süresi: hiçbiri gerekli değildir, ancak hepsi hissedilir.
On yıl sonra Chrome dino, harika bir oyunun fotogerçekçi grafiklere veya 100 gigabaytlık kuruluma ihtiyaç duymadığının kanıtıdır. Sadece sıkı kontrollere, adil kurallara, tek tuşa ve evrelerini koruyan bir aya ihtiyacı var. Artık bunun neden bu kadar iyi hissettirdiğini tam olarak biliyorsunuz: çünkü birisi satır satır bunun böyle olmasını sağladı. Git kaynağı oku.
İnternetteki en iyi ücretsiz oyun tasarımı derslerinden biridir ve başından beri en kötü Wi-Fi günlerinizin arkasında saklanıyordu. Bağımsız web geliştiricisi ve yayıncısı. 2016’dan bu yana, Chrome Dino hayran projesi chromedino.com da dahil olmak üzere tarayıcı oyunları ve referans siteleri oluşturuyoruz. Tarayıcı oyunları, gizli özellikler ve basit yazılım sanatı hakkında yazıyorum. Ücretsiz kodlamayı öğrenin.
freeCodeCamp’in açık kaynak müfredatı 40.000’den fazla kişinin geliştirici olarak iş bulmasına yardımcı oldu. Başlayın REKLAM
İlgili yazılar
- CrawlForge 5.0: Güvenlik ve Doğrulukta Yeni Standartlar
- iOS 27 ile iPhone’unuzda Kullanabileceğiniz 30 Yeni Özellik
Editörün Notu
Chrome Dino oyunu, basit görünümünün ardında kullanıcı deneyimini ön planda tutan dikkatli tasarım seçimleri barındırır; bu da oyunların erişilebilir ve bağımlılık yaratıcı olmasının temelinde stratejik kararların yattığını gösterir. Tasarım sırlarını anlamak, kendi projelerinizde kullanıcı bağlılığını artırmak için ilham verebilir.
