Sanal Gerçeklikte Sonsuz Bir Koşucu Oyunu Nasıl Oluşturulur (3. Bölüm)

Yayınlanan: 2022-03-10
Kısa özet ↬ Bölüm 1'de Alvin, bir sanal gerçeklik modelinin nasıl tasarlanacağının temellerini açıkladı. Bölüm 2'de oyunun temel mantığının nasıl uygulanacağını gösterdi. Eğitiminin bu son bölümünde, "Başlat" ve "Oyun Bitti" menülerinin yanı sıra mobil ve masaüstü istemciler arasında oyun durumlarının senkronizasyonu gibi son rötuşlar eklenecektir. Bu, çok oyunculu oyunlar oluşturmadaki kavramların önünü açar.

Ve böylece yolculuğumuz devam ediyor. Sonsuz bir koşucu VR oyununun nasıl oluşturulacağına dair serimin bu son bölümünde, sizi çok oyunculu bir oyun oluşturmaya bir adım daha yaklaştıracak iki cihaz arasında oyun durumunu nasıl senkronize edebileceğinizi göstereceğim. İstemciden istemciye iletişimde aracı sunucuyu yönetmekten sorumlu olan MirrorVR'ı özellikle tanıtacağım.

Not : Bu oyun VR gözlüğü ile veya VR gözlüğü olmadan oynanabilir. Nihai ürünün demosunu ergo-3.glitch.me adresinde görüntüleyebilirsiniz.

