2012-01-27 16 views
13

Cevabını bulamadığım bir sorum var. Ben node.js ve Socket.IO bir çok oyunculu oyun bina ile deniyorumÇok oyunculu JavaScript oyunu Node.JS ile oluşturulmuştur - Oyuncuları Ayırmak

. İlk denememde bir sohbet odası hazırladım, bu yüzden çalışma yayınlarım var vs. Şimdi Tuval ile çalışan bir şey almak istediğim noktadayım.

I having çoklu ve bağımsız oyuncular etrafında başımı almak olduğunu. Her oyuncunun sunucuya x, y kablolarını göndereceğini ve sunucunun bunları yayınlayacağını biliyorum, ancak müşteri kaç tane oyuncunun görüntüleneceğini nasıl bildiğini tahmin ediyor, sanırım bir yerlerde bir dizide saklanmaları gerekiyor.

cevap

39

Benim uygulanması bakmak tavsiye etmemekle birlikte düğümle "multiplayering" genel bir anlayışı işaret olmalıdır.

Ben en basit yaklaşım istemci hem de sunucu üzerinde bir ilişkisel dizi içeren oyuncular (varlıklar) sahip olduğunu düşünüyorum. Daha sonra istemci tarafında {action: "move", target:[32, 100]} gibi komutlar gönderiyorsunuz ve bu komutu sunucu mantığıyla (gerçek oyunun çalıştığı yerde) işlemektesiniz. Erişebildiğiniz böylece bir oyuncu nesne veya id atamak gerekir on connection her sokete hoşuna: daha sonra

{ 
    timestamp: game.delta, 
    players: { 
    1: {x: 32, y: 100}, 
    2: {x: 14, y: 11} 
    } 
} 

Ve: Sonra

var lastPlayerID = 0; 
var players = {}; 

server.on("connection", function(socket) { 

    var newcommer = new Player({id: lastPlayerID});  
    players[lastPlayerID] = newcommer; 
    socket.player = newcommer; // or lastPlayerID 
    lastPlayerID++;  

    socket.onMessage = function(message) { 
    this.player.doSomething(); 
    } 

}); 

her Diyelim ki bağlı tüm oyunculara anlık gönderebilir 100ms diyelim İstemci tarafı veri alır ve eskiden yeni değerlere enterpolasyon yapar.

// duration in this simplified example is snapshot sending interval in [ms] 
Player.prototype.interpolateTo = function(data, duration) { 
    if(typeof data.x != "undefined") { 
    // step needed to get `destination x` within `duration` miliseconds 
    this.stepValues.x = Math.abs(data.x - this.x)/duration; 
    this.target.x = data.x; 
    } 
    // ... 
} 

// step you call for each game loop iteration 
Player.prototype.step = function(delta) { 
    if(this.x < this.target.x) { 
    this.x += delta * this.stepValues.x 
    } 
} 

Bu, maksimum 20 nesne ile yarı arcade oyun için yeterli bir algoritmadır. Enstantane aralığının azaltılması, daha fazla nesne ile strateji oyunu için neredeyse uygun hale getirir. Ana düşmanınız, paketin boyutunu küçültebilen bant genişliği kullanımıdır. Örneğin, BiSON, LZW hakkında bilgi edinin ve son anlık görüntüden bu yana değişmeyen verileri göndermeyin.

şöhretim bana tüm bağlantıları yayınlamak için izin vermez, bu yüzden onları burada iliştirilmesi: http://pastebin.com/Kh3wvF1D

Genel tanıtım Glenn Fiedler tarafından kavramları çok oyunculu:

http://gafferongames.com/networking-for-game-programmers/what-every-programmer-needs-to-know-about-game-networking/

Quake'den bazı çok oyunculu teknikler: Bu, hakkında bir ipucu verecektir. nterpolation ve ekstrapolasyon (tahmini)

http://fabiensanglard.net/quakeSource/quakeSourcePrediction.php

gecikme tazminat ve genel optimizasyonlar hakkında Valve'nin madde:

https://developer.valvesoftware.com/wiki/Latency_Compensating_Methods_in_Client/Server_In-game_Protocol_Design_and_Optimization

Age of Empires

Çok teknikleri:

http://zoo.cs.yale.edu/classes/cs538/readings/papers/terrano_1500arch.pdf#search=%22Real%20time%20strategy%20networking%20lockstep%22

Ayrıca bu bilginin büyük bir kazık var Ivo adlı kişinin Wetzel Mapple.js için bant genişliği kullanımını

http://rezoner.net/minimizing-bandwidth-usage-in-html5-games-using-websocket,299

+1 optimize ilgili yazımda okuyabilirsiniz.

https://github.com/BonsaiDen/Maple.js

+0

Stackoverflow'a Hoş Geldiniz! Çok iyi cevap, böyle devam et ve senin rep eksikliği, çok uzun bir sorun olmamalı. :) – RedRiderX

+0

Böyle detaylı bir açıklama için teşekkür ederim :) – Henryz

10

oyuncular, elle koordinatlarını göndererek hile olanak sağlayacak sunucuya y koordinatlarını, onların x göndermeyin.

Her oyuncu "sol eğilimi/sağ/yukarı/aşağı" gönderir sunucuya olaylar. Sunucu daha sonra pozisyonları günceller ve tüm oyuncuların pozisyonunu (veya pozisyondaki deltaları) periyodik olarak yayınlar.

Her istemci sonra bütün bu oyuncu deltaları alır ve bunları kılar. İstemci tarafı uygulaması açısından bir çeşit Board/Map nesnesi olurdu ve RenderableEntities'in bir listesi olurdu. Daha sonra RenderableEntities'i yeni konumlarla güncellerim ve tüm varlıkları periyodik olarak yeniden çiziyorum.

seni çok naif ve hiçbir gecikme telafisi, ekstrapolasyon ve bu tür basitleştirilmiş olacak Maple.js

+0

Elbette. Açıklama için teşekkürler. Böylece, mantık sunucuya oturacak ve oyunculara yeni pozisyonlar yayınlayacak. Bir dizi veya nesneyi yayınlamak ve görüntülemek için istemci tarafında döngü yapmak mı? Maple.js'e bir göz atacağım :) – Henryz

+0

@Henryz, sadece konum değiştiren nesneleri yayınladığınız ve sadece pozisyondaki gerçek farkı tüm pozisyonda yayınladığınız içindir. Veri yapıları size kalmış, bir tuple nesnesi oldukça iyi '{id: [x, y], otherid: [x, y]} 'vb – Raynos

+0

Korkarım ki Maple.js demosu çalıştırmaya çalışıyorum ve hiç çalışmıyor. Son 3 yılda repo güncellemesi yok. İstemci ve sunucu arasında bu tür senkronize güncellemeleri uygulayabilecek başka öneriler var mı? –

0

& Y, her bir oyuncunun X senkronize etmek için başka bir yol Lance kullanmaktır. Yetkili bir sunucuyla birden çok oyuncu için konum düzeltmeyi işleyen açık kaynaklı bir JavaScript kitaplığıdır.

Nesne adı veya avatar özellikleri gibi koordinatların yanı sıra başka şeyleri de senkronize etmeniz gerekiyorsa yararlı olacaktır. Ya da oyuncularınızın hızları varsa.

İlgili konular