Başlamak için aşağıdakilere ihtiyacınız olacak.

  • İnternet erişimi (özellikle glitch.com'a);
  • Bu öğreticinin 2. bölümünden tamamlanan bir Glitch projesi. https://glitch.com/edit/#!/ergo-2 adresine gidip “Düzenlemek için Remix”e tıklayarak 2. kısım bitmiş üründen başlayabilirsiniz;
  • Bir sanal gerçeklik başlığı (isteğe bağlı, önerilir). (Parçası 15 dolardan sunulan Google Cardboard'u kullanıyorum.)

1. Adım: Puanı Görüntüle

Oyun olduğu gibi çalışır, burada oyuncuya bir meydan okuma verilir: engellerden kaçının. Ancak, nesne çarpışmaları dışında oyun, oyundaki ilerlemeyle ilgili olarak oyuncuya geri bildirim sağlamaz. Bunu düzeltmek için, bu adımda puan görüntüsünü uygulayacaksınız. Puan, kullanıcının görüş alanına yapıştırılmış bir arayüzün aksine, sanal gerçeklik dünyamıza yerleştirilen büyük metin nesnesi olacaktır.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Genel olarak sanal gerçeklikte, kullanıcı arayüzü, kullanıcının kafasına takılmak yerine dünyaya en iyi şekilde entegre edilir.

Puan ekranı
Skor ekranı (Geniş önizleme)

Nesneyi index.html dosyasına ekleyerek başlayın. Diğer metin öğeleri için yeniden kullanılacak bir text karışımı ekleyin:

 <a-assets> ... <a-mixin text=" font:exo2bold; anchor:center; align:center;"></a-mixin> ... </a-assets>

Ardından, oynatıcıdan hemen önce platforma bir text öğesi ekleyin:

 <!-- Score --> <a-text value="" mixin="text" height="40" width="40" position="0 1.2 -3" opacity="0.75"></a-text> <!-- Player --> ...

Bu, sanal gerçeklik sahnesine bir metin varlığı ekler. Değeri boş olarak ayarlandığından metin şu anda görünmüyor. Ancak, şimdi metin varlığını JavaScript kullanarak dinamik olarak dolduracaksınız. varlıklar/ergo.js'ye gidin. collisions bölümünden sonra bir score bölümü ekleyin ve bir dizi global değişken tanımlayın:

  • score : mevcut oyun skoru.
  • countedTrees : Skora dahil olan tüm ağaçların kimlikleri. (Bunun nedeni, çarpışma testlerinin aynı ağaç için birden çok kez tetiklenebilmesidir.)
  • scoreDisplay : sanal gerçeklik dünyasında bir metin nesnesine karşılık gelen DOM nesnesine başvuru.
 /********* * SCORE * *********/ var score; var countedTrees; var scoreDisplay;

Ardından, global değişkenlerimizi başlatmak için bir kurulum işlevi tanımlayın. Aynı şekilde, bir teardown işlevi tanımlayın.

 ... var scoreDisplay; function setupScore() { score = 0; countedTrees = new Set(); scoreDisplay = document.getElementById('score'); } function teardownScore() { scoreDisplay.setAttribute('value', ''); }

Game bölümünde, gameOver , startGame ve window.onload puan kurulumunu ve ayırmayı içerecek şekilde güncelleyin.

 /******** * GAME * ********/ function gameOver() { ... teardownScore(); } function startGame() { ... setupScore(); addTreesRandomlyLoop(); } window.onload = function() { setupScore(); ... }

Belirli bir ağaç için puanı artıran bir işlev tanımlayın. Bu işlev, ağacın iki kez sayılmadığından emin olmak için countedTrees karşı kontrol yapacaktır.

 function addScoreForTree(tree_id) { if (countedTrees.has(tree_id)) return; score += 1; countedTrees.add(tree_id); }

Ek olarak, genel değişkeni kullanarak puan görüntüsünü güncellemek için bir yardımcı program ekleyin.

 function updateScoreDisplay() { scoreDisplay.setAttribute('value', score); }

Oyuncunun önünden bir engel geçtiğinde bu puan artırma işlevini başlatmak için çarpışma testini uygun şekilde güncelleyin. Hala assets/ergo.js içinde, collisions bölümüne gidin. Aşağıdaki kontrolü ekleyin ve güncelleyin.

 AFRAME.registerComponent('player', { tick: function() { document.querySelectorAll('.tree').forEach(function(tree) { ... if (position.z > POSITION_Z_LINE_END) { addScoreForTree(tree_id); updateScoreDisplay(); } }) } })

Son olarak, oyun başlar başlamaz skor ekranını güncelleyin. Game bölümüne gidin ve updateScoreDisplay(); startGame için:

 function startGame() { ... setupScore(); updateScoreDisplay(); ... }

varlıklar/ergo.js ve index.html'nin ilgili kaynak kodu dosyalarıyla eşleştiğinden emin olun. Ardından, önizlemenize gidin. Aşağıdakileri görmelisiniz:

Puan ekranı
Skor ekranı (Geniş önizleme)

Bu, puan gösterimini tamamlar. Ardından, oyuncunun oyunu istediği gibi tekrar oynayabilmesi için uygun başlangıç ​​ve Game Over menülerini ekleyeceğiz.

2. Adım: Başlat Menüsü Ekle

Artık kullanıcı ilerlemeyi takip edebildiğine göre, oyun deneyimini tamamlamak için son rötuşları ekleyeceksiniz. Bu adımda, kullanıcının oyunları başlatmasına ve yeniden başlatmasına izin veren bir Başlat menüsü ve bir Oyun Bitti menüsü ekleyeceksiniz.

Oyuncunun oyuna başlamak için bir "Başlat" düğmesini tıkladığı Başlat menüsü ile başlayalım. Bu adımın ikinci yarısı için, “Yeniden Başlat” düğmesi olan bir Oyun Bitti menüsü ekleyeceksiniz:

Menüler üzerinden başla ve oyun oyna
Başlangıç ​​ve oyun üzerinden menüler (Geniş önizleme)

Editörünüzde index.html'ye gidin. Ardından, Mixins bölümünü bulun. Burada, özellikle büyük metinler için stilleri tanımlayan title karışımını ekleyin. Daha önce olduğu gibi aynı fontu kullanıyoruz, metni ortaya hizalıyoruz ve metnin türüne uygun bir boyut belirliyoruz. (Aşağıdaki anchor , bir metin nesnesinin konumuna sabitlendiği yer olduğuna dikkat edin.)

 <a-assets> ... <a-mixin text=" font:exo2bold; height:40; width:40; opacity:0.75; anchor:center; align:center;"></a-mixin> </a-assets>

Ardından, ikincil başlıklar için ikinci bir karışım ekleyin. Bu metin biraz daha küçüktür, ancak bunun dışında başlıkla aynıdır.

 <a-assets> ... <a-mixin text=" font:exo2bold; height:10; width:10; opacity:0.75; anchor:center; align:center;"></a-mixin> </a-assets>

Üçüncü ve son karışım için, ikincil başlıklardan bile daha küçük olan açıklayıcı metin özelliklerini tanımlayın.

 <a-assets> ... <a-mixin text=" font:exo2bold; height:5; width:5; opacity:0.75; anchor:center; align:center;"></a-mixin> </a-assets>

Tüm metin stilleri tanımlandığında, artık dünyadaki metin nesnelerini tanımlayacaksınız. Başlat menüsü için boş bir kapsayıcı ile Score bölümünün altına yeni bir Menus bölümü ekleyin:

 <!-- Score --> ... <!-- Menus --> <a-entity> <a-entity position="0 1.1 -3"> </a-entity> </a-entity>

Başlat menüsü kabının içinde, başlık olmayan tüm metinler için bir başlık ve bir kap tanımlayın:

 ... <a-entity ...> <a-entity position="0 1 0"> </a-entity> <a-text value="ERGO" mixin="title"></a-text> </a-entity> </a-entity>

Başlıksız metin kutusunun içine oyunu oynamak için talimatlar ekleyin:

 <a-entity...> <a-text value="Turn left and right to move your player, and avoid the trees!" mixin="copy"></a-text> </a-entity>

Başlat menüsünü tamamlamak için "Başlat" yazan bir düğme ekleyin:

 <a-entity...> ... <a-text value="Start" position="0 0.75 0" mixin="heading"></a-text> <a-box position="0 0.65 -0.05" width="1.5" height="0.6" depth="0.1"></a-box> </a-entity>

Başlat menüsü HTML kodunuzun aşağıdakilerle eşleştiğini iki kez kontrol edin:

 <!-- Menus --> <a-entity> <a-entity position="0 1.1 -3"> <a-entity position="0 1 0"> <a-text value="Turn left and right to move your player, and avoid the trees!" mixin="copy"></a-text> <a-text value="Start" position="0 0.75 0" mixin="heading"></a-text> <a-box position="0 0.65 -0.05" width="1.5" height="0.6" depth="0.1"></a-box> </a-entity> <a-text value="ERGO" mixin="title"></a-text> </a-entity> </a-entity>

Önizlemenize gidin ve aşağıdaki Başlat menüsünü göreceksiniz:

Başlat menüsünün resmi
Başlat menüsü (Geniş önizleme)

Yine Menus bölümünde (doğrudan start menüsünün altında), aynı karışımları kullanarak game-over menüsünü ekleyin:

 <!-- Menus --> <a-entity> ... <a-entity position="0 1.1 -3"> <a-text value="?" mixin="heading" position="0 1.7 0"></a-text> <a-text value="Score" mixin="copy" position="0 1.2 0"></a-text> <a-entity> <a-text value="Restart" mixin="heading" position="0 0.7 0"></a-text> <a-box position="0 0.6 -0.05" width="2" height="0.6" depth="0.1"></a-box> </a-entity> <a-text value="Game Over" mixin="title"></a-text> </a-entity> </a-entity>

JavaScript dosyanıza, entity/ergo.js'ye gidin . Game bölümünden önce yeni bir Menus bölümü oluşturun. Ek olarak, üç boş işlev tanımlayın: setupAllMenus , hideAllMenus ve showGameOverMenu .

 /******** * MENU * ********/ function setupAllMenus() { } function hideAllMenus() { } function showGameOverMenu() { } /******** * GAME * ********/

Ardından, Game bölümünü üç yerde güncelleyin. gameOver Game Over menüsünü gösterin:

 function gameOver() { ... showGameOverMenu(); } ``` In `startGame`, hide all menus: ``` function startGame() { ... hideAllMenus(); }

Ardından, window.onload içinde, startGame için doğrudan çağrıyı kaldırın ve bunun yerine setupAllMenus . Dinleyicinizi aşağıdakilerle eşleşecek şekilde güncelleyin:

 window.onload = function() { setupAllMenus(); setupScore(); setupTrees(); }

Menu bölümüne geri gidin. Çeşitli DOM nesnelerine referansları kaydedin:

 /******** * MENU * ********/ var menuStart; var menuGameOver; var menuContainer; var isGameRunning = false; var startButton; var restartButton; function setupAllMenus() { menuStart = document.getElementById('start-menu'); menuGameOver = document.getElementById('game-over'); menuContainer = document.getElementById('menu-container'); startButton = document.getElementById('start-button'); restartButton = document.getElementById('restart-button'); }

Ardından, startGame için hem "Başlat" hem de "Yeniden Başlat" düğmelerini bağlayın:

 function setupAllMenus() { ... startButton.addEventListener('click', startGame); restartButton.addEventListener('click', startGame); }

showStartMenu tanımlayın ve setupAllMenus :

 function setupAllMenus() { ... showStartMenu(); } function hideAllMenus() { } function showGameOverMenu() { } function showStartMenu() { }

Üç boş işlevi doldurmak için birkaç yardımcı işleve ihtiyacınız olacak. Bir A-Frame VR varlığını temsil eden bir DOM öğesini kabul eden ve onu gösteren veya gizleyen aşağıdaki iki işlevi tanımlayın. showAllMenus üzerinde her iki işlevi de tanımlayın:

 ... var restartButton; function hideEntity(el) { el.setAttribute('visible', false); } function showEntity(el) { el.setAttribute('visible', true); } function showAllMenus() { ...

İlk hideAllMenus . Nesneleri görüş alanından kaldıracak, ardından her iki menü için de tıklama dinleyicilerini kaldıracaksınız:

 function hideAllMenus() { hideEntity(menuContainer); startButton.classList.remove('clickable'); restartButton.classList.remove('clickable'); }

İkinci olarak, showGameOverMenu . Burada, her iki menünün yanı sıra Game Over menüsü ve 'Yeniden Başlat' düğmesinin tıklama dinleyicisi için kapsayıcıyı geri yükleyin. Ancak, 'Başlat' düğmesinin tıklama dinleyicisini kaldırın ve 'Başlat' menüsünü gizleyin.

 function showGameOverMenu() { showEntity(menuContainer); hideEntity(menuStart); showEntity(menuGameOver); startButton.classList.remove('clickable'); restartButton.classList.add('clickable'); }

Üçüncüsü, showStartMenu . Burada, showGameOverMenu gerçekleştirdiği tüm değişiklikleri tersine çevirin.

 function showStartMenu() { showEntity(menuContainer); hideEntity(menuGameOver); showEntity(menuStart); startButton.classList.add('clickable'); restartButton.classList.remove('clickable'); }

Kodunuzun ilgili kaynak dosyalarla eşleştiğini iki kez kontrol edin. Ardından, önizlemenize gidin ve aşağıdaki davranışı gözlemleyeceksiniz:

Menüler üzerinden başla ve oyun oyna
Başlat ve Game Over menüleri (Geniş önizleme)

Bu, Başlat ve Oyun Bitti menülerini tamamlar.

Tebrikler! Artık uygun bir başlangıç ​​ve uygun bir bitiş ile tamamen işleyen bir oyununuz var. Ancak, bu eğitimde bir adımımız daha kaldı: Oyun durumunu farklı oyuncu cihazları arasında senkronize etmemiz gerekiyor. Bu bizi çok oyunculu oyunlara bir adım daha yaklaştıracak.

3. Adım: Oyun Durumunu MirrorVR ile Senkronize Etme

Önceki bir öğreticide, bir sunucu ile bir istemci arasında tek yönlü iletişimi kolaylaştırmak için soketler arasında gerçek zamanlı bilgilerin nasıl gönderileceğini öğrendiniz. Bu adımda, aracı sunucuyu istemciden istemciye iletişimde yöneten MirrorVR adlı bu öğreticinin tam teşekküllü bir ürününün üzerine inşa edeceksiniz.

Not : MirrorVR hakkında daha fazla bilgiyi buradan edinebilirsiniz.

index.html'ye gidin. Burada, MirrorVR'ı yükleyeceğiz ve kameraya, uygulanabilir olduğunda bir mobil cihazın görünümünü yansıtması gerektiğini belirten bir bileşen ekleyeceğiz. Socket.io bağımlılığını ve MirrorVR 0.2.3'ü içe aktarın.

 <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script> <script src="https://cdn.jsdelivr.net/gh/alvinwan/[email protected]/dist/mirrorvr.min.js"></script>

Ardından, camera-listener adlı bir bileşen ekleyin:

 <a-camera camera-listener ...>

varlıklar/ergo.js'ye gidin. Bu adımda, mobil cihaz komutlar gönderecek ve masaüstü cihaz yalnızca mobil cihazı yansıtacaktır.

Bunu kolaylaştırmak için, masaüstü ve mobil cihazları ayırt edecek bir yardımcı programa ihtiyacınız var. Dosyanızın sonuna, shuffle sonra bir mobileCheck işlevi ekleyin:

 /** * Checks for mobile and tablet platforms. */ function mobileCheck() { var check = false; (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[aw])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera); return check; };

İlk olarak, oyun başlangıcını senkronize edeceğiz. Oyun bölümünün startGame , sonuna bir mirrorVR bildirimi ekleyin.

 function startGame() { ... if (mobileCheck()) { mirrorVR.notify('startGame', {}) } }

Mobil istemci artık bir oyunun başlamasıyla ilgili bildirimler gönderir. Şimdi masaüstünün yanıtını uygulayacaksınız.

Pencere yükleme dinleyicisinde bir setupMirrorVR işlevi çağırın:

 window.onload = function() { ... setupMirrorVR(); }

MirrorVR kurulumu için Game bölümünün üzerinde yeni bir bölüm tanımlayın:

 /************ * MirrorVR * ************/ function setupMirrorVR() { mirrorVR.init(); }

Ardından, mirrorVR için başlatma işlevine anahtar sözcük bağımsız değişkenleri ekleyin. Özellikle, oyun başlatma bildirimleri için işleyiciyi tanımlayacağız. Ayrıca bir oda kimliği belirteceğiz; bu, uygulamanızı yükleyen herkesin anında senkronize edilmesini sağlar.

 function setupMirrorVR() { mirrorVR.init({ roomId: 'ergo', state: { startGame: { onNotify: function(data) { hideAllMenus(); setupScore(); updateScoreDisplay(); } }, } }); }

Game Over için aynı senkronizasyon işlemini tekrarlayın. gameOver Game bölümünde, mobil cihazlar için bir kontrol ekleyin ve buna göre bir bildirim gönderin:

 function gameOver() { ... if (mobileCheck()) { mirrorVR.notify('gameOver', {}); } }

MirrorVR bölümüne gidin ve bir gameOver dinleyicisi ile anahtar kelime argümanlarını güncelleyin:

 function setupMirrorVR() { mirrorVR.init({ state: { startGame: {... }, gameOver: { onNotify: function(data) { gameOver(); } }, } }) }

Ardından, ağaçların eklenmesi için aynı senkronizasyon işlemini tekrarlayın. Trees bölümünde addTreesRandomly öğesine gidin. Hangi şeritlerin yeni ağaçlar aldığını takip edin. Ardından, return direktifinden hemen önce ve buna göre bir bildirim gönderin:

 function addTreesRandomly(...) { ... var numberOfTreesAdded ... var position_indices = []; trees.forEach(function (tree) { if (...) { ... position_indices.push(tree.position_index); } }); if (mobileCheck()) { mirrorVR.notify('addTrees', position_indices); } return ... }

MirrorVR bölümüne gidin ve anahtar sözcük argümanlarını ağaçlar için yeni bir dinleyiciyle mirrorVR.init olarak güncelleyin:

 function setupMirrorVR() { mirrorVR.init({ state: { ... gameOver: {... }, addTrees: { onNotify: function(position_indices) { position_indices.forEach(addTreeTo) } }, } }) }

Son olarak, oyun skorunu senkronize ediyoruz. Score bölümündeki updateScoreDisplay , uygun olduğunda bir bildirim gönderin:

 function updateScoreDisplay() { ... if (mobileCheck()) { mirrorVR.notify('score', score); } }

Skor değişiklikleri için bir dinleyici ile mirrorVR başlatmayı son kez güncelleyin:

 function setupMirrorVR() { mirrorVR.init({ state: { addTrees: { }, score: { onNotify: function(data) { score = data; updateScoreDisplay(); } } } }); }

Kodunuzun bu adım için uygun kaynak kod dosyalarıyla eşleştiğini iki kez kontrol edin. Ardından, masaüstü önizlemenize gidin. Ek olarak, aynı URL'yi mobil cihazınızda açın. Mobil cihazınız web sayfasını yükler yüklemez, masaüstünüz hemen mobil cihazın oyununu yansıtmaya başlamalıdır.

İşte bir demo. Masaüstü imlecinin hareket etmediğine dikkat edin, bu, mobil aygıtın masaüstü önizlemesini kontrol ettiğini gösterir.

MirrorVR oyun durumu senkronizasyonu ile Son Sonsuz Koşucu Oyunu
MirrorVR oyun durumu senkronizasyonu ile sonsuz koşucu oyununun nihai sonucu (Büyük önizleme)

Bu, artırılmış projenizi mirrorVR ile tamamlar.

Bu üçüncü adım, birkaç temel oyun durumu senkronizasyon adımını tanıttı; Bunu daha sağlam hale getirmek için daha fazla akıl sağlığı kontrolü ve daha fazla senkronizasyon noktası ekleyebilirsiniz.

Çözüm

Bu öğreticide, sonsuz koşucu oyununuza son rötuşlar eklediniz ve bir masaüstü istemcisinin bir mobil istemciyle gerçek zamanlı senkronizasyonunu uyguladınız ve mobil cihazın ekranını masaüstünüze etkili bir şekilde yansıttınız. Bu, sanal gerçeklikte sonsuz bir koşucu oyunu oluşturma serisini sonlandırıyor. A-Frame VR teknikleriyle birlikte, 3B modelleme, müşteriden müşteriye iletişim ve diğer yaygın olarak uygulanabilir kavramları öğrendiniz.

Sonraki adımlar şunları içerebilir:

  • Daha Gelişmiş Modelleme
    Bu, potansiyel olarak üçüncü taraf bir yazılımda oluşturulan ve içe aktarılan daha gerçekçi 3B modeller anlamına gelir. Örneğin, (MagicaVoxel) voksel sanatı oluşturmayı basitleştirir ve (Blender) eksiksiz bir 3D modelleme çözümüdür.
  • Daha Fazla Karmaşıklık
    Gerçek zamanlı strateji oyunu gibi daha karmaşık oyunlar, verimliliği artırmak için üçüncü taraf bir motordan yararlanabilir. Bu, derlenmiş (Unity3d) bir oyun yayınlamak yerine A-Frame ve webVR'den tamamen uzaklaşmak anlamına gelebilir.

Diğer yollar arasında çok oyunculu destek ve daha zengin grafikler bulunur. Bu eğitim serisinin sonunda, artık daha fazlasını keşfedeceğiniz bir çerçeveniz var.